1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2017 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 a segment register of thread base pointer load
65 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
66 ;; ! -- print MPX prefix for jxx/call/ret instructions if required.
68 (define_c_enum "unspec" [
69 ;; Relocation specifiers
80 UNSPEC_MACHOPIC_OFFSET
89 UNSPEC_MEMORY_BLOCKAGE
100 ;; Other random patterns
108 UNSPEC_LD_MPIC ; load_macho_picbase
110 UNSPEC_DIV_ALREADY_SPLIT
116 UNSPEC_INSN_FALSE_DEP
118 ;; For SSE/MMX support:
126 ;; Generic math support
128 UNSPEC_IEEE_MIN ; not commutative
129 UNSPEC_IEEE_MAX ; not commutative
131 ;; x87 Floating point
147 UNSPEC_FRNDINT_MASK_PM
151 ;; x87 Double output FP
178 ;; For LZCNT suppoprt
200 UNSPEC_INTERRUPT_RETURN
203 (define_c_enum "unspecv" [
206 UNSPECV_PROBE_STACK_RANGE
209 UNSPECV_SPLIT_STACK_RETURN
215 UNSPECV_LLWP_INTRINSIC
216 UNSPECV_SLWP_INTRINSIC
217 UNSPECV_LWPVAL_INTRINSIC
218 UNSPECV_LWPINS_INTRINSIC
240 ;; For atomic compound assignments.
246 ;; For RDRAND support
249 ;; For RDSEED support
263 ;; For CLFLUSHOPT support
266 ;; For MONITORX and MWAITX support
270 ;; For CLZERO support
273 ;; For RDPKRU and WRPKRU support
277 ;; Constants to represent rounding modes in the ROUND instruction
286 ;; Constants to represent AVX512F embeded rounding
288 [(ROUND_NEAREST_INT 0)
296 ;; Constants to represent pcomtrue/pcomfalse variants
306 ;; Constants used in the XOP pperm instruction
308 [(PPERM_SRC 0x00) /* copy source */
309 (PPERM_INVERT 0x20) /* invert source */
310 (PPERM_REVERSE 0x40) /* bit reverse source */
311 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
312 (PPERM_ZERO 0x80) /* all 0's */
313 (PPERM_ONES 0xa0) /* all 1's */
314 (PPERM_SIGN 0xc0) /* propagate sign bit */
315 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
316 (PPERM_SRC1 0x00) /* use first source byte */
317 (PPERM_SRC2 0x10) /* use second source byte */
320 ;; Registers by name.
403 (FIRST_PSEUDO_REG 81)
406 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
409 ;; In C guard expressions, put expressions which may be compile-time
410 ;; constants first. This allows for better optimization. For
411 ;; example, write "TARGET_64BIT && reload_completed", not
412 ;; "reload_completed && TARGET_64BIT".
416 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
417 atom,slm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
418 bdver4,btver2,znver1"
419 (const (symbol_ref "ix86_schedule")))
421 ;; A basic instruction type. Refinements due to arguments to be
422 ;; provided in other attributes.
425 alu,alu1,negnot,imov,imovx,lea,
426 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
427 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
428 push,pop,call,callv,leave,
430 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
431 fxch,fistp,fisttp,frndint,
432 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
433 ssemul,sseimul,ssediv,sselog,sselog1,
434 sseishft,sseishft1,ssecmp,ssecomi,
435 ssecvt,ssecvt1,sseicvt,sseins,
436 sseshuf,sseshuf1,ssemuladd,sse4arg,
438 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
439 mpxmov,mpxmk,mpxchk,mpxld,mpxst"
440 (const_string "other"))
442 ;; Main data type used by the insn
444 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
446 (const_string "unknown"))
448 ;; The CPU unit operations uses.
449 (define_attr "unit" "integer,i387,sse,mmx,unknown"
450 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
451 fxch,fistp,fisttp,frndint")
452 (const_string "i387")
453 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
454 ssemul,sseimul,ssediv,sselog,sselog1,
455 sseishft,sseishft1,ssecmp,ssecomi,
456 ssecvt,ssecvt1,sseicvt,sseins,
457 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
459 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
461 (eq_attr "type" "other")
462 (const_string "unknown")]
463 (const_string "integer")))
465 ;; The (bounding maximum) length of an instruction immediate.
466 (define_attr "length_immediate" ""
467 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
468 bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
471 (eq_attr "unit" "i387,sse,mmx")
473 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
474 rotate,rotatex,rotate1,imul,icmp,push,pop")
475 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
476 (eq_attr "type" "imov,test")
477 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
478 (eq_attr "type" "call")
479 (if_then_else (match_operand 0 "constant_call_address_operand")
482 (eq_attr "type" "callv")
483 (if_then_else (match_operand 1 "constant_call_address_operand")
486 ;; We don't know the size before shorten_branches. Expect
487 ;; the instruction to fit for better scheduling.
488 (eq_attr "type" "ibr")
491 (symbol_ref "/* Update immediate_length and other attributes! */
492 gcc_unreachable (),1")))
494 ;; The (bounding maximum) length of an instruction address.
495 (define_attr "length_address" ""
496 (cond [(eq_attr "type" "str,other,multi,fxch")
498 (and (eq_attr "type" "call")
499 (match_operand 0 "constant_call_address_operand"))
501 (and (eq_attr "type" "callv")
502 (match_operand 1 "constant_call_address_operand"))
505 (symbol_ref "ix86_attr_length_address_default (insn)")))
507 ;; Set when length prefix is used.
508 (define_attr "prefix_data16" ""
509 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
511 (eq_attr "mode" "HI")
513 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
518 ;; Set when string REP prefix is used.
519 (define_attr "prefix_rep" ""
520 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
522 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
524 (and (eq_attr "type" "ibr,call,callv")
525 (match_test "ix86_bnd_prefixed_insn_p (insn)"))
530 ;; Set when 0f opcode prefix is used.
531 (define_attr "prefix_0f" ""
533 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
534 mpxmk,mpxmov,mpxchk,mpxld,mpxst")
535 (eq_attr "unit" "sse,mmx"))
539 ;; Set when REX opcode prefix is used.
540 (define_attr "prefix_rex" ""
541 (cond [(not (match_test "TARGET_64BIT"))
543 (and (eq_attr "mode" "DI")
544 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
545 (eq_attr "unit" "!mmx")))
547 (and (eq_attr "mode" "QI")
548 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
550 (match_test "x86_extended_reg_mentioned_p (insn)")
552 (and (eq_attr "type" "imovx")
553 (match_operand:QI 1 "ext_QIreg_operand"))
558 ;; There are also additional prefixes in 3DNOW, SSSE3.
559 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
560 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
561 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
562 (define_attr "prefix_extra" ""
563 (cond [(eq_attr "type" "ssemuladd,sse4arg")
565 (eq_attr "type" "sseiadd1,ssecvt1")
570 ;; Set when BND opcode prefix may be used.
571 (define_attr "maybe_prefix_bnd" "" (const_int 0))
573 ;; Prefix used: original, VEX or maybe VEX.
574 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
575 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
577 (eq_attr "mode" "XI,V16SF,V8DF")
578 (const_string "evex")
580 (const_string "orig")))
582 ;; VEX W bit is used.
583 (define_attr "prefix_vex_w" "" (const_int 0))
585 ;; The length of VEX prefix
586 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
587 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
588 ;; still prefix_0f 1, with prefix_extra 1.
589 (define_attr "length_vex" ""
590 (if_then_else (and (eq_attr "prefix_0f" "1")
591 (eq_attr "prefix_extra" "0"))
592 (if_then_else (eq_attr "prefix_vex_w" "1")
593 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
594 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
595 (if_then_else (eq_attr "prefix_vex_w" "1")
596 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
597 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
599 ;; 4-bytes evex prefix and 1 byte opcode.
600 (define_attr "length_evex" "" (const_int 5))
602 ;; Set when modrm byte is used.
603 (define_attr "modrm" ""
604 (cond [(eq_attr "type" "str,leave")
606 (eq_attr "unit" "i387")
608 (and (eq_attr "type" "incdec")
609 (and (not (match_test "TARGET_64BIT"))
610 (ior (match_operand:SI 1 "register_operand")
611 (match_operand:HI 1 "register_operand"))))
613 (and (eq_attr "type" "push")
614 (not (match_operand 1 "memory_operand")))
616 (and (eq_attr "type" "pop")
617 (not (match_operand 0 "memory_operand")))
619 (and (eq_attr "type" "imov")
620 (and (not (eq_attr "mode" "DI"))
621 (ior (and (match_operand 0 "register_operand")
622 (match_operand 1 "immediate_operand"))
623 (ior (and (match_operand 0 "ax_reg_operand")
624 (match_operand 1 "memory_displacement_only_operand"))
625 (and (match_operand 0 "memory_displacement_only_operand")
626 (match_operand 1 "ax_reg_operand"))))))
628 (and (eq_attr "type" "call")
629 (match_operand 0 "constant_call_address_operand"))
631 (and (eq_attr "type" "callv")
632 (match_operand 1 "constant_call_address_operand"))
634 (and (eq_attr "type" "alu,alu1,icmp,test")
635 (match_operand 0 "ax_reg_operand"))
636 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
640 (define_attr "modrm_class" "none,incdec,op0,op01,op02,pushpop,unknown"
641 (cond [(eq_attr "modrm" "0")
642 (const_string "none")
643 (eq_attr "type" "alu,imul,ishift")
644 (const_string "op02")
645 (eq_attr "type" "imov,imovx,lea,alu1,icmp")
646 (const_string "op01")
647 (eq_attr "type" "incdec")
648 (const_string "incdec")
649 (eq_attr "type" "push,pop")
650 (const_string "pushpop")]
651 (const_string "unknown")))
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,mpxmk,mpxchk")
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" "mpxld")
706 (const_string "load")
707 (eq_attr "type" "mpxst")
708 (const_string "store")
709 (eq_attr "type" "push")
710 (if_then_else (match_operand 1 "memory_operand")
711 (const_string "both")
712 (const_string "store"))
713 (eq_attr "type" "pop")
714 (if_then_else (match_operand 0 "memory_operand")
715 (const_string "both")
716 (const_string "load"))
717 (eq_attr "type" "setcc")
718 (if_then_else (match_operand 0 "memory_operand")
719 (const_string "store")
720 (const_string "none"))
721 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
722 (if_then_else (ior (match_operand 0 "memory_operand")
723 (match_operand 1 "memory_operand"))
724 (const_string "load")
725 (const_string "none"))
726 (eq_attr "type" "ibr")
727 (if_then_else (match_operand 0 "memory_operand")
728 (const_string "load")
729 (const_string "none"))
730 (eq_attr "type" "call")
731 (if_then_else (match_operand 0 "constant_call_address_operand")
732 (const_string "none")
733 (const_string "load"))
734 (eq_attr "type" "callv")
735 (if_then_else (match_operand 1 "constant_call_address_operand")
736 (const_string "none")
737 (const_string "load"))
738 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
739 (match_operand 1 "memory_operand"))
740 (const_string "both")
741 (and (match_operand 0 "memory_operand")
742 (match_operand 1 "memory_operand"))
743 (const_string "both")
744 (match_operand 0 "memory_operand")
745 (const_string "store")
746 (match_operand 1 "memory_operand")
747 (const_string "load")
749 "!alu1,negnot,ishift1,
750 imov,imovx,icmp,test,bitmanip,
752 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
753 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
754 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
755 (match_operand 2 "memory_operand"))
756 (const_string "load")
757 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
758 (match_operand 3 "memory_operand"))
759 (const_string "load")
761 (const_string "none")))
763 ;; Indicates if an instruction has both an immediate and a displacement.
765 (define_attr "imm_disp" "false,true,unknown"
766 (cond [(eq_attr "type" "other,multi")
767 (const_string "unknown")
768 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
769 (and (match_operand 0 "memory_displacement_operand")
770 (match_operand 1 "immediate_operand")))
771 (const_string "true")
772 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
773 (and (match_operand 0 "memory_displacement_operand")
774 (match_operand 2 "immediate_operand")))
775 (const_string "true")
777 (const_string "false")))
779 ;; Indicates if an FP operation has an integer source.
781 (define_attr "fp_int_src" "false,true"
782 (const_string "false"))
784 ;; Defines rounding mode of an FP operation.
786 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
787 (const_string "any"))
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_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 fma_avx512f,avx512bw,noavx512bw,avx512dq,noavx512dq,
800 avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw"
801 (const_string "base"))
803 (define_attr "enabled" ""
804 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
805 (eq_attr "isa" "x64_sse4")
806 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
807 (eq_attr "isa" "x64_sse4_noavx")
808 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
809 (eq_attr "isa" "x64_avx")
810 (symbol_ref "TARGET_64BIT && TARGET_AVX")
811 (eq_attr "isa" "x64_avx512dq")
812 (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
813 (eq_attr "isa" "x64_avx512bw")
814 (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
815 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
816 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
817 (eq_attr "isa" "sse2_noavx")
818 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
819 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
820 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
821 (eq_attr "isa" "sse4_noavx")
822 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
823 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
824 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
825 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
826 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
827 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
828 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
829 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
830 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
831 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
832 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
833 (eq_attr "isa" "fma_avx512f")
834 (symbol_ref "TARGET_FMA || TARGET_AVX512F")
835 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
836 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
837 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
838 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
839 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
840 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
844 (define_attr "preferred_for_size" "" (const_int 1))
845 (define_attr "preferred_for_speed" "" (const_int 1))
847 ;; Describe a user's asm statement.
848 (define_asm_attributes
849 [(set_attr "length" "128")
850 (set_attr "type" "multi")])
852 (define_code_iterator plusminus [plus minus])
854 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
856 (define_code_iterator multdiv [mult div])
858 ;; Base name for define_insn
859 (define_code_attr plusminus_insn
860 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
861 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
863 ;; Base name for insn mnemonic.
864 (define_code_attr plusminus_mnemonic
865 [(plus "add") (ss_plus "adds") (us_plus "addus")
866 (minus "sub") (ss_minus "subs") (us_minus "subus")])
867 (define_code_attr multdiv_mnemonic
868 [(mult "mul") (div "div")])
870 ;; Mark commutative operators as such in constraints.
871 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
872 (minus "") (ss_minus "") (us_minus "")])
874 ;; Mapping of max and min
875 (define_code_iterator maxmin [smax smin umax umin])
877 ;; Mapping of signed max and min
878 (define_code_iterator smaxmin [smax smin])
880 ;; Mapping of unsigned max and min
881 (define_code_iterator umaxmin [umax umin])
883 ;; Base name for integer and FP insn mnemonic
884 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
885 (umax "maxu") (umin "minu")])
886 (define_code_attr maxmin_float [(smax "max") (smin "min")])
888 (define_int_iterator IEEE_MAXMIN
892 (define_int_attr ieee_maxmin
893 [(UNSPEC_IEEE_MAX "max")
894 (UNSPEC_IEEE_MIN "min")])
896 ;; Mapping of logic operators
897 (define_code_iterator any_logic [and ior xor])
898 (define_code_iterator any_or [ior xor])
899 (define_code_iterator fpint_logic [and xor])
901 ;; Base name for insn mnemonic.
902 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
904 ;; Mapping of logic-shift operators
905 (define_code_iterator any_lshift [ashift lshiftrt])
907 ;; Mapping of shift-right operators
908 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
910 ;; Mapping of all shift operators
911 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
913 ;; Base name for define_insn
914 (define_code_attr shift_insn
915 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
917 ;; Base name for insn mnemonic.
918 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
919 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
921 ;; Mapping of rotate operators
922 (define_code_iterator any_rotate [rotate rotatert])
924 ;; Base name for define_insn
925 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
927 ;; Base name for insn mnemonic.
928 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
930 ;; Mapping of abs neg operators
931 (define_code_iterator absneg [abs neg])
933 ;; Base name for x87 insn mnemonic.
934 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
936 ;; Used in signed and unsigned widening multiplications.
937 (define_code_iterator any_extend [sign_extend zero_extend])
939 ;; Prefix for insn menmonic.
940 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
942 ;; Prefix for define_insn
943 (define_code_attr u [(sign_extend "") (zero_extend "u")])
944 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
945 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
947 ;; Used in signed and unsigned truncations.
948 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
949 ;; Instruction suffix for truncations.
950 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
952 ;; Used in signed and unsigned fix.
953 (define_code_iterator any_fix [fix unsigned_fix])
954 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
956 ;; Used in signed and unsigned float.
957 (define_code_iterator any_float [float unsigned_float])
958 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
960 ;; All integer modes.
961 (define_mode_iterator SWI1248x [QI HI SI DI])
963 ;; All integer modes without QImode.
964 (define_mode_iterator SWI248x [HI SI DI])
966 ;; All integer modes without QImode and HImode.
967 (define_mode_iterator SWI48x [SI DI])
969 ;; All integer modes without SImode and DImode.
970 (define_mode_iterator SWI12 [QI HI])
972 ;; All integer modes without DImode.
973 (define_mode_iterator SWI124 [QI HI SI])
975 ;; All integer modes without QImode and DImode.
976 (define_mode_iterator SWI24 [HI SI])
978 ;; Single word integer modes.
979 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
981 ;; Single word integer modes without QImode.
982 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
984 ;; Single word integer modes without QImode and HImode.
985 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
987 ;; All math-dependant single and double word integer modes.
988 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
989 (HI "TARGET_HIMODE_MATH")
990 SI DI (TI "TARGET_64BIT")])
992 ;; Math-dependant single word integer modes.
993 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
994 (HI "TARGET_HIMODE_MATH")
995 SI (DI "TARGET_64BIT")])
997 ;; Math-dependant integer modes without DImode.
998 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
999 (HI "TARGET_HIMODE_MATH")
1002 ;; Math-dependant integer modes with DImode.
1003 (define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH")
1004 (HI "TARGET_HIMODE_MATH")
1005 SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")])
1007 ;; Math-dependant single word integer modes without QImode.
1008 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1009 SI (DI "TARGET_64BIT")])
1011 ;; Double word integer modes.
1012 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1013 (TI "TARGET_64BIT")])
1015 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1016 ;; compile time constant, it is faster to use <MODE_SIZE> than
1017 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1018 ;; command line options just use GET_MODE_SIZE macro.
1019 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1020 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1021 (V16QI "16") (V32QI "32") (V64QI "64")
1022 (V8HI "16") (V16HI "32") (V32HI "64")
1023 (V4SI "16") (V8SI "32") (V16SI "64")
1024 (V2DI "16") (V4DI "32") (V8DI "64")
1025 (V1TI "16") (V2TI "32") (V4TI "64")
1026 (V2DF "16") (V4DF "32") (V8DF "64")
1027 (V4SF "16") (V8SF "32") (V16SF "64")])
1029 ;; Double word integer modes as mode attribute.
1030 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1031 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1033 ;; LEA mode corresponding to an integer mode
1034 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1036 ;; Half mode for double word integer modes.
1037 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1038 (DI "TARGET_64BIT")])
1041 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1042 (BND64 "TARGET_LP64")])
1044 ;; Pointer mode corresponding to bound mode.
1045 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1048 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1051 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1053 (UNSPEC_BNDCN "cn")])
1055 ;; Instruction suffix for integer modes.
1056 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1058 ;; Instruction suffix for masks.
1059 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1061 ;; Pointer size prefix for integer modes (Intel asm dialect)
1062 (define_mode_attr iptrsize [(QI "BYTE")
1067 ;; Register class for integer modes.
1068 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1070 ;; Immediate operand constraint for integer modes.
1071 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1073 ;; General operand constraint for word modes.
1074 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1076 ;; Immediate operand constraint for double integer modes.
1077 (define_mode_attr di [(SI "nF") (DI "Wd")])
1079 ;; Immediate operand constraint for shifts.
1080 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1082 ;; General operand predicate for integer modes.
1083 (define_mode_attr general_operand
1084 [(QI "general_operand")
1085 (HI "general_operand")
1086 (SI "x86_64_general_operand")
1087 (DI "x86_64_general_operand")
1088 (TI "x86_64_general_operand")])
1090 ;; General operand predicate for integer modes, where for TImode
1091 ;; we need both words of the operand to be general operands.
1092 (define_mode_attr general_hilo_operand
1093 [(QI "general_operand")
1094 (HI "general_operand")
1095 (SI "x86_64_general_operand")
1096 (DI "x86_64_general_operand")
1097 (TI "x86_64_hilo_general_operand")])
1099 ;; General sign extend operand predicate for integer modes,
1100 ;; which disallows VOIDmode operands and thus it is suitable
1101 ;; for use inside sign_extend.
1102 (define_mode_attr general_sext_operand
1103 [(QI "sext_operand")
1105 (SI "x86_64_sext_operand")
1106 (DI "x86_64_sext_operand")])
1108 ;; General sign/zero extend operand predicate for integer modes.
1109 (define_mode_attr general_szext_operand
1110 [(QI "general_operand")
1111 (HI "general_operand")
1112 (SI "x86_64_szext_general_operand")
1113 (DI "x86_64_szext_general_operand")])
1115 ;; Immediate operand predicate for integer modes.
1116 (define_mode_attr immediate_operand
1117 [(QI "immediate_operand")
1118 (HI "immediate_operand")
1119 (SI "x86_64_immediate_operand")
1120 (DI "x86_64_immediate_operand")])
1122 ;; Nonmemory operand predicate for integer modes.
1123 (define_mode_attr nonmemory_operand
1124 [(QI "nonmemory_operand")
1125 (HI "nonmemory_operand")
1126 (SI "x86_64_nonmemory_operand")
1127 (DI "x86_64_nonmemory_operand")])
1129 ;; Operand predicate for shifts.
1130 (define_mode_attr shift_operand
1131 [(QI "nonimmediate_operand")
1132 (HI "nonimmediate_operand")
1133 (SI "nonimmediate_operand")
1134 (DI "shiftdi_operand")
1135 (TI "register_operand")])
1137 ;; Operand predicate for shift argument.
1138 (define_mode_attr shift_immediate_operand
1139 [(QI "const_1_to_31_operand")
1140 (HI "const_1_to_31_operand")
1141 (SI "const_1_to_31_operand")
1142 (DI "const_1_to_63_operand")])
1144 ;; Input operand predicate for arithmetic left shifts.
1145 (define_mode_attr ashl_input_operand
1146 [(QI "nonimmediate_operand")
1147 (HI "nonimmediate_operand")
1148 (SI "nonimmediate_operand")
1149 (DI "ashldi_input_operand")
1150 (TI "reg_or_pm1_operand")])
1152 ;; SSE and x87 SFmode and DFmode floating point modes
1153 (define_mode_iterator MODEF [SF DF])
1155 ;; All x87 floating point modes
1156 (define_mode_iterator X87MODEF [SF DF XF])
1158 ;; SSE instruction suffix for various modes
1159 (define_mode_attr ssemodesuffix
1160 [(SF "ss") (DF "sd")
1161 (V16SF "ps") (V8DF "pd")
1162 (V8SF "ps") (V4DF "pd")
1163 (V4SF "ps") (V2DF "pd")
1164 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1165 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1166 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1168 ;; SSE vector suffix for floating point modes
1169 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1171 ;; SSE vector mode corresponding to a scalar mode
1172 (define_mode_attr ssevecmode
1173 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1174 (define_mode_attr ssevecmodelower
1175 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1177 ;; AVX512F vector mode corresponding to a scalar mode
1178 (define_mode_attr avx512fvecmode
1179 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1181 ;; Instruction suffix for REX 64bit operators.
1182 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1184 ;; This mode iterator allows :P to be used for patterns that operate on
1185 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1186 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1188 ;; This mode iterator allows :W to be used for patterns that operate on
1189 ;; word_mode sized quantities.
1190 (define_mode_iterator W
1191 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1193 ;; This mode iterator allows :PTR to be used for patterns that operate on
1194 ;; ptr_mode sized quantities.
1195 (define_mode_iterator PTR
1196 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1198 ;; Scheduling descriptions
1200 (include "pentium.md")
1203 (include "athlon.md")
1204 (include "bdver1.md")
1205 (include "bdver3.md")
1206 (include "btver2.md")
1207 (include "znver1.md")
1208 (include "geode.md")
1211 (include "core2.md")
1212 (include "haswell.md")
1215 ;; Operand and operator predicates and constraints
1217 (include "predicates.md")
1218 (include "constraints.md")
1221 ;; Compare and branch/compare and store instructions.
1223 (define_expand "cbranch<mode>4"
1224 [(set (reg:CC FLAGS_REG)
1225 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1226 (match_operand:SDWIM 2 "<general_operand>")))
1227 (set (pc) (if_then_else
1228 (match_operator 0 "ordered_comparison_operator"
1229 [(reg:CC FLAGS_REG) (const_int 0)])
1230 (label_ref (match_operand 3))
1234 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1235 operands[1] = force_reg (<MODE>mode, operands[1]);
1236 ix86_expand_branch (GET_CODE (operands[0]),
1237 operands[1], operands[2], operands[3]);
1241 (define_expand "cstore<mode>4"
1242 [(set (reg:CC FLAGS_REG)
1243 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1244 (match_operand:SWIM 3 "<general_operand>")))
1245 (set (match_operand:QI 0 "register_operand")
1246 (match_operator 1 "ordered_comparison_operator"
1247 [(reg:CC FLAGS_REG) (const_int 0)]))]
1250 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1251 operands[2] = force_reg (<MODE>mode, operands[2]);
1252 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1253 operands[2], operands[3]);
1257 (define_expand "cmp<mode>_1"
1258 [(set (reg:CC FLAGS_REG)
1259 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1260 (match_operand:SWI48 1 "<general_operand>")))])
1262 (define_insn "*cmp<mode>_ccno_1"
1263 [(set (reg FLAGS_REG)
1264 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1265 (match_operand:SWI 1 "const0_operand")))]
1266 "ix86_match_ccmode (insn, CCNOmode)"
1268 test{<imodesuffix>}\t%0, %0
1269 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1270 [(set_attr "type" "test,icmp")
1271 (set_attr "length_immediate" "0,1")
1272 (set_attr "modrm_class" "op0,unknown")
1273 (set_attr "mode" "<MODE>")])
1275 (define_insn "*cmp<mode>_1"
1276 [(set (reg FLAGS_REG)
1277 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1278 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1279 "ix86_match_ccmode (insn, CCmode)"
1280 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1281 [(set_attr "type" "icmp")
1282 (set_attr "mode" "<MODE>")])
1284 (define_insn "*cmp<mode>_minus_1"
1285 [(set (reg FLAGS_REG)
1287 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1288 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1290 "ix86_match_ccmode (insn, CCGOCmode)"
1291 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1292 [(set_attr "type" "icmp")
1293 (set_attr "mode" "<MODE>")])
1295 (define_insn "*cmpqi_ext_1"
1296 [(set (reg FLAGS_REG)
1298 (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1301 (match_operand 1 "ext_register_operand" "Q,Q")
1303 (const_int 8)) 0)))]
1304 "ix86_match_ccmode (insn, CCmode)"
1305 "cmp{b}\t{%h1, %0|%0, %h1}"
1306 [(set_attr "isa" "*,nox64")
1307 (set_attr "type" "icmp")
1308 (set_attr "mode" "QI")])
1310 (define_insn "*cmpqi_ext_2"
1311 [(set (reg FLAGS_REG)
1315 (match_operand 0 "ext_register_operand" "Q")
1318 (match_operand:QI 1 "const0_operand")))]
1319 "ix86_match_ccmode (insn, CCNOmode)"
1321 [(set_attr "type" "test")
1322 (set_attr "length_immediate" "0")
1323 (set_attr "mode" "QI")])
1325 (define_expand "cmpqi_ext_3"
1326 [(set (reg:CC FLAGS_REG)
1330 (match_operand 0 "ext_register_operand")
1333 (match_operand:QI 1 "const_int_operand")))])
1335 (define_insn "*cmpqi_ext_3"
1336 [(set (reg FLAGS_REG)
1340 (match_operand 0 "ext_register_operand" "Q,Q")
1343 (match_operand:QI 1 "general_operand" "QnBc,m")))]
1344 "ix86_match_ccmode (insn, CCmode)"
1345 "cmp{b}\t{%1, %h0|%h0, %1}"
1346 [(set_attr "isa" "*,nox64")
1347 (set_attr "type" "icmp")
1348 (set_attr "mode" "QI")])
1350 (define_insn "*cmpqi_ext_4"
1351 [(set (reg FLAGS_REG)
1355 (match_operand 0 "ext_register_operand" "Q")
1360 (match_operand 1 "ext_register_operand" "Q")
1362 (const_int 8)) 0)))]
1363 "ix86_match_ccmode (insn, CCmode)"
1364 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1365 [(set_attr "type" "icmp")
1366 (set_attr "mode" "QI")])
1368 ;; These implement float point compares.
1369 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1370 ;; which would allow mix and match FP modes on the compares. Which is what
1371 ;; the old patterns did, but with many more of them.
1373 (define_expand "cbranchxf4"
1374 [(set (reg:CC FLAGS_REG)
1375 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1376 (match_operand:XF 2 "nonmemory_operand")))
1377 (set (pc) (if_then_else
1378 (match_operator 0 "ix86_fp_comparison_operator"
1381 (label_ref (match_operand 3))
1385 ix86_expand_branch (GET_CODE (operands[0]),
1386 operands[1], operands[2], operands[3]);
1390 (define_expand "cstorexf4"
1391 [(set (reg:CC FLAGS_REG)
1392 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1393 (match_operand:XF 3 "nonmemory_operand")))
1394 (set (match_operand:QI 0 "register_operand")
1395 (match_operator 1 "ix86_fp_comparison_operator"
1400 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1401 operands[2], operands[3]);
1405 (define_expand "cbranch<mode>4"
1406 [(set (reg:CC FLAGS_REG)
1407 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1408 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1409 (set (pc) (if_then_else
1410 (match_operator 0 "ix86_fp_comparison_operator"
1413 (label_ref (match_operand 3))
1415 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1417 ix86_expand_branch (GET_CODE (operands[0]),
1418 operands[1], operands[2], operands[3]);
1422 (define_expand "cstore<mode>4"
1423 [(set (reg:CC FLAGS_REG)
1424 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1425 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1426 (set (match_operand:QI 0 "register_operand")
1427 (match_operator 1 "ix86_fp_comparison_operator"
1430 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1432 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1433 operands[2], operands[3]);
1437 (define_expand "cbranchcc4"
1438 [(set (pc) (if_then_else
1439 (match_operator 0 "comparison_operator"
1440 [(match_operand 1 "flags_reg_operand")
1441 (match_operand 2 "const0_operand")])
1442 (label_ref (match_operand 3))
1446 ix86_expand_branch (GET_CODE (operands[0]),
1447 operands[1], operands[2], operands[3]);
1451 (define_expand "cstorecc4"
1452 [(set (match_operand:QI 0 "register_operand")
1453 (match_operator 1 "comparison_operator"
1454 [(match_operand 2 "flags_reg_operand")
1455 (match_operand 3 "const0_operand")]))]
1458 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1459 operands[2], operands[3]);
1464 ;; FP compares, step 1:
1465 ;; Set the FP condition codes.
1467 ;; CCFPmode compare with exceptions
1468 ;; CCFPUmode compare with no exceptions
1470 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1471 ;; used to manage the reg stack popping would not be preserved.
1473 (define_insn "*cmp<mode>_0_i387"
1474 [(set (match_operand:HI 0 "register_operand" "=a")
1477 (match_operand:X87MODEF 1 "register_operand" "f")
1478 (match_operand:X87MODEF 2 "const0_operand"))]
1481 "* return output_fp_compare (insn, operands, false, false);"
1482 [(set_attr "type" "multi")
1483 (set_attr "unit" "i387")
1484 (set_attr "mode" "<MODE>")])
1486 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1487 [(set (reg:CCFP FLAGS_REG)
1489 (match_operand:X87MODEF 1 "register_operand" "f")
1490 (match_operand:X87MODEF 2 "const0_operand")))
1491 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1492 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1494 "&& reload_completed"
1497 [(compare:CCFP (match_dup 1)(match_dup 2))]
1499 (set (reg:CC FLAGS_REG)
1500 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1502 [(set_attr "type" "multi")
1503 (set_attr "unit" "i387")
1504 (set_attr "mode" "<MODE>")])
1506 (define_insn "*cmpxf_i387"
1507 [(set (match_operand:HI 0 "register_operand" "=a")
1510 (match_operand:XF 1 "register_operand" "f")
1511 (match_operand:XF 2 "register_operand" "f"))]
1514 "* return output_fp_compare (insn, operands, false, false);"
1515 [(set_attr "type" "multi")
1516 (set_attr "unit" "i387")
1517 (set_attr "mode" "XF")])
1519 (define_insn_and_split "*cmpxf_cc_i387"
1520 [(set (reg:CCFP FLAGS_REG)
1522 (match_operand:XF 1 "register_operand" "f")
1523 (match_operand:XF 2 "register_operand" "f")))
1524 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1525 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1527 "&& reload_completed"
1530 [(compare:CCFP (match_dup 1)(match_dup 2))]
1532 (set (reg:CC FLAGS_REG)
1533 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1535 [(set_attr "type" "multi")
1536 (set_attr "unit" "i387")
1537 (set_attr "mode" "XF")])
1539 (define_insn "*cmp<mode>_i387"
1540 [(set (match_operand:HI 0 "register_operand" "=a")
1543 (match_operand:MODEF 1 "register_operand" "f")
1544 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1547 "* return output_fp_compare (insn, operands, false, false);"
1548 [(set_attr "type" "multi")
1549 (set_attr "unit" "i387")
1550 (set_attr "mode" "<MODE>")])
1552 (define_insn_and_split "*cmp<mode>_cc_i387"
1553 [(set (reg:CCFP FLAGS_REG)
1555 (match_operand:MODEF 1 "register_operand" "f")
1556 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1557 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1558 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1560 "&& reload_completed"
1563 [(compare:CCFP (match_dup 1)(match_dup 2))]
1565 (set (reg:CC FLAGS_REG)
1566 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1568 [(set_attr "type" "multi")
1569 (set_attr "unit" "i387")
1570 (set_attr "mode" "<MODE>")])
1572 (define_insn "*cmpu<mode>_i387"
1573 [(set (match_operand:HI 0 "register_operand" "=a")
1576 (match_operand:X87MODEF 1 "register_operand" "f")
1577 (match_operand:X87MODEF 2 "register_operand" "f"))]
1580 "* return output_fp_compare (insn, operands, false, true);"
1581 [(set_attr "type" "multi")
1582 (set_attr "unit" "i387")
1583 (set_attr "mode" "<MODE>")])
1585 (define_insn_and_split "*cmpu<mode>_cc_i387"
1586 [(set (reg:CCFPU FLAGS_REG)
1588 (match_operand:X87MODEF 1 "register_operand" "f")
1589 (match_operand:X87MODEF 2 "register_operand" "f")))
1590 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1591 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1593 "&& reload_completed"
1596 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1598 (set (reg:CC FLAGS_REG)
1599 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1601 [(set_attr "type" "multi")
1602 (set_attr "unit" "i387")
1603 (set_attr "mode" "<MODE>")])
1605 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1606 [(set (match_operand:HI 0 "register_operand" "=a")
1609 (match_operand:X87MODEF 1 "register_operand" "f")
1610 (match_operator:X87MODEF 3 "float_operator"
1611 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1614 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1615 || optimize_function_for_size_p (cfun))"
1616 "* return output_fp_compare (insn, operands, false, false);"
1617 [(set_attr "type" "multi")
1618 (set_attr "unit" "i387")
1619 (set_attr "fp_int_src" "true")
1620 (set_attr "mode" "<SWI24:MODE>")])
1622 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1623 [(set (reg:CCFP FLAGS_REG)
1625 (match_operand:X87MODEF 1 "register_operand" "f")
1626 (match_operator:X87MODEF 3 "float_operator"
1627 [(match_operand:SWI24 2 "memory_operand" "m")])))
1628 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1629 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1630 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1631 || optimize_function_for_size_p (cfun))"
1633 "&& reload_completed"
1638 (match_op_dup 3 [(match_dup 2)]))]
1640 (set (reg:CC FLAGS_REG)
1641 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1643 [(set_attr "type" "multi")
1644 (set_attr "unit" "i387")
1645 (set_attr "fp_int_src" "true")
1646 (set_attr "mode" "<SWI24:MODE>")])
1648 ;; FP compares, step 2
1649 ;; Move the fpsw to ax.
1651 (define_insn "x86_fnstsw_1"
1652 [(set (match_operand:HI 0 "register_operand" "=a")
1653 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1656 [(set_attr "length" "2")
1657 (set_attr "mode" "SI")
1658 (set_attr "unit" "i387")])
1660 ;; FP compares, step 3
1661 ;; Get ax into flags, general case.
1663 (define_insn "x86_sahf_1"
1664 [(set (reg:CC FLAGS_REG)
1665 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1669 #ifndef HAVE_AS_IX86_SAHF
1671 return ASM_BYTE "0x9e";
1676 [(set_attr "length" "1")
1677 (set_attr "athlon_decode" "vector")
1678 (set_attr "amdfam10_decode" "direct")
1679 (set_attr "bdver1_decode" "direct")
1680 (set_attr "mode" "SI")])
1682 ;; Pentium Pro can do steps 1 through 3 in one go.
1683 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1684 ;; (these i387 instructions set flags directly)
1686 (define_mode_iterator FPCMP [CCFP CCFPU])
1687 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1689 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>"
1690 [(set (reg:FPCMP FLAGS_REG)
1692 (match_operand:MODEF 0 "register_operand" "f,v")
1693 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1694 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1695 || (TARGET_80387 && TARGET_CMOVE)"
1696 "* return output_fp_compare (insn, operands, true,
1697 <FPCMP:MODE>mode == CCFPUmode);"
1698 [(set_attr "type" "fcmp,ssecomi")
1699 (set_attr "prefix" "orig,maybe_vex")
1700 (set_attr "mode" "<MODEF:MODE>")
1701 (set_attr "prefix_rep" "*,0")
1702 (set (attr "prefix_data16")
1703 (cond [(eq_attr "alternative" "0")
1705 (eq_attr "mode" "DF")
1708 (const_string "0")))
1709 (set_attr "athlon_decode" "vector")
1710 (set_attr "amdfam10_decode" "direct")
1711 (set_attr "bdver1_decode" "double")
1712 (set_attr "znver1_decode" "double")
1713 (set (attr "enabled")
1715 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1717 (eq_attr "alternative" "0")
1718 (symbol_ref "TARGET_MIX_SSE_I387")
1719 (symbol_ref "true"))
1721 (eq_attr "alternative" "0")
1723 (symbol_ref "false"))))])
1725 (define_insn "*cmpi<unord>xf_i387"
1726 [(set (reg:FPCMP FLAGS_REG)
1728 (match_operand:XF 0 "register_operand" "f")
1729 (match_operand:XF 1 "register_operand" "f")))]
1730 "TARGET_80387 && TARGET_CMOVE"
1731 "* return output_fp_compare (insn, operands, true,
1732 <MODE>mode == CCFPUmode);"
1733 [(set_attr "type" "fcmp")
1734 (set_attr "mode" "XF")
1735 (set_attr "athlon_decode" "vector")
1736 (set_attr "amdfam10_decode" "direct")
1737 (set_attr "bdver1_decode" "double")
1738 (set_attr "znver1_decode" "double")])
1740 ;; Push/pop instructions.
1742 (define_insn "*push<mode>2"
1743 [(set (match_operand:DWI 0 "push_operand" "=<")
1744 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1747 [(set_attr "type" "multi")
1748 (set_attr "mode" "<MODE>")])
1751 [(set (match_operand:DWI 0 "push_operand")
1752 (match_operand:DWI 1 "general_gr_operand"))]
1755 "ix86_split_long_move (operands); DONE;")
1757 (define_insn "*pushdi2_rex64"
1758 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1759 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1764 [(set_attr "type" "push,multi")
1765 (set_attr "mode" "DI")])
1767 ;; Convert impossible pushes of immediate to existing instructions.
1768 ;; First try to get scratch register and go through it. In case this
1769 ;; fails, push sign extended lower part first and then overwrite
1770 ;; upper part by 32bit move.
1772 [(match_scratch:DI 2 "r")
1773 (set (match_operand:DI 0 "push_operand")
1774 (match_operand:DI 1 "immediate_operand"))]
1775 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1776 && !x86_64_immediate_operand (operands[1], DImode)"
1777 [(set (match_dup 2) (match_dup 1))
1778 (set (match_dup 0) (match_dup 2))])
1780 ;; We need to define this as both peepholer and splitter for case
1781 ;; peephole2 pass is not run.
1782 ;; "&& 1" is needed to keep it from matching the previous pattern.
1784 [(set (match_operand:DI 0 "push_operand")
1785 (match_operand:DI 1 "immediate_operand"))]
1786 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1787 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1788 [(set (match_dup 0) (match_dup 1))
1789 (set (match_dup 2) (match_dup 3))]
1791 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1793 operands[1] = gen_lowpart (DImode, operands[2]);
1794 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1799 [(set (match_operand:DI 0 "push_operand")
1800 (match_operand:DI 1 "immediate_operand"))]
1801 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1802 ? epilogue_completed : reload_completed)
1803 && !symbolic_operand (operands[1], DImode)
1804 && !x86_64_immediate_operand (operands[1], DImode)"
1805 [(set (match_dup 0) (match_dup 1))
1806 (set (match_dup 2) (match_dup 3))]
1808 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1810 operands[1] = gen_lowpart (DImode, operands[2]);
1811 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1815 (define_insn "*pushsi2"
1816 [(set (match_operand:SI 0 "push_operand" "=<")
1817 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1820 [(set_attr "type" "push")
1821 (set_attr "mode" "SI")])
1823 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1824 ;; "push a byte/word". But actually we use pushl, which has the effect
1825 ;; of rounding the amount pushed up to a word.
1827 ;; For TARGET_64BIT we always round up to 8 bytes.
1828 (define_insn "*push<mode>2_rex64"
1829 [(set (match_operand:SWI124 0 "push_operand" "=X")
1830 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1833 [(set_attr "type" "push")
1834 (set_attr "mode" "DI")])
1836 (define_insn "*push<mode>2"
1837 [(set (match_operand:SWI12 0 "push_operand" "=X")
1838 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1841 [(set_attr "type" "push")
1842 (set_attr "mode" "SI")])
1844 (define_insn "*push<mode>2_prologue"
1845 [(set (match_operand:W 0 "push_operand" "=<")
1846 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1847 (clobber (mem:BLK (scratch)))]
1849 "push{<imodesuffix>}\t%1"
1850 [(set_attr "type" "push")
1851 (set_attr "mode" "<MODE>")])
1853 (define_insn "*pop<mode>1"
1854 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1855 (match_operand:W 1 "pop_operand" ">"))]
1857 "pop{<imodesuffix>}\t%0"
1858 [(set_attr "type" "pop")
1859 (set_attr "mode" "<MODE>")])
1861 (define_insn "*pop<mode>1_epilogue"
1862 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1863 (match_operand:W 1 "pop_operand" ">"))
1864 (clobber (mem:BLK (scratch)))]
1866 "pop{<imodesuffix>}\t%0"
1867 [(set_attr "type" "pop")
1868 (set_attr "mode" "<MODE>")])
1870 (define_insn "*pushfl<mode>2"
1871 [(set (match_operand:W 0 "push_operand" "=<")
1872 (match_operand:W 1 "flags_reg_operand"))]
1874 "pushf{<imodesuffix>}"
1875 [(set_attr "type" "push")
1876 (set_attr "mode" "<MODE>")])
1878 (define_insn "*popfl<mode>1"
1879 [(set (match_operand:W 0 "flags_reg_operand")
1880 (match_operand:W 1 "pop_operand" ">"))]
1882 "popf{<imodesuffix>}"
1883 [(set_attr "type" "pop")
1884 (set_attr "mode" "<MODE>")])
1887 ;; Reload patterns to support multi-word load/store
1888 ;; with non-offsetable address.
1889 (define_expand "reload_noff_store"
1890 [(parallel [(match_operand 0 "memory_operand" "=m")
1891 (match_operand 1 "register_operand" "r")
1892 (match_operand:DI 2 "register_operand" "=&r")])]
1895 rtx mem = operands[0];
1896 rtx addr = XEXP (mem, 0);
1898 emit_move_insn (operands[2], addr);
1899 mem = replace_equiv_address_nv (mem, operands[2]);
1901 emit_insn (gen_rtx_SET (mem, operands[1]));
1905 (define_expand "reload_noff_load"
1906 [(parallel [(match_operand 0 "register_operand" "=r")
1907 (match_operand 1 "memory_operand" "m")
1908 (match_operand:DI 2 "register_operand" "=r")])]
1911 rtx mem = operands[1];
1912 rtx addr = XEXP (mem, 0);
1914 emit_move_insn (operands[2], addr);
1915 mem = replace_equiv_address_nv (mem, operands[2]);
1917 emit_insn (gen_rtx_SET (operands[0], mem));
1921 ;; Move instructions.
1923 (define_expand "movxi"
1924 [(set (match_operand:XI 0 "nonimmediate_operand")
1925 (match_operand:XI 1 "general_operand"))]
1927 "ix86_expand_vector_move (XImode, operands); DONE;")
1929 (define_expand "movoi"
1930 [(set (match_operand:OI 0 "nonimmediate_operand")
1931 (match_operand:OI 1 "general_operand"))]
1933 "ix86_expand_vector_move (OImode, operands); DONE;")
1935 (define_expand "movti"
1936 [(set (match_operand:TI 0 "nonimmediate_operand")
1937 (match_operand:TI 1 "general_operand"))]
1938 "TARGET_64BIT || TARGET_SSE"
1941 ix86_expand_move (TImode, operands);
1943 ix86_expand_vector_move (TImode, operands);
1947 ;; This expands to what emit_move_complex would generate if we didn't
1948 ;; have a movti pattern. Having this avoids problems with reload on
1949 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1950 ;; to have around all the time.
1951 (define_expand "movcdi"
1952 [(set (match_operand:CDI 0 "nonimmediate_operand")
1953 (match_operand:CDI 1 "general_operand"))]
1956 if (push_operand (operands[0], CDImode))
1957 emit_move_complex_push (CDImode, operands[0], operands[1]);
1959 emit_move_complex_parts (operands[0], operands[1]);
1963 (define_expand "mov<mode>"
1964 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1965 (match_operand:SWI1248x 1 "general_operand"))]
1967 "ix86_expand_move (<MODE>mode, operands); DONE;")
1969 (define_insn "*mov<mode>_xor"
1970 [(set (match_operand:SWI48 0 "register_operand" "=r")
1971 (match_operand:SWI48 1 "const0_operand"))
1972 (clobber (reg:CC FLAGS_REG))]
1975 [(set_attr "type" "alu1")
1976 (set_attr "modrm_class" "op0")
1977 (set_attr "mode" "SI")
1978 (set_attr "length_immediate" "0")])
1980 (define_insn "*mov<mode>_or"
1981 [(set (match_operand:SWI48 0 "register_operand" "=r")
1982 (match_operand:SWI48 1 "constm1_operand"))
1983 (clobber (reg:CC FLAGS_REG))]
1985 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1986 [(set_attr "type" "alu1")
1987 (set_attr "mode" "<MODE>")
1988 (set_attr "length_immediate" "1")])
1990 (define_insn "*movxi_internal_avx512f"
1991 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m")
1992 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
1994 && (register_operand (operands[0], XImode)
1995 || register_operand (operands[1], XImode))"
1997 switch (get_attr_type (insn))
2000 return standard_sse_constant_opcode (insn, operands[1]);
2003 if (misaligned_operand (operands[0], XImode)
2004 || misaligned_operand (operands[1], XImode))
2005 return "vmovdqu32\t{%1, %0|%0, %1}";
2007 return "vmovdqa32\t{%1, %0|%0, %1}";
2013 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2014 (set_attr "prefix" "evex")
2015 (set_attr "mode" "XI")])
2017 (define_insn "*movoi_internal_avx"
2018 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m")
2019 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2021 && (register_operand (operands[0], OImode)
2022 || register_operand (operands[1], OImode))"
2024 switch (get_attr_type (insn))
2027 return standard_sse_constant_opcode (insn, operands[1]);
2030 if (misaligned_operand (operands[0], OImode)
2031 || misaligned_operand (operands[1], OImode))
2033 if (get_attr_mode (insn) == MODE_V8SF)
2034 return "vmovups\t{%1, %0|%0, %1}";
2035 else if (get_attr_mode (insn) == MODE_XI)
2036 return "vmovdqu32\t{%1, %0|%0, %1}";
2038 return "vmovdqu\t{%1, %0|%0, %1}";
2042 if (get_attr_mode (insn) == MODE_V8SF)
2043 return "vmovaps\t{%1, %0|%0, %1}";
2044 else if (get_attr_mode (insn) == MODE_XI)
2045 return "vmovdqa32\t{%1, %0|%0, %1}";
2047 return "vmovdqa\t{%1, %0|%0, %1}";
2054 [(set_attr "isa" "*,avx2,*,*")
2055 (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2056 (set_attr "prefix" "vex")
2058 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2059 (match_operand 1 "ext_sse_reg_operand"))
2061 (and (eq_attr "alternative" "1")
2062 (match_test "TARGET_AVX512VL"))
2064 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2065 (and (eq_attr "alternative" "3")
2066 (match_test "TARGET_SSE_TYPELESS_STORES")))
2067 (const_string "V8SF")
2069 (const_string "OI")))])
2071 (define_insn "*movti_internal"
2072 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m")
2073 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v"))]
2075 && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2077 && nonimmediate_or_sse_const_operand (operands[1], TImode)
2078 && (register_operand (operands[0], TImode)
2079 || register_operand (operands[1], TImode)))"
2081 switch (get_attr_type (insn))
2087 return standard_sse_constant_opcode (insn, operands[1]);
2090 /* TDmode values are passed as TImode on the stack. Moving them
2091 to stack may result in unaligned memory access. */
2092 if (misaligned_operand (operands[0], TImode)
2093 || misaligned_operand (operands[1], TImode))
2095 if (get_attr_mode (insn) == MODE_V4SF)
2096 return "%vmovups\t{%1, %0|%0, %1}";
2097 else if (get_attr_mode (insn) == MODE_XI)
2098 return "vmovdqu32\t{%1, %0|%0, %1}";
2100 return "%vmovdqu\t{%1, %0|%0, %1}";
2104 if (get_attr_mode (insn) == MODE_V4SF)
2105 return "%vmovaps\t{%1, %0|%0, %1}";
2106 else if (get_attr_mode (insn) == MODE_XI)
2107 return "vmovdqa32\t{%1, %0|%0, %1}";
2109 return "%vmovdqa\t{%1, %0|%0, %1}";
2116 [(set_attr "isa" "x64,x64,*,sse2,*,*")
2117 (set_attr "type" "multi,multi,sselog1,sselog1,ssemov,ssemov")
2118 (set (attr "prefix")
2119 (if_then_else (eq_attr "type" "sselog1,ssemov")
2120 (const_string "maybe_vex")
2121 (const_string "orig")))
2123 (cond [(eq_attr "alternative" "0,1")
2125 (ior (match_operand 0 "ext_sse_reg_operand")
2126 (match_operand 1 "ext_sse_reg_operand"))
2128 (and (eq_attr "alternative" "3")
2129 (match_test "TARGET_AVX512VL"))
2131 (ior (not (match_test "TARGET_SSE2"))
2132 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2133 (and (eq_attr "alternative" "5")
2134 (match_test "TARGET_SSE_TYPELESS_STORES"))))
2135 (const_string "V4SF")
2136 (match_test "TARGET_AVX")
2138 (match_test "optimize_function_for_size_p (cfun)")
2139 (const_string "V4SF")
2141 (const_string "TI")))])
2143 (define_insn "*movdi_internal"
2144 [(set (match_operand:DI 0 "nonimmediate_operand"
2145 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,m,?r ,?r,?*Yi,?*Ym,?*Yi,*k,*k ,*r,*m")
2146 (match_operand:DI 1 "general_operand"
2147 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,v,*Yj,*v,r ,*Yj ,*Yn ,*r,*km,*k,*k"))]
2148 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2150 switch (get_attr_type (insn))
2153 return "kmovq\t{%1, %0|%0, %1}";
2159 return "pxor\t%0, %0";
2162 /* Handle broken assemblers that require movd instead of movq. */
2163 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2164 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2165 return "movd\t{%1, %0|%0, %1}";
2166 return "movq\t{%1, %0|%0, %1}";
2169 if (GENERAL_REG_P (operands[0]))
2170 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2172 return standard_sse_constant_opcode (insn, operands[1]);
2175 switch (get_attr_mode (insn))
2178 /* Handle broken assemblers that require movd instead of movq. */
2179 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2180 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2181 return "%vmovd\t{%1, %0|%0, %1}";
2182 return "%vmovq\t{%1, %0|%0, %1}";
2184 return "%vmovdqa\t{%1, %0|%0, %1}";
2186 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2189 gcc_assert (!TARGET_AVX);
2190 return "movlps\t{%1, %0|%0, %1}";
2192 return "%vmovaps\t{%1, %0|%0, %1}";
2199 if (SSE_REG_P (operands[0]))
2200 return "movq2dq\t{%1, %0|%0, %1}";
2202 return "movdq2q\t{%1, %0|%0, %1}";
2205 return "lea{q}\t{%E1, %0|%0, %E1}";
2208 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2209 if (get_attr_mode (insn) == MODE_SI)
2210 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2211 else if (which_alternative == 4)
2212 return "movabs{q}\t{%1, %0|%0, %1}";
2213 else if (ix86_use_lea_for_mov (insn, operands))
2214 return "lea{q}\t{%E1, %0|%0, %E1}";
2216 return "mov{q}\t{%1, %0|%0, %1}";
2223 (cond [(eq_attr "alternative" "0,1")
2224 (const_string "nox64")
2225 (eq_attr "alternative" "2,3,4,5,10,11,17,19,22,24")
2226 (const_string "x64")
2227 (eq_attr "alternative" "18")
2228 (const_string "x64_sse4")
2230 (const_string "*")))
2232 (cond [(eq_attr "alternative" "0,1")
2233 (const_string "multi")
2234 (eq_attr "alternative" "6")
2235 (const_string "mmx")
2236 (eq_attr "alternative" "7,8,9,10,11")
2237 (const_string "mmxmov")
2238 (eq_attr "alternative" "12,18")
2239 (const_string "sselog1")
2240 (eq_attr "alternative" "13,14,15,16,17,19")
2241 (const_string "ssemov")
2242 (eq_attr "alternative" "20,21")
2243 (const_string "ssecvt")
2244 (eq_attr "alternative" "22,23,24,25")
2245 (const_string "mskmov")
2246 (and (match_operand 0 "register_operand")
2247 (match_operand 1 "pic_32bit_operand"))
2248 (const_string "lea")
2250 (const_string "imov")))
2253 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2255 (const_string "*")))
2256 (set (attr "length_immediate")
2257 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2259 (eq_attr "alternative" "18")
2262 (const_string "*")))
2263 (set (attr "prefix_rex")
2264 (if_then_else (eq_attr "alternative" "10,11,17,18,19")
2266 (const_string "*")))
2267 (set (attr "prefix_extra")
2268 (if_then_else (eq_attr "alternative" "18")
2270 (const_string "*")))
2271 (set (attr "prefix")
2272 (if_then_else (eq_attr "type" "sselog1,ssemov")
2273 (const_string "maybe_vex")
2274 (const_string "orig")))
2275 (set (attr "prefix_data16")
2276 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2278 (const_string "*")))
2280 (cond [(eq_attr "alternative" "2")
2282 (eq_attr "alternative" "12,13")
2283 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2284 (match_operand 1 "ext_sse_reg_operand"))
2286 (ior (not (match_test "TARGET_SSE2"))
2287 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2288 (const_string "V4SF")
2289 (match_test "TARGET_AVX")
2291 (match_test "optimize_function_for_size_p (cfun)")
2292 (const_string "V4SF")
2294 (const_string "TI"))
2296 (and (eq_attr "alternative" "14,15,16")
2297 (not (match_test "TARGET_SSE2")))
2298 (const_string "V2SF")
2299 (eq_attr "alternative" "18")
2302 (const_string "DI")))
2303 (set (attr "enabled")
2304 (cond [(eq_attr "alternative" "15")
2306 (match_test "TARGET_STV && TARGET_SSE2")
2307 (symbol_ref "false")
2309 (eq_attr "alternative" "16")
2311 (match_test "TARGET_STV && TARGET_SSE2")
2313 (symbol_ref "false"))
2315 (const_string "*")))])
2318 [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2319 (match_operand:DWI 1 "general_gr_operand"))]
2322 "ix86_split_long_move (operands); DONE;")
2324 (define_insn "*movsi_internal"
2325 [(set (match_operand:SI 0 "nonimmediate_operand"
2326 "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k ,*rm")
2327 (match_operand:SI 1 "general_operand"
2328 "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r ,*krm,*k"))]
2329 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2331 switch (get_attr_type (insn))
2334 if (GENERAL_REG_P (operands[0]))
2335 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2337 return standard_sse_constant_opcode (insn, operands[1]);
2340 return "kmovd\t{%1, %0|%0, %1}";
2343 switch (get_attr_mode (insn))
2346 return "%vmovd\t{%1, %0|%0, %1}";
2348 return "%vmovdqa\t{%1, %0|%0, %1}";
2350 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2353 return "%vmovaps\t{%1, %0|%0, %1}";
2356 gcc_assert (!TARGET_AVX);
2357 return "movss\t{%1, %0|%0, %1}";
2364 return "pxor\t%0, %0";
2367 switch (get_attr_mode (insn))
2370 return "movq\t{%1, %0|%0, %1}";
2372 return "movd\t{%1, %0|%0, %1}";
2379 return "lea{l}\t{%E1, %0|%0, %E1}";
2382 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2383 if (ix86_use_lea_for_mov (insn, operands))
2384 return "lea{l}\t{%E1, %0|%0, %E1}";
2386 return "mov{l}\t{%1, %0|%0, %1}";
2393 (if_then_else (eq_attr "alternative" "11")
2394 (const_string "sse4")
2395 (const_string "*")))
2397 (cond [(eq_attr "alternative" "2")
2398 (const_string "mmx")
2399 (eq_attr "alternative" "3,4,5")
2400 (const_string "mmxmov")
2401 (eq_attr "alternative" "6,11")
2402 (const_string "sselog1")
2403 (eq_attr "alternative" "7,8,9,10,12")
2404 (const_string "ssemov")
2405 (eq_attr "alternative" "13,14")
2406 (const_string "mskmov")
2407 (and (match_operand 0 "register_operand")
2408 (match_operand 1 "pic_32bit_operand"))
2409 (const_string "lea")
2411 (const_string "imov")))
2412 (set (attr "length_immediate")
2413 (if_then_else (eq_attr "alternative" "11")
2415 (const_string "*")))
2416 (set (attr "prefix_extra")
2417 (if_then_else (eq_attr "alternative" "11")
2419 (const_string "*")))
2420 (set (attr "prefix")
2421 (if_then_else (eq_attr "type" "sselog1,ssemov")
2422 (const_string "maybe_vex")
2423 (const_string "orig")))
2424 (set (attr "prefix_data16")
2425 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2427 (const_string "*")))
2429 (cond [(eq_attr "alternative" "2,3")
2431 (eq_attr "alternative" "6,7")
2432 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2433 (match_operand 1 "ext_sse_reg_operand"))
2435 (ior (not (match_test "TARGET_SSE2"))
2436 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2437 (const_string "V4SF")
2438 (match_test "TARGET_AVX")
2440 (match_test "optimize_function_for_size_p (cfun)")
2441 (const_string "V4SF")
2443 (const_string "TI"))
2445 (and (eq_attr "alternative" "8,9")
2446 (not (match_test "TARGET_SSE2")))
2448 (eq_attr "alternative" "11")
2451 (const_string "SI")))])
2453 (define_insn "*movhi_internal"
2454 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m")
2455 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,r,km,k,k"))]
2456 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2458 switch (get_attr_type (insn))
2461 /* movzwl is faster than movw on p2 due to partial word stalls,
2462 though not as fast as an aligned movl. */
2463 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2466 switch (which_alternative)
2469 return "kmovw\t{%k1, %0|%0, %k1}";
2471 return "kmovw\t{%1, %k0|%k0, %1}";
2474 return "kmovw\t{%1, %0|%0, %1}";
2480 if (get_attr_mode (insn) == MODE_SI)
2481 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2483 return "mov{w}\t{%1, %0|%0, %1}";
2487 (cond [(eq_attr "alternative" "4,5,6,7")
2488 (const_string "mskmov")
2489 (match_test "optimize_function_for_size_p (cfun)")
2490 (const_string "imov")
2491 (and (eq_attr "alternative" "0")
2492 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2493 (not (match_test "TARGET_HIMODE_MATH"))))
2494 (const_string "imov")
2495 (and (eq_attr "alternative" "1,2")
2496 (match_operand:HI 1 "aligned_operand"))
2497 (const_string "imov")
2498 (and (match_test "TARGET_MOVX")
2499 (eq_attr "alternative" "0,2"))
2500 (const_string "imovx")
2502 (const_string "imov")))
2503 (set (attr "prefix")
2504 (if_then_else (eq_attr "alternative" "4,5,6,7")
2505 (const_string "vex")
2506 (const_string "orig")))
2508 (cond [(eq_attr "type" "imovx")
2510 (and (eq_attr "alternative" "1,2")
2511 (match_operand:HI 1 "aligned_operand"))
2513 (and (eq_attr "alternative" "0")
2514 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2515 (not (match_test "TARGET_HIMODE_MATH"))))
2518 (const_string "HI")))])
2520 ;; Situation is quite tricky about when to choose full sized (SImode) move
2521 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2522 ;; partial register dependency machines (such as AMD Athlon), where QImode
2523 ;; moves issue extra dependency and for partial register stalls machines
2524 ;; that don't use QImode patterns (and QImode move cause stall on the next
2527 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2528 ;; register stall machines with, where we use QImode instructions, since
2529 ;; partial register stall can be caused there. Then we use movzx.
2531 (define_insn "*movqi_internal"
2532 [(set (match_operand:QI 0 "nonimmediate_operand"
2533 "=q,q ,q ,r,r ,?r,m ,k,k,r,m,k")
2534 (match_operand:QI 1 "general_operand"
2535 "q ,qn,qm,q,rn,qm,qn,r,k,k,k,m"))]
2536 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2538 static char buf[128];
2542 switch (get_attr_type (insn))
2545 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2546 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2549 switch (which_alternative)
2552 ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
2555 ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
2559 gcc_assert (TARGET_AVX512DQ);
2562 ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
2568 suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
2570 snprintf (buf, sizeof (buf), ops, suffix);
2574 if (get_attr_mode (insn) == MODE_SI)
2575 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2577 return "mov{b}\t{%1, %0|%0, %1}";
2581 (if_then_else (eq_attr "alternative" "10,11")
2582 (const_string "avx512dq")
2583 (const_string "*")))
2585 (cond [(eq_attr "alternative" "7,8,9,10,11")
2586 (const_string "mskmov")
2587 (and (eq_attr "alternative" "5")
2588 (not (match_operand:QI 1 "aligned_operand")))
2589 (const_string "imovx")
2590 (match_test "optimize_function_for_size_p (cfun)")
2591 (const_string "imov")
2592 (and (eq_attr "alternative" "3")
2593 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2594 (not (match_test "TARGET_QIMODE_MATH"))))
2595 (const_string "imov")
2596 (eq_attr "alternative" "3,5")
2597 (const_string "imovx")
2598 (and (match_test "TARGET_MOVX")
2599 (eq_attr "alternative" "2"))
2600 (const_string "imovx")
2602 (const_string "imov")))
2603 (set (attr "prefix")
2604 (if_then_else (eq_attr "alternative" "7,8,9")
2605 (const_string "vex")
2606 (const_string "orig")))
2608 (cond [(eq_attr "alternative" "3,4,5")
2610 (eq_attr "alternative" "6")
2612 (and (eq_attr "alternative" "7,8,9")
2613 (not (match_test "TARGET_AVX512DQ")))
2615 (eq_attr "type" "imovx")
2617 (and (eq_attr "type" "imov")
2618 (and (eq_attr "alternative" "0,1")
2619 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2620 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2621 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2623 ;; Avoid partial register stalls when not using QImode arithmetic
2624 (and (eq_attr "type" "imov")
2625 (and (eq_attr "alternative" "0,1")
2626 (and (match_test "TARGET_PARTIAL_REG_STALL")
2627 (not (match_test "TARGET_QIMODE_MATH")))))
2630 (const_string "QI")))])
2632 ;; Stores and loads of ax to arbitrary constant address.
2633 ;; We fake an second form of instruction to force reload to load address
2634 ;; into register when rax is not available
2635 (define_insn "*movabs<mode>_1"
2636 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2637 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2638 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2640 /* Recover the full memory rtx. */
2641 operands[0] = SET_DEST (PATTERN (insn));
2642 switch (which_alternative)
2645 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2647 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2652 [(set_attr "type" "imov")
2653 (set_attr "modrm" "0,*")
2654 (set_attr "length_address" "8,0")
2655 (set_attr "length_immediate" "0,*")
2656 (set_attr "memory" "store")
2657 (set_attr "mode" "<MODE>")])
2659 (define_insn "*movabs<mode>_2"
2660 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2661 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2662 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2664 /* Recover the full memory rtx. */
2665 operands[1] = SET_SRC (PATTERN (insn));
2666 switch (which_alternative)
2669 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2671 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2676 [(set_attr "type" "imov")
2677 (set_attr "modrm" "0,*")
2678 (set_attr "length_address" "8,0")
2679 (set_attr "length_immediate" "0")
2680 (set_attr "memory" "load")
2681 (set_attr "mode" "<MODE>")])
2683 (define_insn "*swap<mode>"
2684 [(set (match_operand:SWI48 0 "register_operand" "+r")
2685 (match_operand:SWI48 1 "register_operand" "+r"))
2689 "xchg{<imodesuffix>}\t%1, %0"
2690 [(set_attr "type" "imov")
2691 (set_attr "mode" "<MODE>")
2692 (set_attr "pent_pair" "np")
2693 (set_attr "athlon_decode" "vector")
2694 (set_attr "amdfam10_decode" "double")
2695 (set_attr "bdver1_decode" "double")])
2697 (define_insn "*swap<mode>"
2698 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2699 (match_operand:SWI12 1 "register_operand" "+<r>,r"))
2704 xchg{<imodesuffix>}\t%1, %0
2706 [(set_attr "type" "imov")
2707 (set_attr "mode" "<MODE>,SI")
2708 (set (attr "preferred_for_size")
2709 (cond [(eq_attr "alternative" "0")
2710 (symbol_ref "false")]
2711 (symbol_ref "true")))
2712 ;; Potential partial reg stall on alternative 1.
2713 (set (attr "preferred_for_speed")
2714 (cond [(eq_attr "alternative" "1")
2715 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2716 (symbol_ref "true")))
2717 (set_attr "pent_pair" "np")
2718 (set_attr "athlon_decode" "vector")
2719 (set_attr "amdfam10_decode" "double")
2720 (set_attr "bdver1_decode" "double")])
2722 (define_expand "movstrict<mode>"
2723 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2724 (match_operand:SWI12 1 "general_operand"))]
2727 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2729 if (SUBREG_P (operands[0])
2730 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2732 /* Don't generate memory->memory moves, go through a register */
2733 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2734 operands[1] = force_reg (<MODE>mode, operands[1]);
2737 (define_insn "*movstrict<mode>_1"
2738 [(set (strict_low_part
2739 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2740 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2741 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2742 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2743 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2744 [(set_attr "type" "imov")
2745 (set_attr "mode" "<MODE>")])
2747 (define_insn "*movstrict<mode>_xor"
2748 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2749 (match_operand:SWI12 1 "const0_operand"))
2750 (clobber (reg:CC FLAGS_REG))]
2752 "xor{<imodesuffix>}\t%0, %0"
2753 [(set_attr "type" "alu1")
2754 (set_attr "modrm_class" "op0")
2755 (set_attr "mode" "<MODE>")
2756 (set_attr "length_immediate" "0")])
2758 (define_expand "extv<mode>"
2759 [(set (match_operand:SWI24 0 "register_operand")
2760 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2761 (match_operand:SI 2 "const_int_operand")
2762 (match_operand:SI 3 "const_int_operand")))]
2765 /* Handle extractions from %ah et al. */
2766 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2769 unsigned int regno = reg_or_subregno (operands[1]);
2771 /* Be careful to expand only with registers having upper parts. */
2772 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2773 operands[1] = copy_to_reg (operands[1]);
2776 (define_insn "*extv<mode>"
2777 [(set (match_operand:SWI24 0 "register_operand" "=R")
2778 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2782 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2783 [(set_attr "type" "imovx")
2784 (set_attr "mode" "SI")])
2786 (define_expand "extzv<mode>"
2787 [(set (match_operand:SWI248 0 "register_operand")
2788 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2789 (match_operand:SI 2 "const_int_operand")
2790 (match_operand:SI 3 "const_int_operand")))]
2793 if (ix86_expand_pextr (operands))
2796 /* Handle extractions from %ah et al. */
2797 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2800 unsigned int regno = reg_or_subregno (operands[1]);
2802 /* Be careful to expand only with registers having upper parts. */
2803 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2804 operands[1] = copy_to_reg (operands[1]);
2807 (define_insn "*extzv<mode>"
2808 [(set (match_operand:SWI248 0 "register_operand" "=R")
2809 (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2813 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2814 [(set_attr "type" "imovx")
2815 (set_attr "mode" "SI")])
2817 (define_insn "*extzvqi_mem_rex64"
2818 [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
2820 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2823 "TARGET_64BIT && reload_completed"
2824 "mov{b}\t{%h1, %0|%0, %h1}"
2825 [(set_attr "type" "imov")
2826 (set_attr "mode" "QI")])
2828 (define_insn "*extzvqi"
2829 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
2831 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2836 switch (get_attr_type (insn))
2839 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2841 return "mov{b}\t{%h1, %0|%0, %h1}";
2844 [(set_attr "isa" "*,*,nox64")
2846 (if_then_else (and (match_operand:QI 0 "register_operand")
2847 (ior (not (match_operand:QI 0 "QIreg_operand"))
2848 (match_test "TARGET_MOVX")))
2849 (const_string "imovx")
2850 (const_string "imov")))
2852 (if_then_else (eq_attr "type" "imovx")
2854 (const_string "QI")))])
2857 [(set (match_operand:QI 0 "register_operand")
2859 (zero_extract:SI (match_operand 1 "ext_register_operand")
2862 (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
2864 && peep2_reg_dead_p (2, operands[0])"
2867 (zero_extract:SI (match_dup 1)
2869 (const_int 8)) 0))])
2871 (define_expand "insv<mode>"
2872 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
2873 (match_operand:SI 1 "const_int_operand")
2874 (match_operand:SI 2 "const_int_operand"))
2875 (match_operand:SWI248 3 "register_operand"))]
2880 if (ix86_expand_pinsr (operands))
2883 /* Handle insertions to %ah et al. */
2884 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
2887 unsigned int regno = reg_or_subregno (operands[0]);
2889 /* Be careful to expand only with registers having upper parts. */
2890 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2891 dst = copy_to_reg (operands[0]);
2895 emit_insn (gen_insv<mode>_1 (dst, operands[3]));
2897 /* Fix up the destination if needed. */
2898 if (dst != operands[0])
2899 emit_move_insn (operands[0], dst);
2904 (define_insn "insv<mode>_1"
2905 [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
2908 (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
2911 if (CONST_INT_P (operands[1]))
2912 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
2913 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2915 [(set_attr "isa" "*,nox64")
2916 (set_attr "type" "imov")
2917 (set_attr "mode" "QI")])
2919 (define_insn "*insvqi"
2920 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2923 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2926 "mov{b}\t{%h1, %h0|%h0, %h1}"
2927 [(set_attr "type" "imov")
2928 (set_attr "mode" "QI")])
2930 ;; Floating point push instructions.
2932 (define_insn "*pushtf"
2933 [(set (match_operand:TF 0 "push_operand" "=<,<")
2934 (match_operand:TF 1 "general_no_elim_operand" "v,*roF"))]
2935 "TARGET_64BIT || TARGET_SSE"
2937 /* This insn should be already split before reg-stack. */
2940 [(set_attr "isa" "*,x64")
2941 (set_attr "type" "multi")
2942 (set_attr "unit" "sse,*")
2943 (set_attr "mode" "TF,DI")])
2945 ;; %%% Kill this when call knows how to work this out.
2947 [(set (match_operand:TF 0 "push_operand")
2948 (match_operand:TF 1 "sse_reg_operand"))]
2949 "TARGET_SSE && reload_completed"
2950 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2951 (set (match_dup 0) (match_dup 1))]
2953 /* Preserve memory attributes. */
2954 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2957 (define_insn "*pushxf"
2958 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<")
2959 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF"))]
2962 /* This insn should be already split before reg-stack. */
2965 [(set_attr "type" "multi")
2966 (set_attr "unit" "i387,*,*,*")
2968 (cond [(eq_attr "alternative" "1,2,3")
2969 (if_then_else (match_test "TARGET_64BIT")
2971 (const_string "SI"))
2973 (const_string "XF")))
2974 (set (attr "preferred_for_size")
2975 (cond [(eq_attr "alternative" "1")
2976 (symbol_ref "false")]
2977 (symbol_ref "true")))])
2979 ;; %%% Kill this when call knows how to work this out.
2981 [(set (match_operand:XF 0 "push_operand")
2982 (match_operand:XF 1 "fp_register_operand"))]
2984 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2985 (set (match_dup 0) (match_dup 1))]
2987 operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2988 /* Preserve memory attributes. */
2989 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2992 (define_insn "*pushdf"
2993 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
2994 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmF,x"))]
2997 /* This insn should be already split before reg-stack. */
3000 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3001 (set_attr "type" "multi")
3002 (set_attr "unit" "i387,*,*,*,*,sse")
3003 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3004 (set (attr "preferred_for_size")
3005 (cond [(eq_attr "alternative" "1")
3006 (symbol_ref "false")]
3007 (symbol_ref "true")))
3008 (set (attr "preferred_for_speed")
3009 (cond [(eq_attr "alternative" "1")
3010 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3011 (symbol_ref "true")))])
3013 ;; %%% Kill this when call knows how to work this out.
3015 [(set (match_operand:DF 0 "push_operand")
3016 (match_operand:DF 1 "any_fp_register_operand"))]
3018 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3019 (set (match_dup 0) (match_dup 1))]
3021 /* Preserve memory attributes. */
3022 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3025 (define_insn "*pushsf_rex64"
3026 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3027 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3030 /* Anything else should be already split before reg-stack. */
3031 gcc_assert (which_alternative == 1);
3032 return "push{q}\t%q1";
3034 [(set_attr "type" "multi,push,multi")
3035 (set_attr "unit" "i387,*,*")
3036 (set_attr "mode" "SF,DI,SF")])
3038 (define_insn "*pushsf"
3039 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3040 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3043 /* Anything else should be already split before reg-stack. */
3044 gcc_assert (which_alternative == 1);
3045 return "push{l}\t%1";
3047 [(set_attr "type" "multi,push,multi")
3048 (set_attr "unit" "i387,*,*")
3049 (set_attr "mode" "SF,SI,SF")])
3051 ;; %%% Kill this when call knows how to work this out.
3053 [(set (match_operand:SF 0 "push_operand")
3054 (match_operand:SF 1 "any_fp_register_operand"))]
3056 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3057 (set (match_dup 0) (match_dup 1))]
3059 rtx op = XEXP (operands[0], 0);
3060 if (GET_CODE (op) == PRE_DEC)
3062 gcc_assert (!TARGET_64BIT);
3067 op = XEXP (XEXP (op, 1), 1);
3068 gcc_assert (CONST_INT_P (op));
3071 /* Preserve memory attributes. */
3072 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3076 [(set (match_operand:SF 0 "push_operand")
3077 (match_operand:SF 1 "memory_operand"))]
3079 && find_constant_src (insn)"
3080 [(set (match_dup 0) (match_dup 2))]
3081 "operands[2] = find_constant_src (curr_insn);")
3084 [(set (match_operand 0 "push_operand")
3085 (match_operand 1 "general_gr_operand"))]
3087 && (GET_MODE (operands[0]) == TFmode
3088 || GET_MODE (operands[0]) == XFmode
3089 || GET_MODE (operands[0]) == DFmode)"
3091 "ix86_split_long_move (operands); DONE;")
3093 ;; Floating point move instructions.
3095 (define_expand "movtf"
3096 [(set (match_operand:TF 0 "nonimmediate_operand")
3097 (match_operand:TF 1 "nonimmediate_operand"))]
3098 "TARGET_64BIT || TARGET_SSE"
3099 "ix86_expand_move (TFmode, operands); DONE;")
3101 (define_expand "mov<mode>"
3102 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3103 (match_operand:X87MODEF 1 "general_operand"))]
3105 "ix86_expand_move (<MODE>mode, operands); DONE;")
3107 (define_insn "*movtf_internal"
3108 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3109 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3110 "(TARGET_64BIT || TARGET_SSE)
3111 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3112 && (lra_in_progress || reload_completed
3113 || !CONST_DOUBLE_P (operands[1])
3114 || ((optimize_function_for_size_p (cfun)
3115 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3116 && standard_sse_constant_p (operands[1], TFmode) == 1
3117 && !memory_operand (operands[0], TFmode))
3118 || (!TARGET_MEMORY_MISMATCH_STALL
3119 && memory_operand (operands[0], TFmode)))"
3121 switch (get_attr_type (insn))
3124 return standard_sse_constant_opcode (insn, operands[1]);
3127 /* Handle misaligned load/store since we
3128 don't have movmisaligntf pattern. */
3129 if (misaligned_operand (operands[0], TFmode)
3130 || misaligned_operand (operands[1], TFmode))
3132 if (get_attr_mode (insn) == MODE_V4SF)
3133 return "%vmovups\t{%1, %0|%0, %1}";
3134 else if (TARGET_AVX512VL
3135 && (EXT_REX_SSE_REG_P (operands[0])
3136 || EXT_REX_SSE_REG_P (operands[1])))
3137 return "vmovdqu64\t{%1, %0|%0, %1}";
3139 return "%vmovdqu\t{%1, %0|%0, %1}";
3143 if (get_attr_mode (insn) == MODE_V4SF)
3144 return "%vmovaps\t{%1, %0|%0, %1}";
3145 else if (TARGET_AVX512VL
3146 && (EXT_REX_SSE_REG_P (operands[0])
3147 || EXT_REX_SSE_REG_P (operands[1])))
3148 return "vmovdqa64\t{%1, %0|%0, %1}";
3150 return "%vmovdqa\t{%1, %0|%0, %1}";
3160 [(set_attr "isa" "*,*,*,x64,x64")
3161 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3162 (set (attr "prefix")
3163 (if_then_else (eq_attr "type" "sselog1,ssemov")
3164 (const_string "maybe_vex")
3165 (const_string "orig")))
3167 (cond [(eq_attr "alternative" "3,4")
3169 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3170 (const_string "V4SF")
3171 (and (eq_attr "alternative" "2")
3172 (match_test "TARGET_SSE_TYPELESS_STORES"))
3173 (const_string "V4SF")
3174 (match_test "TARGET_AVX")
3176 (ior (not (match_test "TARGET_SSE2"))
3177 (match_test "optimize_function_for_size_p (cfun)"))
3178 (const_string "V4SF")
3180 (const_string "TI")))])
3183 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3184 (match_operand:TF 1 "general_gr_operand"))]
3187 "ix86_split_long_move (operands); DONE;")
3189 ;; Possible store forwarding (partial memory) stall
3190 ;; in alternatives 4, 6, 7 and 8.
3191 (define_insn "*movxf_internal"
3192 [(set (match_operand:XF 0 "nonimmediate_operand"
3193 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o")
3194 (match_operand:XF 1 "general_operand"
3195 "fm,f,G,roF,r , *roF,*r,F ,C,roF,rF"))]
3196 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3197 && (lra_in_progress || reload_completed
3198 || !CONST_DOUBLE_P (operands[1])
3199 || ((optimize_function_for_size_p (cfun)
3200 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3201 && standard_80387_constant_p (operands[1]) > 0
3202 && !memory_operand (operands[0], XFmode))
3203 || (!TARGET_MEMORY_MISMATCH_STALL
3204 && memory_operand (operands[0], XFmode))
3205 || !TARGET_HARD_XF_REGS)"
3207 switch (get_attr_type (insn))
3210 if (which_alternative == 2)
3211 return standard_80387_constant_opcode (operands[1]);
3212 return output_387_reg_move (insn, operands);
3222 (cond [(eq_attr "alternative" "7")
3223 (const_string "nox64")
3224 (eq_attr "alternative" "8")
3225 (const_string "x64")
3227 (const_string "*")))
3229 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10")
3230 (const_string "multi")
3232 (const_string "fmov")))
3234 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10")
3235 (if_then_else (match_test "TARGET_64BIT")
3237 (const_string "SI"))
3239 (const_string "XF")))
3240 (set (attr "preferred_for_size")
3241 (cond [(eq_attr "alternative" "3,4")
3242 (symbol_ref "false")]
3243 (symbol_ref "true")))
3244 (set (attr "enabled")
3245 (cond [(eq_attr "alternative" "9,10")
3247 (match_test "TARGET_HARD_XF_REGS")
3248 (symbol_ref "false")
3250 (not (match_test "TARGET_HARD_XF_REGS"))
3251 (symbol_ref "false")
3253 (const_string "*")))])
3256 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3257 (match_operand:XF 1 "general_gr_operand"))]
3260 "ix86_split_long_move (operands); DONE;")
3262 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3263 (define_insn "*movdf_internal"
3264 [(set (match_operand:DF 0 "nonimmediate_operand"
3265 "=Yf*f,m ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi,r ,o ,r ,m")
3266 (match_operand:DF 1 "general_operand"
3267 "Yf*fm,Yf*f,G ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r ,roF,rF,rmF,rC"))]
3268 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3269 && (lra_in_progress || reload_completed
3270 || !CONST_DOUBLE_P (operands[1])
3271 || ((optimize_function_for_size_p (cfun)
3272 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3273 && ((IS_STACK_MODE (DFmode)
3274 && standard_80387_constant_p (operands[1]) > 0)
3275 || (TARGET_SSE2 && TARGET_SSE_MATH
3276 && standard_sse_constant_p (operands[1], DFmode) == 1))
3277 && !memory_operand (operands[0], DFmode))
3278 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3279 && memory_operand (operands[0], DFmode))
3280 || !TARGET_HARD_DF_REGS)"
3282 switch (get_attr_type (insn))
3285 if (which_alternative == 2)
3286 return standard_80387_constant_opcode (operands[1]);
3287 return output_387_reg_move (insn, operands);
3293 if (get_attr_mode (insn) == MODE_SI)
3294 return "mov{l}\t{%1, %k0|%k0, %1}";
3295 else if (which_alternative == 11)
3296 return "movabs{q}\t{%1, %0|%0, %1}";
3298 return "mov{q}\t{%1, %0|%0, %1}";
3301 return standard_sse_constant_opcode (insn, operands[1]);
3304 switch (get_attr_mode (insn))
3307 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3308 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3309 return "%vmovsd\t{%1, %0|%0, %1}";
3312 return "%vmovaps\t{%1, %0|%0, %1}";
3314 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3316 return "%vmovapd\t{%1, %0|%0, %1}";
3319 gcc_assert (!TARGET_AVX);
3320 return "movlps\t{%1, %0|%0, %1}";
3322 gcc_assert (!TARGET_AVX);
3323 return "movlpd\t{%1, %0|%0, %1}";
3326 /* Handle broken assemblers that require movd instead of movq. */
3327 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3328 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3329 return "%vmovd\t{%1, %0|%0, %1}";
3330 return "%vmovq\t{%1, %0|%0, %1}";
3341 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3342 (const_string "nox64")
3343 (eq_attr "alternative" "8,9,10,11,20,21,24,25")
3344 (const_string "x64")
3345 (eq_attr "alternative" "12,13,14,15")
3346 (const_string "sse2")
3348 (const_string "*")))
3350 (cond [(eq_attr "alternative" "0,1,2")
3351 (const_string "fmov")
3352 (eq_attr "alternative" "3,4,5,6,7,22,23")
3353 (const_string "multi")
3354 (eq_attr "alternative" "8,9,10,11,24,25")
3355 (const_string "imov")
3356 (eq_attr "alternative" "12,16")
3357 (const_string "sselog1")
3359 (const_string "ssemov")))
3361 (if_then_else (eq_attr "alternative" "11")
3363 (const_string "*")))
3364 (set (attr "length_immediate")
3365 (if_then_else (eq_attr "alternative" "11")
3367 (const_string "*")))
3368 (set (attr "prefix")
3369 (if_then_else (eq_attr "type" "sselog1,ssemov")
3370 (const_string "maybe_vex")
3371 (const_string "orig")))
3372 (set (attr "prefix_data16")
3374 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3375 (eq_attr "mode" "V1DF"))
3377 (const_string "*")))
3379 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3381 (eq_attr "alternative" "8,9,11,20,21,24,25")
3384 /* xorps is one byte shorter for non-AVX targets. */
3385 (eq_attr "alternative" "12,16")
3386 (cond [(not (match_test "TARGET_SSE2"))
3387 (const_string "V4SF")
3388 (match_test "TARGET_AVX512F")
3390 (match_test "TARGET_AVX")
3391 (const_string "V2DF")
3392 (match_test "optimize_function_for_size_p (cfun)")
3393 (const_string "V4SF")
3394 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3397 (const_string "V2DF"))
3399 /* For architectures resolving dependencies on
3400 whole SSE registers use movapd to break dependency
3401 chains, otherwise use short move to avoid extra work. */
3403 /* movaps is one byte shorter for non-AVX targets. */
3404 (eq_attr "alternative" "13,17")
3405 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3406 (match_operand 1 "ext_sse_reg_operand"))
3407 (const_string "V8DF")
3408 (ior (not (match_test "TARGET_SSE2"))
3409 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3410 (const_string "V4SF")
3411 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3412 (const_string "V2DF")
3413 (match_test "TARGET_AVX")
3415 (match_test "optimize_function_for_size_p (cfun)")
3416 (const_string "V4SF")
3418 (const_string "DF"))
3420 /* For architectures resolving dependencies on register
3421 parts we may avoid extra work to zero out upper part
3423 (eq_attr "alternative" "14,18")
3424 (cond [(not (match_test "TARGET_SSE2"))
3425 (const_string "V2SF")
3426 (match_test "TARGET_AVX")
3428 (match_test "TARGET_SSE_SPLIT_REGS")
3429 (const_string "V1DF")
3431 (const_string "DF"))
3433 (and (eq_attr "alternative" "15,19")
3434 (not (match_test "TARGET_SSE2")))
3435 (const_string "V2SF")
3437 (const_string "DF")))
3438 (set (attr "preferred_for_size")
3439 (cond [(eq_attr "alternative" "3,4")
3440 (symbol_ref "false")]
3441 (symbol_ref "true")))
3442 (set (attr "preferred_for_speed")
3443 (cond [(eq_attr "alternative" "3,4")
3444 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3445 (symbol_ref "true")))
3446 (set (attr "enabled")
3447 (cond [(eq_attr "alternative" "22,23,24,25")
3449 (match_test "TARGET_HARD_DF_REGS")
3450 (symbol_ref "false")
3452 (not (match_test "TARGET_HARD_DF_REGS"))
3453 (symbol_ref "false")
3455 (const_string "*")))])
3458 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
3459 (match_operand:DF 1 "general_gr_operand"))]
3460 "!TARGET_64BIT && reload_completed"
3462 "ix86_split_long_move (operands); DONE;")
3464 (define_insn "*movsf_internal"
3465 [(set (match_operand:SF 0 "nonimmediate_operand"
3466 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym,r ,m")
3467 (match_operand:SF 1 "general_operand"
3468 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r ,rmF,rF"))]
3469 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3470 && (lra_in_progress || reload_completed
3471 || !CONST_DOUBLE_P (operands[1])
3472 || ((optimize_function_for_size_p (cfun)
3473 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3474 && ((IS_STACK_MODE (SFmode)
3475 && standard_80387_constant_p (operands[1]) > 0)
3476 || (TARGET_SSE && TARGET_SSE_MATH
3477 && standard_sse_constant_p (operands[1], SFmode) == 1)))
3478 || memory_operand (operands[0], SFmode)
3479 || !TARGET_HARD_SF_REGS)"
3481 switch (get_attr_type (insn))
3484 if (which_alternative == 2)
3485 return standard_80387_constant_opcode (operands[1]);
3486 return output_387_reg_move (insn, operands);
3489 return "mov{l}\t{%1, %0|%0, %1}";
3492 return standard_sse_constant_opcode (insn, operands[1]);
3495 switch (get_attr_mode (insn))
3498 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3499 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3500 return "%vmovss\t{%1, %0|%0, %1}";
3503 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3505 return "%vmovaps\t{%1, %0|%0, %1}";
3508 return "%vmovd\t{%1, %0|%0, %1}";
3515 switch (get_attr_mode (insn))
3518 return "movq\t{%1, %0|%0, %1}";
3520 return "movd\t{%1, %0|%0, %1}";
3531 (cond [(eq_attr "alternative" "0,1,2")
3532 (const_string "fmov")
3533 (eq_attr "alternative" "3,4,16,17")
3534 (const_string "imov")
3535 (eq_attr "alternative" "5")
3536 (const_string "sselog1")
3537 (eq_attr "alternative" "11,12,13,14,15")
3538 (const_string "mmxmov")
3540 (const_string "ssemov")))
3541 (set (attr "prefix")
3542 (if_then_else (eq_attr "type" "sselog1,ssemov")
3543 (const_string "maybe_vex")
3544 (const_string "orig")))
3545 (set (attr "prefix_data16")
3546 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3548 (const_string "*")))
3550 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3552 (eq_attr "alternative" "11")
3554 (eq_attr "alternative" "5")
3555 (cond [(not (match_test "TARGET_SSE2"))
3556 (const_string "V4SF")
3557 (match_test "TARGET_AVX512F")
3558 (const_string "V16SF")
3559 (match_test "TARGET_AVX")
3560 (const_string "V4SF")
3561 (match_test "optimize_function_for_size_p (cfun)")
3562 (const_string "V4SF")
3563 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3566 (const_string "V4SF"))
3568 /* For architectures resolving dependencies on
3569 whole SSE registers use APS move to break dependency
3570 chains, otherwise use short move to avoid extra work.
3572 Do the same for architectures resolving dependencies on
3573 the parts. While in DF mode it is better to always handle
3574 just register parts, the SF mode is different due to lack
3575 of instructions to load just part of the register. It is
3576 better to maintain the whole registers in single format
3577 to avoid problems on using packed logical operations. */
3578 (eq_attr "alternative" "6")
3579 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3580 (match_operand 1 "ext_sse_reg_operand"))
3581 (const_string "V16SF")
3582 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3583 (match_test "TARGET_SSE_SPLIT_REGS"))
3584 (const_string "V4SF")
3586 (const_string "SF"))
3588 (const_string "SF")))
3589 (set (attr "enabled")
3590 (cond [(eq_attr "alternative" "16,17")
3592 (match_test "TARGET_HARD_SF_REGS")
3593 (symbol_ref "false")
3595 (not (match_test "TARGET_HARD_SF_REGS"))
3596 (symbol_ref "false")
3598 (const_string "*")))])
3601 [(set (match_operand 0 "any_fp_register_operand")
3602 (match_operand 1 "memory_operand"))]
3604 && (GET_MODE (operands[0]) == TFmode
3605 || GET_MODE (operands[0]) == XFmode
3606 || GET_MODE (operands[0]) == DFmode
3607 || GET_MODE (operands[0]) == SFmode)
3608 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3609 [(set (match_dup 0) (match_dup 2))]
3610 "operands[2] = find_constant_src (curr_insn);")
3613 [(set (match_operand 0 "any_fp_register_operand")
3614 (float_extend (match_operand 1 "memory_operand")))]
3616 && (GET_MODE (operands[0]) == TFmode
3617 || GET_MODE (operands[0]) == XFmode
3618 || GET_MODE (operands[0]) == DFmode)
3619 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3620 [(set (match_dup 0) (match_dup 2))]
3621 "operands[2] = find_constant_src (curr_insn);")
3623 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3625 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3626 (match_operand:X87MODEF 1 "immediate_operand"))]
3628 && (standard_80387_constant_p (operands[1]) == 8
3629 || standard_80387_constant_p (operands[1]) == 9)"
3630 [(set (match_dup 0)(match_dup 1))
3632 (neg:X87MODEF (match_dup 0)))]
3634 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3635 operands[1] = CONST0_RTX (<MODE>mode);
3637 operands[1] = CONST1_RTX (<MODE>mode);
3640 (define_insn "swapxf"
3641 [(set (match_operand:XF 0 "register_operand" "+f")
3642 (match_operand:XF 1 "register_operand" "+f"))
3647 if (STACK_TOP_P (operands[0]))
3652 [(set_attr "type" "fxch")
3653 (set_attr "mode" "XF")])
3655 (define_insn "*swap<mode>"
3656 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3657 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3660 "TARGET_80387 || reload_completed"
3662 if (STACK_TOP_P (operands[0]))
3667 [(set_attr "type" "fxch")
3668 (set_attr "mode" "<MODE>")])
3670 ;; Zero extension instructions
3672 (define_expand "zero_extendsidi2"
3673 [(set (match_operand:DI 0 "nonimmediate_operand")
3674 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3676 (define_insn "*zero_extendsidi2"
3677 [(set (match_operand:DI 0 "nonimmediate_operand"
3678 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x,*r")
3680 (match_operand:SI 1 "x86_64_zext_operand"
3681 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m ,*k")))]
3684 switch (get_attr_type (insn))
3687 if (ix86_use_lea_for_mov (insn, operands))
3688 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3690 return "mov{l}\t{%1, %k0|%k0, %1}";
3696 return "movd\t{%1, %0|%0, %1}";
3699 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3702 if (GENERAL_REG_P (operands[0]))
3703 return "%vmovd\t{%1, %k0|%k0, %1}";
3705 return "%vmovd\t{%1, %0|%0, %1}";
3708 return "kmovd\t{%1, %k0|%k0, %1}";
3715 (cond [(eq_attr "alternative" "0,1,2")
3716 (const_string "nox64")
3717 (eq_attr "alternative" "3,7")
3718 (const_string "x64")
3719 (eq_attr "alternative" "8")
3720 (const_string "x64_sse4")
3721 (eq_attr "alternative" "10")
3722 (const_string "sse2")
3723 (eq_attr "alternative" "11")
3724 (const_string "x64_avx512bw")
3726 (const_string "*")))
3728 (cond [(eq_attr "alternative" "0,1,2,4")
3729 (const_string "multi")
3730 (eq_attr "alternative" "5,6")
3731 (const_string "mmxmov")
3732 (eq_attr "alternative" "7,9,10")
3733 (const_string "ssemov")
3734 (eq_attr "alternative" "8")
3735 (const_string "sselog1")
3736 (eq_attr "alternative" "11")
3737 (const_string "mskmov")
3739 (const_string "imovx")))
3740 (set (attr "prefix_extra")
3741 (if_then_else (eq_attr "alternative" "8")
3743 (const_string "*")))
3744 (set (attr "length_immediate")
3745 (if_then_else (eq_attr "alternative" "8")
3747 (const_string "*")))
3748 (set (attr "prefix")
3749 (if_then_else (eq_attr "type" "ssemov,sselog1")
3750 (const_string "maybe_vex")
3751 (const_string "orig")))
3752 (set (attr "prefix_0f")
3753 (if_then_else (eq_attr "type" "imovx")
3755 (const_string "*")))
3757 (cond [(eq_attr "alternative" "5,6")
3759 (eq_attr "alternative" "7,8,9")
3762 (const_string "SI")))])
3765 [(set (match_operand:DI 0 "memory_operand")
3766 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3768 [(set (match_dup 4) (const_int 0))]
3769 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3772 [(set (match_operand:DI 0 "general_reg_operand")
3773 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
3774 "!TARGET_64BIT && reload_completed
3775 && REGNO (operands[0]) == REGNO (operands[1])"
3776 [(set (match_dup 4) (const_int 0))]
3777 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3780 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
3781 (zero_extend:DI (match_operand:SI 1 "nonimmediate_gr_operand")))]
3782 "!TARGET_64BIT && reload_completed
3783 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3784 [(set (match_dup 3) (match_dup 1))
3785 (set (match_dup 4) (const_int 0))]
3786 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3788 (define_mode_attr kmov_isa
3789 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
3791 (define_insn "zero_extend<mode>di2"
3792 [(set (match_operand:DI 0 "register_operand" "=r,*r")
3794 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
3797 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
3798 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
3799 [(set_attr "isa" "*,<kmov_isa>")
3800 (set_attr "type" "imovx,mskmov")
3801 (set_attr "mode" "SI,<MODE>")])
3803 (define_expand "zero_extend<mode>si2"
3804 [(set (match_operand:SI 0 "register_operand")
3805 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3808 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3810 operands[1] = force_reg (<MODE>mode, operands[1]);
3811 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3816 (define_insn_and_split "zero_extend<mode>si2_and"
3817 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3819 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3820 (clobber (reg:CC FLAGS_REG))]
3821 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3823 "&& reload_completed"
3824 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3825 (clobber (reg:CC FLAGS_REG))])]
3827 if (!REG_P (operands[1])
3828 || REGNO (operands[0]) != REGNO (operands[1]))
3830 ix86_expand_clear (operands[0]);
3832 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3833 emit_insn (gen_movstrict<mode>
3834 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3838 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3840 [(set_attr "type" "alu1")
3841 (set_attr "mode" "SI")])
3843 (define_insn "*zero_extend<mode>si2"
3844 [(set (match_operand:SI 0 "register_operand" "=r,*r")
3846 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
3847 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3849 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
3850 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
3851 [(set_attr "isa" "*,<kmov_isa>")
3852 (set_attr "type" "imovx,mskmov")
3853 (set_attr "mode" "SI,<MODE>")])
3855 (define_expand "zero_extendqihi2"
3856 [(set (match_operand:HI 0 "register_operand")
3857 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3860 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3862 operands[1] = force_reg (QImode, operands[1]);
3863 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3868 (define_insn_and_split "zero_extendqihi2_and"
3869 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3870 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3871 (clobber (reg:CC FLAGS_REG))]
3872 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3874 "&& reload_completed"
3875 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3876 (clobber (reg:CC FLAGS_REG))])]
3878 if (!REG_P (operands[1])
3879 || REGNO (operands[0]) != REGNO (operands[1]))
3881 ix86_expand_clear (operands[0]);
3883 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3884 emit_insn (gen_movstrictqi
3885 (gen_lowpart (QImode, operands[0]), operands[1]));
3889 operands[0] = gen_lowpart (SImode, operands[0]);
3891 [(set_attr "type" "alu1")
3892 (set_attr "mode" "SI")])
3894 ; zero extend to SImode to avoid partial register stalls
3895 (define_insn "*zero_extendqihi2"
3896 [(set (match_operand:HI 0 "register_operand" "=r,*r")
3897 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k")))]
3898 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3900 movz{bl|x}\t{%1, %k0|%k0, %1}
3901 kmovb\t{%1, %k0|%k0, %1}"
3902 [(set_attr "isa" "*,avx512dq")
3903 (set_attr "type" "imovx,mskmov")
3904 (set_attr "mode" "SI,QI")])
3906 (define_insn_and_split "*zext<mode>_doubleword_and"
3907 [(set (match_operand:DI 0 "register_operand" "=&<r>")
3908 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3909 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
3910 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3912 "&& reload_completed && GENERAL_REG_P (operands[0])"
3913 [(set (match_dup 2) (const_int 0))]
3915 split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);
3917 emit_move_insn (operands[0], const0_rtx);
3919 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3920 emit_insn (gen_movstrict<mode>
3921 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3924 (define_insn_and_split "*zext<mode>_doubleword"
3925 [(set (match_operand:DI 0 "register_operand" "=r")
3926 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3927 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
3928 && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3930 "&& reload_completed && GENERAL_REG_P (operands[0])"
3931 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
3932 (set (match_dup 2) (const_int 0))]
3933 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
3935 (define_insn_and_split "*zextsi_doubleword"
3936 [(set (match_operand:DI 0 "register_operand" "=r")
3937 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3938 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
3940 "&& reload_completed && GENERAL_REG_P (operands[0])"
3941 [(set (match_dup 0) (match_dup 1))
3942 (set (match_dup 2) (const_int 0))]
3943 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
3945 ;; Sign extension instructions
3947 (define_expand "extendsidi2"
3948 [(set (match_operand:DI 0 "register_operand")
3949 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3954 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3959 (define_insn "*extendsidi2_rex64"
3960 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3961 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3965 movs{lq|x}\t{%1, %0|%0, %1}"
3966 [(set_attr "type" "imovx")
3967 (set_attr "mode" "DI")
3968 (set_attr "prefix_0f" "0")
3969 (set_attr "modrm" "0,1")])
3971 (define_insn "extendsidi2_1"
3972 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3973 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3974 (clobber (reg:CC FLAGS_REG))
3975 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3979 ;; Split the memory case. If the source register doesn't die, it will stay
3980 ;; this way, if it does die, following peephole2s take care of it.
3982 [(set (match_operand:DI 0 "memory_operand")
3983 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3984 (clobber (reg:CC FLAGS_REG))
3985 (clobber (match_operand:SI 2 "register_operand"))]
3989 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3991 emit_move_insn (operands[3], operands[1]);
3993 /* Generate a cltd if possible and doing so it profitable. */
3994 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3995 && REGNO (operands[1]) == AX_REG
3996 && REGNO (operands[2]) == DX_REG)
3998 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4002 emit_move_insn (operands[2], operands[1]);
4003 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4005 emit_move_insn (operands[4], operands[2]);
4009 ;; Peepholes for the case where the source register does die, after
4010 ;; being split with the above splitter.
4012 [(set (match_operand:SI 0 "memory_operand")
4013 (match_operand:SI 1 "general_reg_operand"))
4014 (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4015 (parallel [(set (match_dup 2)
4016 (ashiftrt:SI (match_dup 2) (const_int 31)))
4017 (clobber (reg:CC FLAGS_REG))])
4018 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4019 "REGNO (operands[1]) != REGNO (operands[2])
4020 && peep2_reg_dead_p (2, operands[1])
4021 && peep2_reg_dead_p (4, operands[2])
4022 && !reg_mentioned_p (operands[2], operands[3])"
4023 [(set (match_dup 0) (match_dup 1))
4024 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4025 (clobber (reg:CC FLAGS_REG))])
4026 (set (match_dup 3) (match_dup 1))])
4029 [(set (match_operand:SI 0 "memory_operand")
4030 (match_operand:SI 1 "general_reg_operand"))
4031 (parallel [(set (match_operand:SI 2 "general_reg_operand")
4032 (ashiftrt:SI (match_dup 1) (const_int 31)))
4033 (clobber (reg:CC FLAGS_REG))])
4034 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4035 "/* cltd is shorter than sarl $31, %eax */
4036 !optimize_function_for_size_p (cfun)
4037 && REGNO (operands[1]) == AX_REG
4038 && REGNO (operands[2]) == DX_REG
4039 && peep2_reg_dead_p (2, operands[1])
4040 && peep2_reg_dead_p (3, operands[2])
4041 && !reg_mentioned_p (operands[2], operands[3])"
4042 [(set (match_dup 0) (match_dup 1))
4043 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4044 (clobber (reg:CC FLAGS_REG))])
4045 (set (match_dup 3) (match_dup 1))])
4047 ;; Extend to register case. Optimize case where source and destination
4048 ;; registers match and cases where we can use cltd.
4050 [(set (match_operand:DI 0 "register_operand")
4051 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4052 (clobber (reg:CC FLAGS_REG))
4053 (clobber (match_scratch:SI 2))]
4057 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4059 if (REGNO (operands[3]) != REGNO (operands[1]))
4060 emit_move_insn (operands[3], operands[1]);
4062 /* Generate a cltd if possible and doing so it profitable. */
4063 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4064 && REGNO (operands[3]) == AX_REG
4065 && REGNO (operands[4]) == DX_REG)
4067 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4071 if (REGNO (operands[4]) != REGNO (operands[1]))
4072 emit_move_insn (operands[4], operands[1]);
4074 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4078 (define_insn "extend<mode>di2"
4079 [(set (match_operand:DI 0 "register_operand" "=r")
4081 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4083 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4084 [(set_attr "type" "imovx")
4085 (set_attr "mode" "DI")])
4087 (define_insn "extendhisi2"
4088 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4089 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4092 switch (get_attr_prefix_0f (insn))
4095 return "{cwtl|cwde}";
4097 return "movs{wl|x}\t{%1, %0|%0, %1}";
4100 [(set_attr "type" "imovx")
4101 (set_attr "mode" "SI")
4102 (set (attr "prefix_0f")
4103 ;; movsx is short decodable while cwtl is vector decoded.
4104 (if_then_else (and (eq_attr "cpu" "!k6")
4105 (eq_attr "alternative" "0"))
4107 (const_string "1")))
4108 (set (attr "znver1_decode")
4109 (if_then_else (eq_attr "prefix_0f" "0")
4110 (const_string "double")
4111 (const_string "direct")))
4113 (if_then_else (eq_attr "prefix_0f" "0")
4115 (const_string "1")))])
4117 (define_insn "*extendhisi2_zext"
4118 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4121 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4124 switch (get_attr_prefix_0f (insn))
4127 return "{cwtl|cwde}";
4129 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4132 [(set_attr "type" "imovx")
4133 (set_attr "mode" "SI")
4134 (set (attr "prefix_0f")
4135 ;; movsx is short decodable while cwtl is vector decoded.
4136 (if_then_else (and (eq_attr "cpu" "!k6")
4137 (eq_attr "alternative" "0"))
4139 (const_string "1")))
4141 (if_then_else (eq_attr "prefix_0f" "0")
4143 (const_string "1")))])
4145 (define_insn "extendqisi2"
4146 [(set (match_operand:SI 0 "register_operand" "=r")
4147 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4149 "movs{bl|x}\t{%1, %0|%0, %1}"
4150 [(set_attr "type" "imovx")
4151 (set_attr "mode" "SI")])
4153 (define_insn "*extendqisi2_zext"
4154 [(set (match_operand:DI 0 "register_operand" "=r")
4156 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4158 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4159 [(set_attr "type" "imovx")
4160 (set_attr "mode" "SI")])
4162 (define_insn "extendqihi2"
4163 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4164 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4167 switch (get_attr_prefix_0f (insn))
4170 return "{cbtw|cbw}";
4172 return "movs{bw|x}\t{%1, %0|%0, %1}";
4175 [(set_attr "type" "imovx")
4176 (set_attr "mode" "HI")
4177 (set (attr "prefix_0f")
4178 ;; movsx is short decodable while cwtl is vector decoded.
4179 (if_then_else (and (eq_attr "cpu" "!k6")
4180 (eq_attr "alternative" "0"))
4182 (const_string "1")))
4184 (if_then_else (eq_attr "prefix_0f" "0")
4186 (const_string "1")))])
4188 ;; Conversions between float and double.
4190 ;; These are all no-ops in the model used for the 80387.
4191 ;; So just emit moves.
4193 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4195 [(set (match_operand:DF 0 "push_operand")
4196 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4198 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4199 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4202 [(set (match_operand:XF 0 "push_operand")
4203 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4205 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4206 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4207 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4209 (define_expand "extendsfdf2"
4210 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4211 (float_extend:DF (match_operand:SF 1 "general_operand")))]
4212 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4214 /* ??? Needed for compress_float_constant since all fp constants
4215 are TARGET_LEGITIMATE_CONSTANT_P. */
4216 if (CONST_DOUBLE_P (operands[1]))
4218 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4219 && standard_80387_constant_p (operands[1]) > 0)
4221 operands[1] = simplify_const_unary_operation
4222 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4223 emit_move_insn_1 (operands[0], operands[1]);
4226 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4230 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4232 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4234 We do the conversion post reload to avoid producing of 128bit spills
4235 that might lead to ICE on 32bit target. The sequence unlikely combine
4238 [(set (match_operand:DF 0 "sse_reg_operand")
4240 (match_operand:SF 1 "nonimmediate_operand")))]
4241 "TARGET_USE_VECTOR_FP_CONVERTS
4242 && optimize_insn_for_speed_p ()
4244 && (!EXT_REX_SSE_REG_P (operands[0])
4245 || TARGET_AVX512VL)"
4250 (parallel [(const_int 0) (const_int 1)]))))]
4252 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4253 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4254 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4255 Try to avoid move when unpacking can be done in source. */
4256 if (REG_P (operands[1]))
4258 /* If it is unsafe to overwrite upper half of source, we need
4259 to move to destination and unpack there. */
4260 if (REGNO (operands[0]) != REGNO (operands[1])
4261 || (EXT_REX_SSE_REG_P (operands[1])
4262 && !TARGET_AVX512VL))
4264 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4265 emit_move_insn (tmp, operands[1]);
4268 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4269 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4270 =v, v, then vbroadcastss will be only needed for AVX512F without
4272 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4273 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4277 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4278 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4282 emit_insn (gen_vec_setv4sf_0 (operands[3],
4283 CONST0_RTX (V4SFmode), operands[1]));
4286 ;; It's more profitable to split and then extend in the same register.
4288 [(set (match_operand:DF 0 "sse_reg_operand")
4290 (match_operand:SF 1 "memory_operand")))]
4291 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4292 && optimize_insn_for_speed_p ()"
4293 [(set (match_dup 2) (match_dup 1))
4294 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4295 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4297 (define_insn "*extendsfdf2"
4298 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v")
4300 (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4301 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4303 switch (which_alternative)
4307 return output_387_reg_move (insn, operands);
4310 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4316 [(set_attr "type" "fmov,fmov,ssecvt")
4317 (set_attr "prefix" "orig,orig,maybe_vex")
4318 (set_attr "mode" "SF,XF,DF")
4319 (set (attr "enabled")
4321 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4323 (eq_attr "alternative" "0,1")
4324 (symbol_ref "TARGET_MIX_SSE_I387")
4325 (symbol_ref "true"))
4327 (eq_attr "alternative" "0,1")
4329 (symbol_ref "false"))))])
4331 (define_expand "extend<mode>xf2"
4332 [(set (match_operand:XF 0 "nonimmediate_operand")
4333 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4336 /* ??? Needed for compress_float_constant since all fp constants
4337 are TARGET_LEGITIMATE_CONSTANT_P. */
4338 if (CONST_DOUBLE_P (operands[1]))
4340 if (standard_80387_constant_p (operands[1]) > 0)
4342 operands[1] = simplify_const_unary_operation
4343 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4344 emit_move_insn_1 (operands[0], operands[1]);
4347 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4351 (define_insn "*extend<mode>xf2_i387"
4352 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4354 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4356 "* return output_387_reg_move (insn, operands);"
4357 [(set_attr "type" "fmov")
4358 (set_attr "mode" "<MODE>,XF")])
4360 ;; %%% This seems like bad news.
4361 ;; This cannot output into an f-reg because there is no way to be sure
4362 ;; of truncating in that case. Otherwise this is just like a simple move
4363 ;; insn. So we pretend we can output to a reg in order to get better
4364 ;; register preferencing, but we really use a stack slot.
4366 ;; Conversion from DFmode to SFmode.
4368 (define_expand "truncdfsf2"
4369 [(set (match_operand:SF 0 "nonimmediate_operand")
4371 (match_operand:DF 1 "nonimmediate_operand")))]
4372 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4374 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4376 else if (flag_unsafe_math_optimizations)
4380 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4381 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4386 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4388 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4390 We do the conversion post reload to avoid producing of 128bit spills
4391 that might lead to ICE on 32bit target. The sequence unlikely combine
4394 [(set (match_operand:SF 0 "sse_reg_operand")
4396 (match_operand:DF 1 "nonimmediate_operand")))]
4397 "TARGET_USE_VECTOR_FP_CONVERTS
4398 && optimize_insn_for_speed_p ()
4400 && (!EXT_REX_SSE_REG_P (operands[0])
4401 || TARGET_AVX512VL)"
4404 (float_truncate:V2SF
4408 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4409 operands[3] = CONST0_RTX (V2SFmode);
4410 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4411 /* Use movsd for loading from memory, unpcklpd for registers.
4412 Try to avoid move when unpacking can be done in source, or SSE3
4413 movddup is available. */
4414 if (REG_P (operands[1]))
4417 && REGNO (operands[0]) != REGNO (operands[1]))
4419 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4420 emit_move_insn (tmp, operands[1]);
4423 else if (!TARGET_SSE3)
4424 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4425 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4428 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4429 CONST0_RTX (DFmode)));
4432 ;; It's more profitable to split and then extend in the same register.
4434 [(set (match_operand:SF 0 "sse_reg_operand")
4436 (match_operand:DF 1 "memory_operand")))]
4437 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4438 && optimize_insn_for_speed_p ()"
4439 [(set (match_dup 2) (match_dup 1))
4440 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4441 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4443 (define_expand "truncdfsf2_with_temp"
4444 [(parallel [(set (match_operand:SF 0)
4445 (float_truncate:SF (match_operand:DF 1)))
4446 (clobber (match_operand:SF 2))])])
4448 ;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
4449 ;; because nothing we do there is unsafe.
4450 (define_insn "*truncdfsf_fast_mixed"
4451 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,v")
4453 (match_operand:DF 1 "nonimmediate_operand" "f ,vm")))]
4454 "TARGET_SSE2 && TARGET_SSE_MATH"
4456 switch (which_alternative)
4459 return output_387_reg_move (insn, operands);
4461 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4466 [(set_attr "type" "fmov,ssecvt")
4467 (set_attr "prefix" "orig,maybe_vex")
4468 (set_attr "mode" "SF")
4469 (set (attr "enabled")
4470 (cond [(eq_attr "alternative" "0")
4471 (symbol_ref "TARGET_MIX_SSE_I387
4472 && flag_unsafe_math_optimizations")
4474 (symbol_ref "true")))])
4476 (define_insn "*truncdfsf_fast_i387"
4477 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4479 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4480 "TARGET_80387 && flag_unsafe_math_optimizations"
4481 "* return output_387_reg_move (insn, operands);"
4482 [(set_attr "type" "fmov")
4483 (set_attr "mode" "SF")])
4485 (define_insn "*truncdfsf_mixed"
4486 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,v ,?f,?v,?*r")
4488 (match_operand:DF 1 "nonimmediate_operand" "f ,vm,f ,f ,f")))
4489 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4490 "TARGET_MIX_SSE_I387"
4492 switch (which_alternative)
4495 return output_387_reg_move (insn, operands);
4497 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4503 [(set_attr "isa" "*,sse2,*,*,*")
4504 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4505 (set_attr "unit" "*,*,i387,i387,i387")
4506 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4507 (set_attr "mode" "SF")])
4509 (define_insn "*truncdfsf_i387"
4510 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4512 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4513 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4516 switch (which_alternative)
4519 return output_387_reg_move (insn, operands);
4525 [(set_attr "type" "fmov,multi,multi,multi")
4526 (set_attr "unit" "*,i387,i387,i387")
4527 (set_attr "mode" "SF")])
4529 (define_insn "*truncdfsf2_i387_1"
4530 [(set (match_operand:SF 0 "memory_operand" "=m")
4532 (match_operand:DF 1 "register_operand" "f")))]
4534 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4535 && !TARGET_MIX_SSE_I387"
4536 "* return output_387_reg_move (insn, operands);"
4537 [(set_attr "type" "fmov")
4538 (set_attr "mode" "SF")])
4541 [(set (match_operand:SF 0 "register_operand")
4543 (match_operand:DF 1 "fp_register_operand")))
4544 (clobber (match_operand 2))]
4546 [(set (match_dup 2) (match_dup 1))
4547 (set (match_dup 0) (match_dup 2))]
4548 "operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));")
4550 ;; Conversion from XFmode to {SF,DF}mode
4552 (define_expand "truncxf<mode>2"
4553 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4554 (float_truncate:MODEF
4555 (match_operand:XF 1 "register_operand")))
4556 (clobber (match_dup 2))])]
4559 if (flag_unsafe_math_optimizations)
4561 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4562 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4563 if (reg != operands[0])
4564 emit_move_insn (operands[0], reg);
4568 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4571 (define_insn "*truncxfsf2_mixed"
4572 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4574 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4575 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4578 gcc_assert (!which_alternative);
4579 return output_387_reg_move (insn, operands);
4581 [(set_attr "type" "fmov,multi,multi,multi")
4582 (set_attr "unit" "*,i387,i387,i387")
4583 (set_attr "mode" "SF")])
4585 (define_insn "*truncxfdf2_mixed"
4586 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4588 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4589 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4592 gcc_assert (!which_alternative);
4593 return output_387_reg_move (insn, operands);
4595 [(set_attr "isa" "*,*,sse2,*")
4596 (set_attr "type" "fmov,multi,multi,multi")
4597 (set_attr "unit" "*,i387,i387,i387")
4598 (set_attr "mode" "DF")])
4600 (define_insn "truncxf<mode>2_i387_noop"
4601 [(set (match_operand:MODEF 0 "register_operand" "=f")
4602 (float_truncate:MODEF
4603 (match_operand:XF 1 "register_operand" "f")))]
4604 "TARGET_80387 && flag_unsafe_math_optimizations"
4605 "* return output_387_reg_move (insn, operands);"
4606 [(set_attr "type" "fmov")
4607 (set_attr "mode" "<MODE>")])
4609 (define_insn "*truncxf<mode>2_i387"
4610 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4611 (float_truncate:MODEF
4612 (match_operand:XF 1 "register_operand" "f")))]
4614 "* return output_387_reg_move (insn, operands);"
4615 [(set_attr "type" "fmov")
4616 (set_attr "mode" "<MODE>")])
4619 [(set (match_operand:MODEF 0 "register_operand")
4620 (float_truncate:MODEF
4621 (match_operand:XF 1 "register_operand")))
4622 (clobber (match_operand:MODEF 2 "memory_operand"))]
4623 "TARGET_80387 && reload_completed"
4624 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4625 (set (match_dup 0) (match_dup 2))])
4628 [(set (match_operand:MODEF 0 "memory_operand")
4629 (float_truncate:MODEF
4630 (match_operand:XF 1 "register_operand")))
4631 (clobber (match_operand:MODEF 2 "memory_operand"))]
4633 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4635 ;; Signed conversion to DImode.
4637 (define_expand "fix_truncxfdi2"
4638 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4639 (fix:DI (match_operand:XF 1 "register_operand")))
4640 (clobber (reg:CC FLAGS_REG))])]
4645 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4650 (define_expand "fix_trunc<mode>di2"
4651 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4652 (fix:DI (match_operand:MODEF 1 "register_operand")))
4653 (clobber (reg:CC FLAGS_REG))])]
4654 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4657 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4659 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4662 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4664 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4665 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4666 if (out != operands[0])
4667 emit_move_insn (operands[0], out);
4672 ;; Signed conversion to SImode.
4674 (define_expand "fix_truncxfsi2"
4675 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4676 (fix:SI (match_operand:XF 1 "register_operand")))
4677 (clobber (reg:CC FLAGS_REG))])]
4682 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4687 (define_expand "fix_trunc<mode>si2"
4688 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4689 (fix:SI (match_operand:MODEF 1 "register_operand")))
4690 (clobber (reg:CC FLAGS_REG))])]
4691 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4694 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4696 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4699 if (SSE_FLOAT_MODE_P (<MODE>mode))
4701 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4702 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4703 if (out != operands[0])
4704 emit_move_insn (operands[0], out);
4709 ;; Signed conversion to HImode.
4711 (define_expand "fix_trunc<mode>hi2"
4712 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4713 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4714 (clobber (reg:CC FLAGS_REG))])]
4716 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4720 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4725 ;; Unsigned conversion to SImode.
4727 (define_expand "fixuns_trunc<mode>si2"
4729 [(set (match_operand:SI 0 "register_operand")
4731 (match_operand:MODEF 1 "nonimmediate_operand")))
4733 (clobber (match_scratch:<ssevecmode> 3))
4734 (clobber (match_scratch:<ssevecmode> 4))])]
4735 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4737 machine_mode mode = <MODE>mode;
4738 machine_mode vecmode = <ssevecmode>mode;
4739 REAL_VALUE_TYPE TWO31r;
4742 if (optimize_insn_for_size_p ())
4745 real_ldexp (&TWO31r, &dconst1, 31);
4746 two31 = const_double_from_real_value (TWO31r, mode);
4747 two31 = ix86_build_const_vector (vecmode, true, two31);
4748 operands[2] = force_reg (vecmode, two31);
4751 (define_insn_and_split "*fixuns_trunc<mode>_1"
4752 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4754 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4755 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4756 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4757 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4758 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4759 && optimize_function_for_speed_p (cfun)"
4761 "&& reload_completed"
4764 ix86_split_convert_uns_si_sse (operands);
4768 ;; Unsigned conversion to HImode.
4769 ;; Without these patterns, we'll try the unsigned SI conversion which
4770 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4772 (define_expand "fixuns_trunc<mode>hi2"
4774 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4775 (set (match_operand:HI 0 "nonimmediate_operand")
4776 (subreg:HI (match_dup 2) 0))]
4777 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4778 "operands[2] = gen_reg_rtx (SImode);")
4780 ;; When SSE is available, it is always faster to use it!
4781 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4782 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4783 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
4784 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4785 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4786 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4787 [(set_attr "type" "sseicvt")
4788 (set_attr "prefix" "maybe_vex")
4789 (set (attr "prefix_rex")
4791 (match_test "<SWI48:MODE>mode == DImode")
4793 (const_string "*")))
4794 (set_attr "mode" "<MODEF:MODE>")
4795 (set_attr "athlon_decode" "double,vector")
4796 (set_attr "amdfam10_decode" "double,double")
4797 (set_attr "bdver1_decode" "double,double")])
4799 ;; Avoid vector decoded forms of the instruction.
4801 [(match_scratch:MODEF 2 "x")
4802 (set (match_operand:SWI48 0 "register_operand")
4803 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4804 "TARGET_AVOID_VECTOR_DECODE
4805 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4806 && optimize_insn_for_speed_p ()"
4807 [(set (match_dup 2) (match_dup 1))
4808 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4810 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4811 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4812 (fix:SWI248x (match_operand 1 "register_operand")))]
4813 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4815 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4816 && (TARGET_64BIT || <MODE>mode != DImode))
4818 && can_create_pseudo_p ()"
4823 if (memory_operand (operands[0], VOIDmode))
4824 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4827 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4828 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4834 [(set_attr "type" "fisttp")
4835 (set_attr "mode" "<MODE>")])
4837 (define_insn "fix_trunc<mode>_i387_fisttp"
4838 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4839 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4840 (clobber (match_scratch:XF 2 "=&1f"))]
4841 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4843 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4844 && (TARGET_64BIT || <MODE>mode != DImode))
4845 && TARGET_SSE_MATH)"
4846 "* return output_fix_trunc (insn, operands, true);"
4847 [(set_attr "type" "fisttp")
4848 (set_attr "mode" "<MODE>")])
4850 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4851 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4852 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4853 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4854 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4855 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4857 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4858 && (TARGET_64BIT || <MODE>mode != DImode))
4859 && TARGET_SSE_MATH)"
4861 [(set_attr "type" "fisttp")
4862 (set_attr "mode" "<MODE>")])
4865 [(set (match_operand:SWI248x 0 "register_operand")
4866 (fix:SWI248x (match_operand 1 "register_operand")))
4867 (clobber (match_operand:SWI248x 2 "memory_operand"))
4868 (clobber (match_scratch 3))]
4870 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4871 (clobber (match_dup 3))])
4872 (set (match_dup 0) (match_dup 2))])
4875 [(set (match_operand:SWI248x 0 "memory_operand")
4876 (fix:SWI248x (match_operand 1 "register_operand")))
4877 (clobber (match_operand:SWI248x 2 "memory_operand"))
4878 (clobber (match_scratch 3))]
4880 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4881 (clobber (match_dup 3))])])
4883 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4884 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4885 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4886 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4887 ;; function in i386.c.
4888 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4889 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4890 (fix:SWI248x (match_operand 1 "register_operand")))
4891 (clobber (reg:CC FLAGS_REG))]
4892 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4894 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4895 && (TARGET_64BIT || <MODE>mode != DImode))
4896 && can_create_pseudo_p ()"
4901 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4903 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4904 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4905 if (memory_operand (operands[0], VOIDmode))
4906 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4907 operands[2], operands[3]));
4910 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4911 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4912 operands[2], operands[3],
4917 [(set_attr "type" "fistp")
4918 (set_attr "i387_cw" "trunc")
4919 (set_attr "mode" "<MODE>")])
4921 (define_insn "fix_truncdi_i387"
4922 [(set (match_operand:DI 0 "memory_operand" "=m")
4923 (fix:DI (match_operand 1 "register_operand" "f")))
4924 (use (match_operand:HI 2 "memory_operand" "m"))
4925 (use (match_operand:HI 3 "memory_operand" "m"))
4926 (clobber (match_scratch:XF 4 "=&1f"))]
4927 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4929 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4930 "* return output_fix_trunc (insn, operands, false);"
4931 [(set_attr "type" "fistp")
4932 (set_attr "i387_cw" "trunc")
4933 (set_attr "mode" "DI")])
4935 (define_insn "fix_truncdi_i387_with_temp"
4936 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4937 (fix:DI (match_operand 1 "register_operand" "f,f")))
4938 (use (match_operand:HI 2 "memory_operand" "m,m"))
4939 (use (match_operand:HI 3 "memory_operand" "m,m"))
4940 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4941 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4942 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4944 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4946 [(set_attr "type" "fistp")
4947 (set_attr "i387_cw" "trunc")
4948 (set_attr "mode" "DI")])
4951 [(set (match_operand:DI 0 "register_operand")
4952 (fix:DI (match_operand 1 "register_operand")))
4953 (use (match_operand:HI 2 "memory_operand"))
4954 (use (match_operand:HI 3 "memory_operand"))
4955 (clobber (match_operand:DI 4 "memory_operand"))
4956 (clobber (match_scratch 5))]
4958 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4961 (clobber (match_dup 5))])
4962 (set (match_dup 0) (match_dup 4))])
4965 [(set (match_operand:DI 0 "memory_operand")
4966 (fix:DI (match_operand 1 "register_operand")))
4967 (use (match_operand:HI 2 "memory_operand"))
4968 (use (match_operand:HI 3 "memory_operand"))
4969 (clobber (match_operand:DI 4 "memory_operand"))
4970 (clobber (match_scratch 5))]
4972 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4975 (clobber (match_dup 5))])])
4977 (define_insn "fix_trunc<mode>_i387"
4978 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4979 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4980 (use (match_operand:HI 2 "memory_operand" "m"))
4981 (use (match_operand:HI 3 "memory_operand" "m"))]
4982 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4984 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4985 "* return output_fix_trunc (insn, operands, false);"
4986 [(set_attr "type" "fistp")
4987 (set_attr "i387_cw" "trunc")
4988 (set_attr "mode" "<MODE>")])
4990 (define_insn "fix_trunc<mode>_i387_with_temp"
4991 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4992 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4993 (use (match_operand:HI 2 "memory_operand" "m,m"))
4994 (use (match_operand:HI 3 "memory_operand" "m,m"))
4995 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4996 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4998 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5000 [(set_attr "type" "fistp")
5001 (set_attr "i387_cw" "trunc")
5002 (set_attr "mode" "<MODE>")])
5005 [(set (match_operand:SWI24 0 "register_operand")
5006 (fix:SWI24 (match_operand 1 "register_operand")))
5007 (use (match_operand:HI 2 "memory_operand"))
5008 (use (match_operand:HI 3 "memory_operand"))
5009 (clobber (match_operand:SWI24 4 "memory_operand"))]
5011 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
5013 (use (match_dup 3))])
5014 (set (match_dup 0) (match_dup 4))])
5017 [(set (match_operand:SWI24 0 "memory_operand")
5018 (fix:SWI24 (match_operand 1 "register_operand")))
5019 (use (match_operand:HI 2 "memory_operand"))
5020 (use (match_operand:HI 3 "memory_operand"))
5021 (clobber (match_operand:SWI24 4 "memory_operand"))]
5023 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
5025 (use (match_dup 3))])])
5027 (define_insn "x86_fnstcw_1"
5028 [(set (match_operand:HI 0 "memory_operand" "=m")
5029 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5032 [(set (attr "length")
5033 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5034 (set_attr "mode" "HI")
5035 (set_attr "unit" "i387")
5036 (set_attr "bdver1_decode" "vector")])
5038 (define_insn "x86_fldcw_1"
5039 [(set (reg:HI FPCR_REG)
5040 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5043 [(set (attr "length")
5044 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5045 (set_attr "mode" "HI")
5046 (set_attr "unit" "i387")
5047 (set_attr "athlon_decode" "vector")
5048 (set_attr "amdfam10_decode" "vector")
5049 (set_attr "bdver1_decode" "vector")])
5051 ;; Conversion between fixed point and floating point.
5053 ;; Even though we only accept memory inputs, the backend _really_
5054 ;; wants to be able to do this between registers. Thankfully, LRA
5055 ;; will fix this up for us during register allocation.
5057 (define_insn "floathi<mode>2"
5058 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5059 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5061 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5062 || TARGET_MIX_SSE_I387)"
5064 [(set_attr "type" "fmov")
5065 (set_attr "mode" "<MODE>")
5066 (set_attr "znver1_decode" "double")
5067 (set_attr "fp_int_src" "true")])
5069 (define_insn "float<SWI48x:mode>xf2"
5070 [(set (match_operand:XF 0 "register_operand" "=f")
5071 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5074 [(set_attr "type" "fmov")
5075 (set_attr "mode" "XF")
5076 (set_attr "znver1_decode" "double")
5077 (set_attr "fp_int_src" "true")])
5079 (define_expand "float<SWI48:mode><MODEF:mode>2"
5080 [(set (match_operand:MODEF 0 "register_operand")
5081 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5082 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5084 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
5085 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5087 rtx reg = gen_reg_rtx (XFmode);
5088 rtx (*insn)(rtx, rtx);
5090 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
5092 if (<MODEF:MODE>mode == SFmode)
5093 insn = gen_truncxfsf2;
5094 else if (<MODEF:MODE>mode == DFmode)
5095 insn = gen_truncxfdf2;
5099 emit_insn (insn (operands[0], reg));
5104 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed"
5105 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5107 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5108 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5111 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5112 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5113 [(set_attr "type" "fmov,sseicvt,sseicvt")
5114 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5115 (set_attr "mode" "<MODEF:MODE>")
5116 (set (attr "prefix_rex")
5118 (and (eq_attr "prefix" "maybe_vex")
5119 (match_test "<SWI48:MODE>mode == DImode"))
5121 (const_string "*")))
5122 (set_attr "unit" "i387,*,*")
5123 (set_attr "athlon_decode" "*,double,direct")
5124 (set_attr "amdfam10_decode" "*,vector,double")
5125 (set_attr "bdver1_decode" "*,double,direct")
5126 (set_attr "znver1_decode" "double,*,*")
5127 (set_attr "fp_int_src" "true")
5128 (set (attr "enabled")
5129 (cond [(eq_attr "alternative" "0")
5130 (symbol_ref "TARGET_MIX_SSE_I387
5131 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5134 (symbol_ref "true")))
5135 (set (attr "preferred_for_speed")
5136 (cond [(eq_attr "alternative" "1")
5137 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5138 (symbol_ref "true")))])
5140 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
5141 [(set (match_operand:MODEF 0 "register_operand" "=f")
5142 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5143 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
5145 [(set_attr "type" "fmov")
5146 (set_attr "mode" "<MODEF:MODE>")
5147 (set_attr "znver1_decode" "double")
5148 (set_attr "fp_int_src" "true")])
5150 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5151 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5152 ;; alternative in sse2_loadld.
5154 [(set (match_operand:MODEF 0 "sse_reg_operand")
5155 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5156 "TARGET_USE_VECTOR_CONVERTS
5157 && optimize_function_for_speed_p (cfun)
5159 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5160 && (!EXT_REX_SSE_REG_P (operands[0])
5161 || TARGET_AVX512VL)"
5164 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5165 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5167 emit_insn (gen_sse2_loadld (operands[4],
5168 CONST0_RTX (V4SImode), operands[1]));
5170 if (<ssevecmode>mode == V4SFmode)
5171 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5173 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5177 ;; Avoid partial SSE register dependency stalls. This splitter should split
5178 ;; late in the pass sequence (after register rename pass), so allocated
5179 ;; registers won't change anymore
5182 [(set (match_operand:MODEF 0 "sse_reg_operand")
5183 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5184 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5185 && optimize_function_for_speed_p (cfun)
5186 && (!EXT_REX_SSE_REG_P (operands[0])
5187 || TARGET_AVX512VL)"
5189 (vec_merge:<MODEF:ssevecmode>
5190 (vec_duplicate:<MODEF:ssevecmode>
5196 const machine_mode vmode = <MODEF:ssevecmode>mode;
5198 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5199 emit_move_insn (operands[0], CONST0_RTX (vmode));
5202 ;; Break partial reg stall for cvtsd2ss. This splitter should split
5203 ;; late in the pass sequence (after register rename pass),
5204 ;; so allocated registers won't change anymore.
5207 [(set (match_operand:SF 0 "sse_reg_operand")
5209 (match_operand:DF 1 "nonimmediate_operand")))]
5210 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5211 && optimize_function_for_speed_p (cfun)
5212 && (!REG_P (operands[1])
5213 || REGNO (operands[0]) != REGNO (operands[1]))
5214 && (!EXT_REX_SSE_REG_P (operands[0])
5215 || TARGET_AVX512VL)"
5224 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5225 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5228 ;; Break partial reg stall for cvtss2sd. This splitter should split
5229 ;; late in the pass sequence (after register rename pass),
5230 ;; so allocated registers won't change anymore.
5233 [(set (match_operand:DF 0 "sse_reg_operand")
5235 (match_operand:SF 1 "nonimmediate_operand")))]
5236 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5237 && optimize_function_for_speed_p (cfun)
5238 && (!REG_P (operands[1])
5239 || REGNO (operands[0]) != REGNO (operands[1]))
5240 && (!EXT_REX_SSE_REG_P (operands[0])
5241 || TARGET_AVX512VL)"
5250 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5251 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5254 ;; Avoid store forwarding (partial memory) stall penalty
5255 ;; by passing DImode value through XMM registers. */
5257 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5258 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5260 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5261 (clobber (match_scratch:V4SI 3 "=X,x"))
5262 (clobber (match_scratch:V4SI 4 "=X,x"))
5263 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5264 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5265 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5266 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5268 [(set_attr "type" "multi")
5269 (set_attr "mode" "<X87MODEF:MODE>")
5270 (set_attr "unit" "i387")
5271 (set_attr "fp_int_src" "true")])
5274 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5275 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5276 (clobber (match_scratch:V4SI 3))
5277 (clobber (match_scratch:V4SI 4))
5278 (clobber (match_operand:DI 2 "memory_operand"))]
5279 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5280 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5281 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5282 && reload_completed"
5283 [(set (match_dup 2) (match_dup 3))
5284 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5286 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5287 Assemble the 64-bit DImode value in an xmm register. */
5288 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5289 gen_lowpart (SImode, operands[1])));
5290 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5291 gen_highpart (SImode, operands[1])));
5292 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5295 operands[3] = gen_lowpart (DImode, operands[3]);
5299 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5300 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5301 (clobber (match_scratch:V4SI 3))
5302 (clobber (match_scratch:V4SI 4))
5303 (clobber (match_operand:DI 2 "memory_operand"))]
5304 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5305 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5306 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5307 && reload_completed"
5308 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5310 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5311 [(set (match_operand:MODEF 0 "register_operand")
5312 (unsigned_float:MODEF
5313 (match_operand:SWI12 1 "nonimmediate_operand")))]
5315 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5317 operands[1] = convert_to_mode (SImode, operands[1], 1);
5318 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5322 ;; Avoid store forwarding (partial memory) stall penalty by extending
5323 ;; SImode value to DImode through XMM register instead of pushing two
5324 ;; SImode values to stack. Also note that fild loads from memory only.
5326 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5327 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5328 (unsigned_float:X87MODEF
5329 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5330 (clobber (match_scratch:DI 3 "=x"))
5331 (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5333 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5334 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5336 "&& reload_completed"
5337 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5338 (set (match_dup 2) (match_dup 3))
5340 (float:X87MODEF (match_dup 2)))]
5342 [(set_attr "type" "multi")
5343 (set_attr "mode" "<MODE>")])
5345 (define_expand "floatunssi<mode>2"
5347 [(set (match_operand:X87MODEF 0 "register_operand")
5348 (unsigned_float:X87MODEF
5349 (match_operand:SI 1 "nonimmediate_operand")))
5350 (clobber (match_scratch:DI 3))
5351 (clobber (match_dup 2))])]
5353 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5354 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5355 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5357 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5359 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5363 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5366 (define_expand "floatunsdisf2"
5367 [(use (match_operand:SF 0 "register_operand"))
5368 (use (match_operand:DI 1 "nonimmediate_operand"))]
5369 "TARGET_64BIT && TARGET_SSE_MATH"
5370 "x86_emit_floatuns (operands); DONE;")
5372 (define_expand "floatunsdidf2"
5373 [(use (match_operand:DF 0 "register_operand"))
5374 (use (match_operand:DI 1 "nonimmediate_operand"))]
5375 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5376 && TARGET_SSE2 && TARGET_SSE_MATH"
5379 x86_emit_floatuns (operands);
5381 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5385 ;; Load effective address instructions
5387 (define_insn_and_split "*lea<mode>"
5388 [(set (match_operand:SWI48 0 "register_operand" "=r")
5389 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5392 if (SImode_address_operand (operands[1], VOIDmode))
5394 gcc_assert (TARGET_64BIT);
5395 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5398 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5400 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5403 machine_mode mode = <MODE>mode;
5406 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5407 change operands[] array behind our back. */
5408 pat = PATTERN (curr_insn);
5410 operands[0] = SET_DEST (pat);
5411 operands[1] = SET_SRC (pat);
5413 /* Emit all operations in SImode for zero-extended addresses. */
5414 if (SImode_address_operand (operands[1], VOIDmode))
5417 ix86_split_lea_for_addr (curr_insn, operands, mode);
5419 /* Zero-extend return register to DImode for zero-extended addresses. */
5420 if (mode != <MODE>mode)
5421 emit_insn (gen_zero_extendsidi2
5422 (operands[0], gen_lowpart (mode, operands[0])));
5426 [(set_attr "type" "lea")
5429 (match_operand 1 "SImode_address_operand")
5431 (const_string "<MODE>")))])
5435 (define_expand "add<mode>3"
5436 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5437 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5438 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5440 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5442 (define_insn_and_split "*add<dwi>3_doubleword"
5443 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5445 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5446 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
5448 (clobber (reg:CC FLAGS_REG))]
5449 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5452 [(parallel [(set (reg:CCC FLAGS_REG)
5454 (plus:DWIH (match_dup 1) (match_dup 2))
5457 (plus:DWIH (match_dup 1) (match_dup 2)))])
5458 (parallel [(set (match_dup 3)
5461 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5464 (clobber (reg:CC FLAGS_REG))])]
5466 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5467 if (operands[2] == const0_rtx)
5469 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5474 (define_insn "*add<mode>_1"
5475 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5477 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5478 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5479 (clobber (reg:CC FLAGS_REG))]
5480 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5482 switch (get_attr_type (insn))
5488 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5489 if (operands[2] == const1_rtx)
5490 return "inc{<imodesuffix>}\t%0";
5493 gcc_assert (operands[2] == constm1_rtx);
5494 return "dec{<imodesuffix>}\t%0";
5498 /* For most processors, ADD is faster than LEA. This alternative
5499 was added to use ADD as much as possible. */
5500 if (which_alternative == 2)
5501 std::swap (operands[1], operands[2]);
5503 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5504 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5505 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5507 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5511 (cond [(eq_attr "alternative" "3")
5512 (const_string "lea")
5513 (match_operand:SWI48 2 "incdec_operand")
5514 (const_string "incdec")
5516 (const_string "alu")))
5517 (set (attr "length_immediate")
5519 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5521 (const_string "*")))
5522 (set_attr "mode" "<MODE>")])
5524 ;; It may seem that nonimmediate operand is proper one for operand 1.
5525 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5526 ;; we take care in ix86_binary_operator_ok to not allow two memory
5527 ;; operands so proper swapping will be done in reload. This allow
5528 ;; patterns constructed from addsi_1 to match.
5530 (define_insn "addsi_1_zext"
5531 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5533 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5534 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5535 (clobber (reg:CC FLAGS_REG))]
5536 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5538 switch (get_attr_type (insn))
5544 if (operands[2] == const1_rtx)
5545 return "inc{l}\t%k0";
5548 gcc_assert (operands[2] == constm1_rtx);
5549 return "dec{l}\t%k0";
5553 /* For most processors, ADD is faster than LEA. This alternative
5554 was added to use ADD as much as possible. */
5555 if (which_alternative == 1)
5556 std::swap (operands[1], operands[2]);
5558 if (x86_maybe_negate_const_int (&operands[2], SImode))
5559 return "sub{l}\t{%2, %k0|%k0, %2}";
5561 return "add{l}\t{%2, %k0|%k0, %2}";
5565 (cond [(eq_attr "alternative" "2")
5566 (const_string "lea")
5567 (match_operand:SI 2 "incdec_operand")
5568 (const_string "incdec")
5570 (const_string "alu")))
5571 (set (attr "length_immediate")
5573 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5575 (const_string "*")))
5576 (set_attr "mode" "SI")])
5578 (define_insn "*addhi_1"
5579 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5580 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5581 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5582 (clobber (reg:CC FLAGS_REG))]
5583 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5585 switch (get_attr_type (insn))
5591 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5592 if (operands[2] == const1_rtx)
5593 return "inc{w}\t%0";
5596 gcc_assert (operands[2] == constm1_rtx);
5597 return "dec{w}\t%0";
5601 /* For most processors, ADD is faster than LEA. This alternative
5602 was added to use ADD as much as possible. */
5603 if (which_alternative == 2)
5604 std::swap (operands[1], operands[2]);
5606 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5607 if (x86_maybe_negate_const_int (&operands[2], HImode))
5608 return "sub{w}\t{%2, %0|%0, %2}";
5610 return "add{w}\t{%2, %0|%0, %2}";
5614 (cond [(eq_attr "alternative" "3")
5615 (const_string "lea")
5616 (match_operand:HI 2 "incdec_operand")
5617 (const_string "incdec")
5619 (const_string "alu")))
5620 (set (attr "length_immediate")
5622 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5624 (const_string "*")))
5625 (set_attr "mode" "HI,HI,HI,SI")])
5627 (define_insn "*addqi_1"
5628 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5629 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5630 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5631 (clobber (reg:CC FLAGS_REG))]
5632 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5634 bool widen = (get_attr_mode (insn) != MODE_QI);
5636 switch (get_attr_type (insn))
5642 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5643 if (operands[2] == const1_rtx)
5644 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5647 gcc_assert (operands[2] == constm1_rtx);
5648 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5652 /* For most processors, ADD is faster than LEA. These alternatives
5653 were added to use ADD as much as possible. */
5654 if (which_alternative == 2 || which_alternative == 4)
5655 std::swap (operands[1], operands[2]);
5657 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5658 if (x86_maybe_negate_const_int (&operands[2], QImode))
5661 return "sub{l}\t{%2, %k0|%k0, %2}";
5663 return "sub{b}\t{%2, %0|%0, %2}";
5666 return "add{l}\t{%k2, %k0|%k0, %k2}";
5668 return "add{b}\t{%2, %0|%0, %2}";
5672 (cond [(eq_attr "alternative" "5")
5673 (const_string "lea")
5674 (match_operand:QI 2 "incdec_operand")
5675 (const_string "incdec")
5677 (const_string "alu")))
5678 (set (attr "length_immediate")
5680 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5682 (const_string "*")))
5683 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
5684 ;; Potential partial reg stall on alternatives 3 and 4.
5685 (set (attr "preferred_for_speed")
5686 (cond [(eq_attr "alternative" "3,4")
5687 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
5688 (symbol_ref "true")))])
5690 (define_insn "*addqi_1_slp"
5691 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5692 (plus:QI (match_dup 0)
5693 (match_operand:QI 1 "general_operand" "qn,qm")))
5694 (clobber (reg:CC FLAGS_REG))]
5695 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5696 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5698 switch (get_attr_type (insn))
5701 if (operands[1] == const1_rtx)
5702 return "inc{b}\t%0";
5705 gcc_assert (operands[1] == constm1_rtx);
5706 return "dec{b}\t%0";
5710 if (x86_maybe_negate_const_int (&operands[1], QImode))
5711 return "sub{b}\t{%1, %0|%0, %1}";
5713 return "add{b}\t{%1, %0|%0, %1}";
5717 (if_then_else (match_operand:QI 1 "incdec_operand")
5718 (const_string "incdec")
5719 (const_string "alu1")))
5720 (set (attr "memory")
5721 (if_then_else (match_operand 1 "memory_operand")
5722 (const_string "load")
5723 (const_string "none")))
5724 (set_attr "mode" "QI")])
5726 ;; Split non destructive adds if we cannot use lea.
5728 [(set (match_operand:SWI48 0 "register_operand")
5729 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5730 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5731 (clobber (reg:CC FLAGS_REG))]
5732 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5733 [(set (match_dup 0) (match_dup 1))
5734 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5735 (clobber (reg:CC FLAGS_REG))])])
5737 ;; Split non destructive adds if we cannot use lea.
5739 [(set (match_operand:DI 0 "register_operand")
5741 (plus:SI (match_operand:SI 1 "register_operand")
5742 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5743 (clobber (reg:CC FLAGS_REG))]
5745 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5746 [(set (match_dup 3) (match_dup 1))
5747 (parallel [(set (match_dup 0)
5748 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5749 (clobber (reg:CC FLAGS_REG))])]
5750 "operands[3] = gen_lowpart (SImode, operands[0]);")
5752 ;; Convert add to the lea pattern to avoid flags dependency.
5754 [(set (match_operand:SWI 0 "register_operand")
5755 (plus:SWI (match_operand:SWI 1 "register_operand")
5756 (match_operand:SWI 2 "<nonmemory_operand>")))
5757 (clobber (reg:CC FLAGS_REG))]
5758 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5760 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
5762 if (<MODE>mode != <LEAMODE>mode)
5764 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
5765 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
5766 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
5770 ;; Convert add to the lea pattern to avoid flags dependency.
5772 [(set (match_operand:DI 0 "register_operand")
5774 (plus:SI (match_operand:SI 1 "register_operand")
5775 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5776 (clobber (reg:CC FLAGS_REG))]
5777 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5779 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5781 (define_insn "*add<mode>_2"
5782 [(set (reg FLAGS_REG)
5785 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5786 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5788 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5789 (plus:SWI (match_dup 1) (match_dup 2)))]
5790 "ix86_match_ccmode (insn, CCGOCmode)
5791 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5793 switch (get_attr_type (insn))
5796 if (operands[2] == const1_rtx)
5797 return "inc{<imodesuffix>}\t%0";
5800 gcc_assert (operands[2] == constm1_rtx);
5801 return "dec{<imodesuffix>}\t%0";
5805 if (which_alternative == 2)
5806 std::swap (operands[1], operands[2]);
5808 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5809 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5810 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5812 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5816 (if_then_else (match_operand:SWI 2 "incdec_operand")
5817 (const_string "incdec")
5818 (const_string "alu")))
5819 (set (attr "length_immediate")
5821 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5823 (const_string "*")))
5824 (set_attr "mode" "<MODE>")])
5826 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5827 (define_insn "*addsi_2_zext"
5828 [(set (reg FLAGS_REG)
5830 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5831 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5833 (set (match_operand:DI 0 "register_operand" "=r,r")
5834 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5835 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5836 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5838 switch (get_attr_type (insn))
5841 if (operands[2] == const1_rtx)
5842 return "inc{l}\t%k0";
5845 gcc_assert (operands[2] == constm1_rtx);
5846 return "dec{l}\t%k0";
5850 if (which_alternative == 1)
5851 std::swap (operands[1], operands[2]);
5853 if (x86_maybe_negate_const_int (&operands[2], SImode))
5854 return "sub{l}\t{%2, %k0|%k0, %2}";
5856 return "add{l}\t{%2, %k0|%k0, %2}";
5860 (if_then_else (match_operand:SI 2 "incdec_operand")
5861 (const_string "incdec")
5862 (const_string "alu")))
5863 (set (attr "length_immediate")
5865 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5867 (const_string "*")))
5868 (set_attr "mode" "SI")])
5870 (define_insn "*add<mode>_3"
5871 [(set (reg FLAGS_REG)
5873 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5874 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5875 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5876 "ix86_match_ccmode (insn, CCZmode)
5877 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5879 switch (get_attr_type (insn))
5882 if (operands[2] == const1_rtx)
5883 return "inc{<imodesuffix>}\t%0";
5886 gcc_assert (operands[2] == constm1_rtx);
5887 return "dec{<imodesuffix>}\t%0";
5891 if (which_alternative == 1)
5892 std::swap (operands[1], operands[2]);
5894 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5895 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5896 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5898 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5902 (if_then_else (match_operand:SWI 2 "incdec_operand")
5903 (const_string "incdec")
5904 (const_string "alu")))
5905 (set (attr "length_immediate")
5907 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5909 (const_string "*")))
5910 (set_attr "mode" "<MODE>")])
5912 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5913 (define_insn "*addsi_3_zext"
5914 [(set (reg FLAGS_REG)
5916 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5917 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5918 (set (match_operand:DI 0 "register_operand" "=r,r")
5919 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5920 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5921 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5923 switch (get_attr_type (insn))
5926 if (operands[2] == const1_rtx)
5927 return "inc{l}\t%k0";
5930 gcc_assert (operands[2] == constm1_rtx);
5931 return "dec{l}\t%k0";
5935 if (which_alternative == 1)
5936 std::swap (operands[1], operands[2]);
5938 if (x86_maybe_negate_const_int (&operands[2], SImode))
5939 return "sub{l}\t{%2, %k0|%k0, %2}";
5941 return "add{l}\t{%2, %k0|%k0, %2}";
5945 (if_then_else (match_operand:SI 2 "incdec_operand")
5946 (const_string "incdec")
5947 (const_string "alu")))
5948 (set (attr "length_immediate")
5950 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5952 (const_string "*")))
5953 (set_attr "mode" "SI")])
5955 ; For comparisons against 1, -1 and 128, we may generate better code
5956 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5957 ; is matched then. We can't accept general immediate, because for
5958 ; case of overflows, the result is messed up.
5959 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5960 ; only for comparisons not depending on it.
5962 (define_insn "*adddi_4"
5963 [(set (reg FLAGS_REG)
5965 (match_operand:DI 1 "nonimmediate_operand" "0")
5966 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5967 (clobber (match_scratch:DI 0 "=rm"))]
5969 && ix86_match_ccmode (insn, CCGCmode)"
5971 switch (get_attr_type (insn))
5974 if (operands[2] == constm1_rtx)
5975 return "inc{q}\t%0";
5978 gcc_assert (operands[2] == const1_rtx);
5979 return "dec{q}\t%0";
5983 if (x86_maybe_negate_const_int (&operands[2], DImode))
5984 return "add{q}\t{%2, %0|%0, %2}";
5986 return "sub{q}\t{%2, %0|%0, %2}";
5990 (if_then_else (match_operand:DI 2 "incdec_operand")
5991 (const_string "incdec")
5992 (const_string "alu")))
5993 (set (attr "length_immediate")
5995 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5997 (const_string "*")))
5998 (set_attr "mode" "DI")])
6000 ; For comparisons against 1, -1 and 128, we may generate better code
6001 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6002 ; is matched then. We can't accept general immediate, because for
6003 ; case of overflows, the result is messed up.
6004 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6005 ; only for comparisons not depending on it.
6007 (define_insn "*add<mode>_4"
6008 [(set (reg FLAGS_REG)
6010 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6011 (match_operand:SWI124 2 "const_int_operand" "n")))
6012 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6013 "ix86_match_ccmode (insn, CCGCmode)"
6015 switch (get_attr_type (insn))
6018 if (operands[2] == constm1_rtx)
6019 return "inc{<imodesuffix>}\t%0";
6022 gcc_assert (operands[2] == const1_rtx);
6023 return "dec{<imodesuffix>}\t%0";
6027 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6028 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6030 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6034 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6035 (const_string "incdec")
6036 (const_string "alu")))
6037 (set (attr "length_immediate")
6039 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6041 (const_string "*")))
6042 (set_attr "mode" "<MODE>")])
6044 (define_insn "*add<mode>_5"
6045 [(set (reg FLAGS_REG)
6048 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6049 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6051 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6052 "ix86_match_ccmode (insn, CCGOCmode)
6053 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6055 switch (get_attr_type (insn))
6058 if (operands[2] == const1_rtx)
6059 return "inc{<imodesuffix>}\t%0";
6062 gcc_assert (operands[2] == constm1_rtx);
6063 return "dec{<imodesuffix>}\t%0";
6067 if (which_alternative == 1)
6068 std::swap (operands[1], operands[2]);
6070 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6071 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6072 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6074 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6078 (if_then_else (match_operand:SWI 2 "incdec_operand")
6079 (const_string "incdec")
6080 (const_string "alu")))
6081 (set (attr "length_immediate")
6083 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6085 (const_string "*")))
6086 (set_attr "mode" "<MODE>")])
6088 (define_insn "addqi_ext_1"
6089 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
6095 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
6098 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
6099 (clobber (reg:CC FLAGS_REG))]
6102 switch (get_attr_type (insn))
6105 if (operands[2] == const1_rtx)
6106 return "inc{b}\t%h0";
6109 gcc_assert (operands[2] == constm1_rtx);
6110 return "dec{b}\t%h0";
6114 return "add{b}\t{%2, %h0|%h0, %2}";
6117 [(set_attr "isa" "*,nox64")
6119 (if_then_else (match_operand:QI 2 "incdec_operand")
6120 (const_string "incdec")
6121 (const_string "alu")))
6122 (set_attr "mode" "QI")])
6124 (define_insn "*addqi_ext_2"
6125 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6131 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
6135 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
6137 (const_int 8)) 0)) 0))
6138 (clobber (reg:CC FLAGS_REG))]
6140 "add{b}\t{%h2, %h0|%h0, %h2}"
6141 [(set_attr "type" "alu")
6142 (set_attr "mode" "QI")])
6144 ;; Add with jump on overflow.
6145 (define_expand "addv<mode>4"
6146 [(parallel [(set (reg:CCO FLAGS_REG)
6149 (match_operand:SWI 1 "nonimmediate_operand"))
6152 (plus:SWI (match_dup 1)
6153 (match_operand:SWI 2
6154 "<general_operand>")))))
6155 (set (match_operand:SWI 0 "register_operand")
6156 (plus:SWI (match_dup 1) (match_dup 2)))])
6157 (set (pc) (if_then_else
6158 (eq (reg:CCO FLAGS_REG) (const_int 0))
6159 (label_ref (match_operand 3))
6163 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6164 if (CONST_INT_P (operands[2]))
6165 operands[4] = operands[2];
6167 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6170 (define_insn "*addv<mode>4"
6171 [(set (reg:CCO FLAGS_REG)
6174 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6176 (match_operand:SWI 2 "<general_sext_operand>"
6179 (plus:SWI (match_dup 1) (match_dup 2)))))
6180 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6181 (plus:SWI (match_dup 1) (match_dup 2)))]
6182 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6183 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6184 [(set_attr "type" "alu")
6185 (set_attr "mode" "<MODE>")])
6187 (define_insn "*addv<mode>4_1"
6188 [(set (reg:CCO FLAGS_REG)
6191 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6192 (match_operand:<DWI> 3 "const_int_operand" "i"))
6194 (plus:SWI (match_dup 1)
6195 (match_operand:SWI 2 "x86_64_immediate_operand"
6197 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6198 (plus:SWI (match_dup 1) (match_dup 2)))]
6199 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6200 && CONST_INT_P (operands[2])
6201 && INTVAL (operands[2]) == INTVAL (operands[3])"
6202 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6203 [(set_attr "type" "alu")
6204 (set_attr "mode" "<MODE>")
6205 (set (attr "length_immediate")
6206 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6208 (match_test "<MODE_SIZE> == 8")
6210 (const_string "<MODE_SIZE>")))])
6212 (define_expand "uaddv<mode>4"
6213 [(parallel [(set (reg:CCC FLAGS_REG)
6216 (match_operand:SWI 1 "nonimmediate_operand")
6217 (match_operand:SWI 2 "<general_operand>"))
6219 (set (match_operand:SWI 0 "register_operand")
6220 (plus:SWI (match_dup 1) (match_dup 2)))])
6221 (set (pc) (if_then_else
6222 (ltu (reg:CCC FLAGS_REG) (const_int 0))
6223 (label_ref (match_operand 3))
6226 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6228 ;; The lea patterns for modes less than 32 bits need to be matched by
6229 ;; several insns converted to real lea by splitters.
6231 (define_insn_and_split "*lea<mode>_general_1"
6232 [(set (match_operand:SWI12 0 "register_operand" "=r")
6234 (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6235 (match_operand:SWI12 2 "register_operand" "r"))
6236 (match_operand:SWI12 3 "immediate_operand" "i")))]
6237 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6239 "&& reload_completed"
6242 (plus:SI (match_dup 1) (match_dup 2))
6245 operands[0] = gen_lowpart (SImode, operands[0]);
6246 operands[1] = gen_lowpart (SImode, operands[1]);
6247 operands[2] = gen_lowpart (SImode, operands[2]);
6248 operands[3] = gen_lowpart (SImode, operands[3]);
6250 [(set_attr "type" "lea")
6251 (set_attr "mode" "SI")])
6253 (define_insn_and_split "*lea<mode>_general_2"
6254 [(set (match_operand:SWI12 0 "register_operand" "=r")
6256 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6257 (match_operand 2 "const248_operand" "n"))
6258 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6259 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6261 "&& reload_completed"
6264 (mult:SI (match_dup 1) (match_dup 2))
6267 operands[0] = gen_lowpart (SImode, operands[0]);
6268 operands[1] = gen_lowpart (SImode, operands[1]);
6269 operands[3] = gen_lowpart (SImode, operands[3]);
6271 [(set_attr "type" "lea")
6272 (set_attr "mode" "SI")])
6274 (define_insn_and_split "*lea<mode>_general_2b"
6275 [(set (match_operand:SWI12 0 "register_operand" "=r")
6277 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6278 (match_operand 2 "const123_operand" "n"))
6279 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6280 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6282 "&& reload_completed"
6285 (ashift:SI (match_dup 1) (match_dup 2))
6288 operands[0] = gen_lowpart (SImode, operands[0]);
6289 operands[1] = gen_lowpart (SImode, operands[1]);
6290 operands[3] = gen_lowpart (SImode, operands[3]);
6292 [(set_attr "type" "lea")
6293 (set_attr "mode" "SI")])
6295 (define_insn_and_split "*lea<mode>_general_3"
6296 [(set (match_operand:SWI12 0 "register_operand" "=r")
6299 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6300 (match_operand 2 "const248_operand" "n"))
6301 (match_operand:SWI12 3 "register_operand" "r"))
6302 (match_operand:SWI12 4 "immediate_operand" "i")))]
6303 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6305 "&& reload_completed"
6309 (mult:SI (match_dup 1) (match_dup 2))
6313 operands[0] = gen_lowpart (SImode, operands[0]);
6314 operands[1] = gen_lowpart (SImode, operands[1]);
6315 operands[3] = gen_lowpart (SImode, operands[3]);
6316 operands[4] = gen_lowpart (SImode, operands[4]);
6318 [(set_attr "type" "lea")
6319 (set_attr "mode" "SI")])
6321 (define_insn_and_split "*lea<mode>_general_3b"
6322 [(set (match_operand:SWI12 0 "register_operand" "=r")
6325 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6326 (match_operand 2 "const123_operand" "n"))
6327 (match_operand:SWI12 3 "register_operand" "r"))
6328 (match_operand:SWI12 4 "immediate_operand" "i")))]
6329 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6331 "&& reload_completed"
6335 (ashift:SI (match_dup 1) (match_dup 2))
6339 operands[0] = gen_lowpart (SImode, operands[0]);
6340 operands[1] = gen_lowpart (SImode, operands[1]);
6341 operands[3] = gen_lowpart (SImode, operands[3]);
6342 operands[4] = gen_lowpart (SImode, operands[4]);
6344 [(set_attr "type" "lea")
6345 (set_attr "mode" "SI")])
6347 (define_insn_and_split "*lea<mode>_general_4"
6348 [(set (match_operand:SWI12 0 "register_operand" "=r")
6351 (match_operand:SWI12 1 "index_register_operand" "l")
6352 (match_operand 2 "const_0_to_3_operand" "n"))
6353 (match_operand 3 "const_int_operand" "n")))]
6354 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6355 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6356 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6358 "&& reload_completed"
6361 (mult:SI (match_dup 1) (match_dup 2))
6364 operands[0] = gen_lowpart (SImode, operands[0]);
6365 operands[1] = gen_lowpart (SImode, operands[1]);
6366 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6368 [(set_attr "type" "lea")
6369 (set_attr "mode" "SI")])
6371 (define_insn_and_split "*lea<mode>_general_4"
6372 [(set (match_operand:SWI48 0 "register_operand" "=r")
6375 (match_operand:SWI48 1 "index_register_operand" "l")
6376 (match_operand 2 "const_0_to_3_operand" "n"))
6377 (match_operand 3 "const_int_operand" "n")))]
6378 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6379 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6381 "&& reload_completed"
6384 (mult:SWI48 (match_dup 1) (match_dup 2))
6386 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6387 [(set_attr "type" "lea")
6388 (set_attr "mode" "<MODE>")])
6390 ;; Subtract instructions
6392 (define_expand "sub<mode>3"
6393 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6394 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6395 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6397 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6399 (define_insn_and_split "*sub<dwi>3_doubleword"
6400 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6402 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6403 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
6405 (clobber (reg:CC FLAGS_REG))]
6406 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6409 [(parallel [(set (reg:CC FLAGS_REG)
6410 (compare:CC (match_dup 1) (match_dup 2)))
6412 (minus:DWIH (match_dup 1) (match_dup 2)))])
6413 (parallel [(set (match_dup 3)
6417 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6419 (clobber (reg:CC FLAGS_REG))])]
6421 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6422 if (operands[2] == const0_rtx)
6424 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6429 (define_insn "*sub<mode>_1"
6430 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6432 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6433 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6434 (clobber (reg:CC FLAGS_REG))]
6435 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6436 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6437 [(set_attr "type" "alu")
6438 (set_attr "mode" "<MODE>")])
6440 (define_insn "*subsi_1_zext"
6441 [(set (match_operand:DI 0 "register_operand" "=r")
6443 (minus:SI (match_operand:SI 1 "register_operand" "0")
6444 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6445 (clobber (reg:CC FLAGS_REG))]
6446 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6447 "sub{l}\t{%2, %k0|%k0, %2}"
6448 [(set_attr "type" "alu")
6449 (set_attr "mode" "SI")])
6451 (define_insn "*subqi_1_slp"
6452 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6453 (minus:QI (match_dup 0)
6454 (match_operand:QI 1 "general_operand" "qn,qm")))
6455 (clobber (reg:CC FLAGS_REG))]
6456 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6457 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6458 "sub{b}\t{%1, %0|%0, %1}"
6459 [(set_attr "type" "alu1")
6460 (set_attr "mode" "QI")])
6462 (define_insn "*sub<mode>_2"
6463 [(set (reg FLAGS_REG)
6466 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6467 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6469 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6470 (minus:SWI (match_dup 1) (match_dup 2)))]
6471 "ix86_match_ccmode (insn, CCGOCmode)
6472 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6473 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6474 [(set_attr "type" "alu")
6475 (set_attr "mode" "<MODE>")])
6477 (define_insn "*subsi_2_zext"
6478 [(set (reg FLAGS_REG)
6480 (minus:SI (match_operand:SI 1 "register_operand" "0")
6481 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6483 (set (match_operand:DI 0 "register_operand" "=r")
6485 (minus:SI (match_dup 1)
6487 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6488 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6489 "sub{l}\t{%2, %k0|%k0, %2}"
6490 [(set_attr "type" "alu")
6491 (set_attr "mode" "SI")])
6493 ;; Subtract with jump on overflow.
6494 (define_expand "subv<mode>4"
6495 [(parallel [(set (reg:CCO FLAGS_REG)
6496 (eq:CCO (minus:<DWI>
6498 (match_operand:SWI 1 "nonimmediate_operand"))
6501 (minus:SWI (match_dup 1)
6502 (match_operand:SWI 2
6503 "<general_operand>")))))
6504 (set (match_operand:SWI 0 "register_operand")
6505 (minus:SWI (match_dup 1) (match_dup 2)))])
6506 (set (pc) (if_then_else
6507 (eq (reg:CCO FLAGS_REG) (const_int 0))
6508 (label_ref (match_operand 3))
6512 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6513 if (CONST_INT_P (operands[2]))
6514 operands[4] = operands[2];
6516 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6519 (define_insn "*subv<mode>4"
6520 [(set (reg:CCO FLAGS_REG)
6521 (eq:CCO (minus:<DWI>
6523 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6525 (match_operand:SWI 2 "<general_sext_operand>"
6528 (minus:SWI (match_dup 1) (match_dup 2)))))
6529 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6530 (minus:SWI (match_dup 1) (match_dup 2)))]
6531 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6532 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6533 [(set_attr "type" "alu")
6534 (set_attr "mode" "<MODE>")])
6536 (define_insn "*subv<mode>4_1"
6537 [(set (reg:CCO FLAGS_REG)
6538 (eq:CCO (minus:<DWI>
6540 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6541 (match_operand:<DWI> 3 "const_int_operand" "i"))
6543 (minus:SWI (match_dup 1)
6544 (match_operand:SWI 2 "x86_64_immediate_operand"
6546 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6547 (minus:SWI (match_dup 1) (match_dup 2)))]
6548 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6549 && CONST_INT_P (operands[2])
6550 && INTVAL (operands[2]) == INTVAL (operands[3])"
6551 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6552 [(set_attr "type" "alu")
6553 (set_attr "mode" "<MODE>")
6554 (set (attr "length_immediate")
6555 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6557 (match_test "<MODE_SIZE> == 8")
6559 (const_string "<MODE_SIZE>")))])
6561 (define_expand "usubv<mode>4"
6562 [(parallel [(set (reg:CC FLAGS_REG)
6564 (match_operand:SWI 1 "nonimmediate_operand")
6565 (match_operand:SWI 2 "<general_operand>")))
6566 (set (match_operand:SWI 0 "register_operand")
6567 (minus:SWI (match_dup 1) (match_dup 2)))])
6568 (set (pc) (if_then_else
6569 (ltu (reg:CC FLAGS_REG) (const_int 0))
6570 (label_ref (match_operand 3))
6573 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6575 (define_insn "*sub<mode>_3"
6576 [(set (reg FLAGS_REG)
6577 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6578 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6579 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6580 (minus:SWI (match_dup 1) (match_dup 2)))]
6581 "ix86_match_ccmode (insn, CCmode)
6582 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6583 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6584 [(set_attr "type" "alu")
6585 (set_attr "mode" "<MODE>")])
6587 (define_insn "*subsi_3_zext"
6588 [(set (reg FLAGS_REG)
6589 (compare (match_operand:SI 1 "register_operand" "0")
6590 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6591 (set (match_operand:DI 0 "register_operand" "=r")
6593 (minus:SI (match_dup 1)
6595 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6596 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6597 "sub{l}\t{%2, %1|%1, %2}"
6598 [(set_attr "type" "alu")
6599 (set_attr "mode" "SI")])
6601 ;; Add with carry and subtract with borrow
6603 (define_insn "add<mode>3_carry"
6604 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6607 (match_operator:SWI 4 "ix86_carry_flag_operator"
6608 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6609 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6610 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6611 (clobber (reg:CC FLAGS_REG))]
6612 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6613 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6614 [(set_attr "type" "alu")
6615 (set_attr "use_carry" "1")
6616 (set_attr "pent_pair" "pu")
6617 (set_attr "mode" "<MODE>")])
6619 (define_insn "*addsi3_carry_zext"
6620 [(set (match_operand:DI 0 "register_operand" "=r")
6623 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6624 [(reg FLAGS_REG) (const_int 0)])
6625 (match_operand:SI 1 "register_operand" "%0"))
6626 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6627 (clobber (reg:CC FLAGS_REG))]
6628 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6629 "adc{l}\t{%2, %k0|%k0, %2}"
6630 [(set_attr "type" "alu")
6631 (set_attr "use_carry" "1")
6632 (set_attr "pent_pair" "pu")
6633 (set_attr "mode" "SI")])
6635 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6637 (define_insn "addcarry<mode>"
6638 [(set (reg:CCC FLAGS_REG)
6642 (match_operator:SWI48 4 "ix86_carry_flag_operator"
6643 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6644 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6645 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))
6647 (set (match_operand:SWI48 0 "register_operand" "=r")
6648 (plus:SWI48 (plus:SWI48 (match_op_dup 4
6649 [(match_dup 3) (const_int 0)])
6652 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6653 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6654 [(set_attr "type" "alu")
6655 (set_attr "use_carry" "1")
6656 (set_attr "pent_pair" "pu")
6657 (set_attr "mode" "<MODE>")])
6659 (define_insn "sub<mode>3_carry"
6660 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6663 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6664 (match_operator:SWI 4 "ix86_carry_flag_operator"
6665 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6666 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6667 (clobber (reg:CC FLAGS_REG))]
6668 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6669 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6670 [(set_attr "type" "alu")
6671 (set_attr "use_carry" "1")
6672 (set_attr "pent_pair" "pu")
6673 (set_attr "mode" "<MODE>")])
6675 (define_insn "*subsi3_carry_zext"
6676 [(set (match_operand:DI 0 "register_operand" "=r")
6680 (match_operand:SI 1 "register_operand" "0")
6681 (match_operator:SI 3 "ix86_carry_flag_operator"
6682 [(reg FLAGS_REG) (const_int 0)]))
6683 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6684 (clobber (reg:CC FLAGS_REG))]
6685 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6686 "sbb{l}\t{%2, %k0|%k0, %2}"
6687 [(set_attr "type" "alu")
6688 (set_attr "use_carry" "1")
6689 (set_attr "pent_pair" "pu")
6690 (set_attr "mode" "SI")])
6692 (define_insn "subborrow<mode>"
6693 [(set (reg:CCC FLAGS_REG)
6695 (match_operand:SWI48 1 "nonimmediate_operand" "0")
6697 (match_operator:SWI48 4 "ix86_carry_flag_operator"
6698 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6699 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
6700 (set (match_operand:SWI48 0 "register_operand" "=r")
6701 (minus:SWI48 (minus:SWI48 (match_dup 1)
6703 [(match_dup 3) (const_int 0)]))
6705 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6706 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6707 [(set_attr "type" "alu")
6708 (set_attr "use_carry" "1")
6709 (set_attr "pent_pair" "pu")
6710 (set_attr "mode" "<MODE>")])
6712 ;; Overflow setting add instructions
6714 (define_expand "addqi3_cconly_overflow"
6716 [(set (reg:CCC FLAGS_REG)
6719 (match_operand:QI 0 "nonimmediate_operand")
6720 (match_operand:QI 1 "general_operand"))
6722 (clobber (match_scratch:QI 2))])]
6723 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
6725 (define_insn "*add<mode>3_cconly_overflow_1"
6726 [(set (reg:CCC FLAGS_REG)
6729 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6730 (match_operand:SWI 2 "<general_operand>" "<g>"))
6732 (clobber (match_scratch:SWI 0 "=<r>"))]
6733 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6734 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6735 [(set_attr "type" "alu")
6736 (set_attr "mode" "<MODE>")])
6738 (define_insn "*add<mode>3_cc_overflow_1"
6739 [(set (reg:CCC FLAGS_REG)
6742 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6743 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6745 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6746 (plus:SWI (match_dup 1) (match_dup 2)))]
6747 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6748 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6749 [(set_attr "type" "alu")
6750 (set_attr "mode" "<MODE>")])
6752 (define_insn "*addsi3_zext_cc_overflow_1"
6753 [(set (reg:CCC FLAGS_REG)
6756 (match_operand:SI 1 "nonimmediate_operand" "%0")
6757 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6759 (set (match_operand:DI 0 "register_operand" "=r")
6760 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6761 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6762 "add{l}\t{%2, %k0|%k0, %2}"
6763 [(set_attr "type" "alu")
6764 (set_attr "mode" "SI")])
6766 (define_insn "*add<mode>3_cconly_overflow_2"
6767 [(set (reg:CCC FLAGS_REG)
6770 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6771 (match_operand:SWI 2 "<general_operand>" "<g>"))
6773 (clobber (match_scratch:SWI 0 "=<r>"))]
6774 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6775 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6776 [(set_attr "type" "alu")
6777 (set_attr "mode" "<MODE>")])
6779 (define_insn "*add<mode>3_cc_overflow_2"
6780 [(set (reg:CCC FLAGS_REG)
6783 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6784 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6786 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6787 (plus:SWI (match_dup 1) (match_dup 2)))]
6788 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6789 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6790 [(set_attr "type" "alu")
6791 (set_attr "mode" "<MODE>")])
6793 (define_insn "*addsi3_zext_cc_overflow_2"
6794 [(set (reg:CCC FLAGS_REG)
6797 (match_operand:SI 1 "nonimmediate_operand" "%0")
6798 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6800 (set (match_operand:DI 0 "register_operand" "=r")
6801 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6802 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6803 "add{l}\t{%2, %k0|%k0, %2}"
6804 [(set_attr "type" "alu")
6805 (set_attr "mode" "SI")])
6807 ;; The patterns that match these are at the end of this file.
6809 (define_expand "<plusminus_insn>xf3"
6810 [(set (match_operand:XF 0 "register_operand")
6812 (match_operand:XF 1 "register_operand")
6813 (match_operand:XF 2 "register_operand")))]
6816 (define_expand "<plusminus_insn><mode>3"
6817 [(set (match_operand:MODEF 0 "register_operand")
6819 (match_operand:MODEF 1 "register_operand")
6820 (match_operand:MODEF 2 "nonimmediate_operand")))]
6821 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6822 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6824 ;; Multiply instructions
6826 (define_expand "mul<mode>3"
6827 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6829 (match_operand:SWIM248 1 "register_operand")
6830 (match_operand:SWIM248 2 "<general_operand>")))
6831 (clobber (reg:CC FLAGS_REG))])])
6833 (define_expand "mulqi3"
6834 [(parallel [(set (match_operand:QI 0 "register_operand")
6836 (match_operand:QI 1 "register_operand")
6837 (match_operand:QI 2 "nonimmediate_operand")))
6838 (clobber (reg:CC FLAGS_REG))])]
6839 "TARGET_QIMODE_MATH")
6842 ;; IMUL reg32/64, reg32/64, imm8 Direct
6843 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6844 ;; IMUL reg32/64, reg32/64, imm32 Direct
6845 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6846 ;; IMUL reg32/64, reg32/64 Direct
6847 ;; IMUL reg32/64, mem32/64 Direct
6849 ;; On BDVER1, all above IMULs use DirectPath
6852 ;; IMUL reg16, reg16, imm8 VectorPath
6853 ;; IMUL reg16, mem16, imm8 VectorPath
6854 ;; IMUL reg16, reg16, imm16 VectorPath
6855 ;; IMUL reg16, mem16, imm16 VectorPath
6856 ;; IMUL reg16, reg16 Direct
6857 ;; IMUL reg16, mem16 Direct
6859 ;; On BDVER1, all HI MULs use DoublePath
6861 (define_insn "*mul<mode>3_1"
6862 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
6864 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
6865 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
6866 (clobber (reg:CC FLAGS_REG))]
6867 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6869 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6870 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6871 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6872 [(set_attr "type" "imul")
6873 (set_attr "prefix_0f" "0,0,1")
6874 (set (attr "athlon_decode")
6875 (cond [(eq_attr "cpu" "athlon")
6876 (const_string "vector")
6877 (eq_attr "alternative" "1")
6878 (const_string "vector")
6879 (and (eq_attr "alternative" "2")
6880 (ior (match_test "<MODE>mode == HImode")
6881 (match_operand 1 "memory_operand")))
6882 (const_string "vector")]
6883 (const_string "direct")))
6884 (set (attr "amdfam10_decode")
6885 (cond [(and (eq_attr "alternative" "0,1")
6886 (ior (match_test "<MODE>mode == HImode")
6887 (match_operand 1 "memory_operand")))
6888 (const_string "vector")]
6889 (const_string "direct")))
6890 (set (attr "bdver1_decode")
6892 (match_test "<MODE>mode == HImode")
6893 (const_string "double")
6894 (const_string "direct")))
6895 (set_attr "mode" "<MODE>")])
6897 (define_insn "*mulsi3_1_zext"
6898 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6900 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6901 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6902 (clobber (reg:CC FLAGS_REG))]
6904 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6906 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6907 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6908 imul{l}\t{%2, %k0|%k0, %2}"
6909 [(set_attr "type" "imul")
6910 (set_attr "prefix_0f" "0,0,1")
6911 (set (attr "athlon_decode")
6912 (cond [(eq_attr "cpu" "athlon")
6913 (const_string "vector")
6914 (eq_attr "alternative" "1")
6915 (const_string "vector")
6916 (and (eq_attr "alternative" "2")
6917 (match_operand 1 "memory_operand"))
6918 (const_string "vector")]
6919 (const_string "direct")))
6920 (set (attr "amdfam10_decode")
6921 (cond [(and (eq_attr "alternative" "0,1")
6922 (match_operand 1 "memory_operand"))
6923 (const_string "vector")]
6924 (const_string "direct")))
6925 (set_attr "bdver1_decode" "direct")
6926 (set_attr "mode" "SI")])
6928 ;;On AMDFAM10 and BDVER1
6932 (define_insn "*mulqi3_1"
6933 [(set (match_operand:QI 0 "register_operand" "=a")
6934 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6935 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6936 (clobber (reg:CC FLAGS_REG))]
6938 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6940 [(set_attr "type" "imul")
6941 (set_attr "length_immediate" "0")
6942 (set (attr "athlon_decode")
6943 (if_then_else (eq_attr "cpu" "athlon")
6944 (const_string "vector")
6945 (const_string "direct")))
6946 (set_attr "amdfam10_decode" "direct")
6947 (set_attr "bdver1_decode" "direct")
6948 (set_attr "mode" "QI")])
6950 ;; Multiply with jump on overflow.
6951 (define_expand "mulv<mode>4"
6952 [(parallel [(set (reg:CCO FLAGS_REG)
6955 (match_operand:SWI248 1 "register_operand"))
6958 (mult:SWI248 (match_dup 1)
6959 (match_operand:SWI248 2
6960 "<general_operand>")))))
6961 (set (match_operand:SWI248 0 "register_operand")
6962 (mult:SWI248 (match_dup 1) (match_dup 2)))])
6963 (set (pc) (if_then_else
6964 (eq (reg:CCO FLAGS_REG) (const_int 0))
6965 (label_ref (match_operand 3))
6969 if (CONST_INT_P (operands[2]))
6970 operands[4] = operands[2];
6972 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6975 (define_insn "*mulv<mode>4"
6976 [(set (reg:CCO FLAGS_REG)
6979 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6981 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
6983 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6984 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6985 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6986 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6988 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6989 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6990 [(set_attr "type" "imul")
6991 (set_attr "prefix_0f" "0,1")
6992 (set (attr "athlon_decode")
6993 (cond [(eq_attr "cpu" "athlon")
6994 (const_string "vector")
6995 (eq_attr "alternative" "0")
6996 (const_string "vector")
6997 (and (eq_attr "alternative" "1")
6998 (match_operand 1 "memory_operand"))
6999 (const_string "vector")]
7000 (const_string "direct")))
7001 (set (attr "amdfam10_decode")
7002 (cond [(and (eq_attr "alternative" "1")
7003 (match_operand 1 "memory_operand"))
7004 (const_string "vector")]
7005 (const_string "direct")))
7006 (set_attr "bdver1_decode" "direct")
7007 (set_attr "mode" "<MODE>")])
7009 (define_insn "*mulvhi4"
7010 [(set (reg:CCO FLAGS_REG)
7013 (match_operand:HI 1 "nonimmediate_operand" "%0"))
7015 (match_operand:HI 2 "nonimmediate_operand" "mr")))
7017 (mult:HI (match_dup 1) (match_dup 2)))))
7018 (set (match_operand:HI 0 "register_operand" "=r")
7019 (mult:HI (match_dup 1) (match_dup 2)))]
7020 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7021 "imul{w}\t{%2, %0|%0, %2}"
7022 [(set_attr "type" "imul")
7023 (set_attr "prefix_0f" "1")
7024 (set_attr "athlon_decode" "vector")
7025 (set_attr "amdfam10_decode" "direct")
7026 (set_attr "bdver1_decode" "double")
7027 (set_attr "mode" "HI")])
7029 (define_insn "*mulv<mode>4_1"
7030 [(set (reg:CCO FLAGS_REG)
7033 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7034 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7036 (mult:SWI248 (match_dup 1)
7037 (match_operand:SWI248 2
7038 "<immediate_operand>" "K,<i>")))))
7039 (set (match_operand:SWI248 0 "register_operand" "=r,r")
7040 (mult:SWI248 (match_dup 1) (match_dup 2)))]
7041 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7042 && CONST_INT_P (operands[2])
7043 && INTVAL (operands[2]) == INTVAL (operands[3])"
7044 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7045 [(set_attr "type" "imul")
7046 (set (attr "prefix_0f")
7048 (match_test "<MODE>mode == HImode")
7050 (const_string "*")))
7051 (set (attr "athlon_decode")
7052 (cond [(eq_attr "cpu" "athlon")
7053 (const_string "vector")
7054 (eq_attr "alternative" "1")
7055 (const_string "vector")]
7056 (const_string "direct")))
7057 (set (attr "amdfam10_decode")
7058 (cond [(ior (match_test "<MODE>mode == HImode")
7059 (match_operand 1 "memory_operand"))
7060 (const_string "vector")]
7061 (const_string "direct")))
7062 (set (attr "bdver1_decode")
7064 (match_test "<MODE>mode == HImode")
7065 (const_string "double")
7066 (const_string "direct")))
7067 (set_attr "mode" "<MODE>")
7068 (set (attr "length_immediate")
7069 (cond [(eq_attr "alternative" "0")
7071 (match_test "<MODE_SIZE> == 8")
7073 (const_string "<MODE_SIZE>")))])
7075 (define_expand "umulv<mode>4"
7076 [(parallel [(set (reg:CCO FLAGS_REG)
7079 (match_operand:SWI248 1
7080 "nonimmediate_operand"))
7082 (match_operand:SWI248 2
7083 "nonimmediate_operand")))
7085 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7086 (set (match_operand:SWI248 0 "register_operand")
7087 (mult:SWI248 (match_dup 1) (match_dup 2)))
7088 (clobber (match_scratch:SWI248 4))])
7089 (set (pc) (if_then_else
7090 (eq (reg:CCO FLAGS_REG) (const_int 0))
7091 (label_ref (match_operand 3))
7095 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7096 operands[1] = force_reg (<MODE>mode, operands[1]);
7099 (define_insn "*umulv<mode>4"
7100 [(set (reg:CCO FLAGS_REG)
7103 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7105 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7107 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7108 (set (match_operand:SWI248 0 "register_operand" "=a")
7109 (mult:SWI248 (match_dup 1) (match_dup 2)))
7110 (clobber (match_scratch:SWI248 3 "=d"))]
7111 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7112 "mul{<imodesuffix>}\t%2"
7113 [(set_attr "type" "imul")
7114 (set_attr "length_immediate" "0")
7115 (set (attr "athlon_decode")
7116 (if_then_else (eq_attr "cpu" "athlon")
7117 (const_string "vector")
7118 (const_string "double")))
7119 (set_attr "amdfam10_decode" "double")
7120 (set_attr "bdver1_decode" "direct")
7121 (set_attr "mode" "<MODE>")])
7123 (define_expand "<u>mulvqi4"
7124 [(parallel [(set (reg:CCO FLAGS_REG)
7127 (match_operand:QI 1 "nonimmediate_operand"))
7129 (match_operand:QI 2 "nonimmediate_operand")))
7131 (mult:QI (match_dup 1) (match_dup 2)))))
7132 (set (match_operand:QI 0 "register_operand")
7133 (mult:QI (match_dup 1) (match_dup 2)))])
7134 (set (pc) (if_then_else
7135 (eq (reg:CCO FLAGS_REG) (const_int 0))
7136 (label_ref (match_operand 3))
7138 "TARGET_QIMODE_MATH"
7140 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7141 operands[1] = force_reg (QImode, operands[1]);
7144 (define_insn "*<u>mulvqi4"
7145 [(set (reg:CCO FLAGS_REG)
7148 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7150 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7152 (mult:QI (match_dup 1) (match_dup 2)))))
7153 (set (match_operand:QI 0 "register_operand" "=a")
7154 (mult:QI (match_dup 1) (match_dup 2)))]
7156 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7157 "<sgnprefix>mul{b}\t%2"
7158 [(set_attr "type" "imul")
7159 (set_attr "length_immediate" "0")
7160 (set (attr "athlon_decode")
7161 (if_then_else (eq_attr "cpu" "athlon")
7162 (const_string "vector")
7163 (const_string "direct")))
7164 (set_attr "amdfam10_decode" "direct")
7165 (set_attr "bdver1_decode" "direct")
7166 (set_attr "mode" "QI")])
7168 (define_expand "<u>mul<mode><dwi>3"
7169 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7172 (match_operand:DWIH 1 "nonimmediate_operand"))
7174 (match_operand:DWIH 2 "register_operand"))))
7175 (clobber (reg:CC FLAGS_REG))])])
7177 (define_expand "<u>mulqihi3"
7178 [(parallel [(set (match_operand:HI 0 "register_operand")
7181 (match_operand:QI 1 "nonimmediate_operand"))
7183 (match_operand:QI 2 "register_operand"))))
7184 (clobber (reg:CC FLAGS_REG))])]
7185 "TARGET_QIMODE_MATH")
7187 (define_insn "*bmi2_umul<mode><dwi>3_1"
7188 [(set (match_operand:DWIH 0 "register_operand" "=r")
7190 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7191 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7192 (set (match_operand:DWIH 1 "register_operand" "=r")
7195 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7196 (zero_extend:<DWI> (match_dup 3)))
7197 (match_operand:QI 4 "const_int_operand" "n"))))]
7198 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7199 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7200 "mulx\t{%3, %0, %1|%1, %0, %3}"
7201 [(set_attr "type" "imulx")
7202 (set_attr "prefix" "vex")
7203 (set_attr "mode" "<MODE>")])
7205 (define_insn "*umul<mode><dwi>3_1"
7206 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7209 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7211 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7212 (clobber (reg:CC FLAGS_REG))]
7213 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7216 mul{<imodesuffix>}\t%2"
7217 [(set_attr "isa" "bmi2,*")
7218 (set_attr "type" "imulx,imul")
7219 (set_attr "length_immediate" "*,0")
7220 (set (attr "athlon_decode")
7221 (cond [(eq_attr "alternative" "1")
7222 (if_then_else (eq_attr "cpu" "athlon")
7223 (const_string "vector")
7224 (const_string "double"))]
7225 (const_string "*")))
7226 (set_attr "amdfam10_decode" "*,double")
7227 (set_attr "bdver1_decode" "*,direct")
7228 (set_attr "prefix" "vex,orig")
7229 (set_attr "mode" "<MODE>")])
7231 ;; Convert mul to the mulx pattern to avoid flags dependency.
7233 [(set (match_operand:<DWI> 0 "register_operand")
7236 (match_operand:DWIH 1 "register_operand"))
7238 (match_operand:DWIH 2 "nonimmediate_operand"))))
7239 (clobber (reg:CC FLAGS_REG))]
7240 "TARGET_BMI2 && reload_completed
7241 && REGNO (operands[1]) == DX_REG"
7242 [(parallel [(set (match_dup 3)
7243 (mult:DWIH (match_dup 1) (match_dup 2)))
7247 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7248 (zero_extend:<DWI> (match_dup 2)))
7251 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7253 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7256 (define_insn "*mul<mode><dwi>3_1"
7257 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7260 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7262 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7263 (clobber (reg:CC FLAGS_REG))]
7264 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7265 "imul{<imodesuffix>}\t%2"
7266 [(set_attr "type" "imul")
7267 (set_attr "length_immediate" "0")
7268 (set (attr "athlon_decode")
7269 (if_then_else (eq_attr "cpu" "athlon")
7270 (const_string "vector")
7271 (const_string "double")))
7272 (set_attr "amdfam10_decode" "double")
7273 (set_attr "bdver1_decode" "direct")
7274 (set_attr "mode" "<MODE>")])
7276 (define_insn "*<u>mulqihi3_1"
7277 [(set (match_operand:HI 0 "register_operand" "=a")
7280 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7282 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7283 (clobber (reg:CC FLAGS_REG))]
7285 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7286 "<sgnprefix>mul{b}\t%2"
7287 [(set_attr "type" "imul")
7288 (set_attr "length_immediate" "0")
7289 (set (attr "athlon_decode")
7290 (if_then_else (eq_attr "cpu" "athlon")
7291 (const_string "vector")
7292 (const_string "direct")))
7293 (set_attr "amdfam10_decode" "direct")
7294 (set_attr "bdver1_decode" "direct")
7295 (set_attr "mode" "QI")])
7297 (define_expand "<s>mul<mode>3_highpart"
7298 [(parallel [(set (match_operand:SWI48 0 "register_operand")
7303 (match_operand:SWI48 1 "nonimmediate_operand"))
7305 (match_operand:SWI48 2 "register_operand")))
7307 (clobber (match_scratch:SWI48 3))
7308 (clobber (reg:CC FLAGS_REG))])]
7310 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7312 (define_insn "*<s>muldi3_highpart_1"
7313 [(set (match_operand:DI 0 "register_operand" "=d")
7318 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7320 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7322 (clobber (match_scratch:DI 3 "=1"))
7323 (clobber (reg:CC FLAGS_REG))]
7325 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7326 "<sgnprefix>mul{q}\t%2"
7327 [(set_attr "type" "imul")
7328 (set_attr "length_immediate" "0")
7329 (set (attr "athlon_decode")
7330 (if_then_else (eq_attr "cpu" "athlon")
7331 (const_string "vector")
7332 (const_string "double")))
7333 (set_attr "amdfam10_decode" "double")
7334 (set_attr "bdver1_decode" "direct")
7335 (set_attr "mode" "DI")])
7337 (define_insn "*<s>mulsi3_highpart_zext"
7338 [(set (match_operand:DI 0 "register_operand" "=d")
7339 (zero_extend:DI (truncate:SI
7341 (mult:DI (any_extend:DI
7342 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7344 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7346 (clobber (match_scratch:SI 3 "=1"))
7347 (clobber (reg:CC FLAGS_REG))]
7349 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7350 "<sgnprefix>mul{l}\t%2"
7351 [(set_attr "type" "imul")
7352 (set_attr "length_immediate" "0")
7353 (set (attr "athlon_decode")
7354 (if_then_else (eq_attr "cpu" "athlon")
7355 (const_string "vector")
7356 (const_string "double")))
7357 (set_attr "amdfam10_decode" "double")
7358 (set_attr "bdver1_decode" "direct")
7359 (set_attr "mode" "SI")])
7361 (define_insn "*<s>mulsi3_highpart_1"
7362 [(set (match_operand:SI 0 "register_operand" "=d")
7367 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7369 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7371 (clobber (match_scratch:SI 3 "=1"))
7372 (clobber (reg:CC FLAGS_REG))]
7373 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7374 "<sgnprefix>mul{l}\t%2"
7375 [(set_attr "type" "imul")
7376 (set_attr "length_immediate" "0")
7377 (set (attr "athlon_decode")
7378 (if_then_else (eq_attr "cpu" "athlon")
7379 (const_string "vector")
7380 (const_string "double")))
7381 (set_attr "amdfam10_decode" "double")
7382 (set_attr "bdver1_decode" "direct")
7383 (set_attr "mode" "SI")])
7385 ;; The patterns that match these are at the end of this file.
7387 (define_expand "mulxf3"
7388 [(set (match_operand:XF 0 "register_operand")
7389 (mult:XF (match_operand:XF 1 "register_operand")
7390 (match_operand:XF 2 "register_operand")))]
7393 (define_expand "mul<mode>3"
7394 [(set (match_operand:MODEF 0 "register_operand")
7395 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7396 (match_operand:MODEF 2 "nonimmediate_operand")))]
7397 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7398 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7400 ;; Divide instructions
7402 ;; The patterns that match these are at the end of this file.
7404 (define_expand "divxf3"
7405 [(set (match_operand:XF 0 "register_operand")
7406 (div:XF (match_operand:XF 1 "register_operand")
7407 (match_operand:XF 2 "register_operand")))]
7410 (define_expand "divdf3"
7411 [(set (match_operand:DF 0 "register_operand")
7412 (div:DF (match_operand:DF 1 "register_operand")
7413 (match_operand:DF 2 "nonimmediate_operand")))]
7414 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7415 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7417 (define_expand "divsf3"
7418 [(set (match_operand:SF 0 "register_operand")
7419 (div:SF (match_operand:SF 1 "register_operand")
7420 (match_operand:SF 2 "nonimmediate_operand")))]
7421 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7426 && optimize_insn_for_speed_p ()
7427 && flag_finite_math_only && !flag_trapping_math
7428 && flag_unsafe_math_optimizations)
7430 ix86_emit_swdivsf (operands[0], operands[1],
7431 operands[2], SFmode);
7436 ;; Divmod instructions.
7438 (define_expand "divmod<mode>4"
7439 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7441 (match_operand:SWIM248 1 "register_operand")
7442 (match_operand:SWIM248 2 "nonimmediate_operand")))
7443 (set (match_operand:SWIM248 3 "register_operand")
7444 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7445 (clobber (reg:CC FLAGS_REG))])])
7447 ;; Split with 8bit unsigned divide:
7448 ;; if (dividend an divisor are in [0-255])
7449 ;; use 8bit unsigned integer divide
7451 ;; use original integer divide
7453 [(set (match_operand:SWI48 0 "register_operand")
7454 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7455 (match_operand:SWI48 3 "nonimmediate_operand")))
7456 (set (match_operand:SWI48 1 "register_operand")
7457 (mod:SWI48 (match_dup 2) (match_dup 3)))
7458 (clobber (reg:CC FLAGS_REG))]
7459 "TARGET_USE_8BIT_IDIV
7460 && TARGET_QIMODE_MATH
7461 && can_create_pseudo_p ()
7462 && !optimize_insn_for_size_p ()"
7464 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7466 (define_insn_and_split "divmod<mode>4_1"
7467 [(set (match_operand:SWI48 0 "register_operand" "=a")
7468 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7469 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7470 (set (match_operand:SWI48 1 "register_operand" "=&d")
7471 (mod:SWI48 (match_dup 2) (match_dup 3)))
7472 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7473 (clobber (reg:CC FLAGS_REG))]
7477 [(parallel [(set (match_dup 1)
7478 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7479 (clobber (reg:CC FLAGS_REG))])
7480 (parallel [(set (match_dup 0)
7481 (div:SWI48 (match_dup 2) (match_dup 3)))
7483 (mod:SWI48 (match_dup 2) (match_dup 3)))
7485 (clobber (reg:CC FLAGS_REG))])]
7487 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7489 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7490 operands[4] = operands[2];
7493 /* Avoid use of cltd in favor of a mov+shift. */
7494 emit_move_insn (operands[1], operands[2]);
7495 operands[4] = operands[1];
7498 [(set_attr "type" "multi")
7499 (set_attr "mode" "<MODE>")])
7501 (define_insn_and_split "*divmod<mode>4"
7502 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7503 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7504 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7505 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7506 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7507 (clobber (reg:CC FLAGS_REG))]
7511 [(parallel [(set (match_dup 1)
7512 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7513 (clobber (reg:CC FLAGS_REG))])
7514 (parallel [(set (match_dup 0)
7515 (div:SWIM248 (match_dup 2) (match_dup 3)))
7517 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7519 (clobber (reg:CC FLAGS_REG))])]
7521 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7523 if (<MODE>mode != HImode
7524 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7525 operands[4] = operands[2];
7528 /* Avoid use of cltd in favor of a mov+shift. */
7529 emit_move_insn (operands[1], operands[2]);
7530 operands[4] = operands[1];
7533 [(set_attr "type" "multi")
7534 (set_attr "mode" "<MODE>")])
7536 (define_insn "*divmod<mode>4_noext"
7537 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7538 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7539 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7540 (set (match_operand:SWIM248 1 "register_operand" "=d")
7541 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7542 (use (match_operand:SWIM248 4 "register_operand" "1"))
7543 (clobber (reg:CC FLAGS_REG))]
7545 "idiv{<imodesuffix>}\t%3"
7546 [(set_attr "type" "idiv")
7547 (set_attr "mode" "<MODE>")])
7549 (define_expand "divmodqi4"
7550 [(parallel [(set (match_operand:QI 0 "register_operand")
7552 (match_operand:QI 1 "register_operand")
7553 (match_operand:QI 2 "nonimmediate_operand")))
7554 (set (match_operand:QI 3 "register_operand")
7555 (mod:QI (match_dup 1) (match_dup 2)))
7556 (clobber (reg:CC FLAGS_REG))])]
7557 "TARGET_QIMODE_MATH"
7562 tmp0 = gen_reg_rtx (HImode);
7563 tmp1 = gen_reg_rtx (HImode);
7565 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
7566 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7567 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7569 /* Extract remainder from AH. */
7570 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7571 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
7572 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7574 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7575 set_unique_reg_note (insn, REG_EQUAL, mod);
7577 /* Extract quotient from AL. */
7578 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7580 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7581 set_unique_reg_note (insn, REG_EQUAL, div);
7586 ;; Divide AX by r/m8, with result stored in
7589 ;; Change div/mod to HImode and extend the second argument to HImode
7590 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7591 ;; combine may fail.
7592 (define_insn "divmodhiqi3"
7593 [(set (match_operand:HI 0 "register_operand" "=a")
7598 (mod:HI (match_operand:HI 1 "register_operand" "0")
7600 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7604 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7605 (clobber (reg:CC FLAGS_REG))]
7606 "TARGET_QIMODE_MATH"
7608 [(set_attr "type" "idiv")
7609 (set_attr "mode" "QI")])
7611 (define_expand "udivmod<mode>4"
7612 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7614 (match_operand:SWIM248 1 "register_operand")
7615 (match_operand:SWIM248 2 "nonimmediate_operand")))
7616 (set (match_operand:SWIM248 3 "register_operand")
7617 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7618 (clobber (reg:CC FLAGS_REG))])])
7620 ;; Split with 8bit unsigned divide:
7621 ;; if (dividend an divisor are in [0-255])
7622 ;; use 8bit unsigned integer divide
7624 ;; use original integer divide
7626 [(set (match_operand:SWI48 0 "register_operand")
7627 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7628 (match_operand:SWI48 3 "nonimmediate_operand")))
7629 (set (match_operand:SWI48 1 "register_operand")
7630 (umod:SWI48 (match_dup 2) (match_dup 3)))
7631 (clobber (reg:CC FLAGS_REG))]
7632 "TARGET_USE_8BIT_IDIV
7633 && TARGET_QIMODE_MATH
7634 && can_create_pseudo_p ()
7635 && !optimize_insn_for_size_p ()"
7637 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7639 (define_insn_and_split "udivmod<mode>4_1"
7640 [(set (match_operand:SWI48 0 "register_operand" "=a")
7641 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7642 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7643 (set (match_operand:SWI48 1 "register_operand" "=&d")
7644 (umod:SWI48 (match_dup 2) (match_dup 3)))
7645 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7646 (clobber (reg:CC FLAGS_REG))]
7650 [(set (match_dup 1) (const_int 0))
7651 (parallel [(set (match_dup 0)
7652 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7654 (umod:SWI48 (match_dup 2) (match_dup 3)))
7656 (clobber (reg:CC FLAGS_REG))])]
7658 [(set_attr "type" "multi")
7659 (set_attr "mode" "<MODE>")])
7661 (define_insn_and_split "*udivmod<mode>4"
7662 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7663 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7664 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7665 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7666 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7667 (clobber (reg:CC FLAGS_REG))]
7671 [(set (match_dup 1) (const_int 0))
7672 (parallel [(set (match_dup 0)
7673 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7675 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7677 (clobber (reg:CC FLAGS_REG))])]
7679 [(set_attr "type" "multi")
7680 (set_attr "mode" "<MODE>")])
7682 ;; Optimize division or modulo by constant power of 2, if the constant
7683 ;; materializes only after expansion.
7684 (define_insn_and_split "*udivmod<mode>4_pow2"
7685 [(set (match_operand:SWI48 0 "register_operand" "=r")
7686 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7687 (match_operand:SWI48 3 "const_int_operand" "n")))
7688 (set (match_operand:SWI48 1 "register_operand" "=r")
7689 (umod:SWI48 (match_dup 2) (match_dup 3)))
7690 (clobber (reg:CC FLAGS_REG))]
7691 "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
7692 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
7695 [(set (match_dup 1) (match_dup 2))
7696 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7697 (clobber (reg:CC FLAGS_REG))])
7698 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7699 (clobber (reg:CC FLAGS_REG))])]
7701 int v = exact_log2 (UINTVAL (operands[3]));
7702 operands[4] = GEN_INT (v);
7703 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7705 [(set_attr "type" "multi")
7706 (set_attr "mode" "<MODE>")])
7708 (define_insn "*udivmod<mode>4_noext"
7709 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7710 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7711 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7712 (set (match_operand:SWIM248 1 "register_operand" "=d")
7713 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7714 (use (match_operand:SWIM248 4 "register_operand" "1"))
7715 (clobber (reg:CC FLAGS_REG))]
7717 "div{<imodesuffix>}\t%3"
7718 [(set_attr "type" "idiv")
7719 (set_attr "mode" "<MODE>")])
7721 (define_expand "udivmodqi4"
7722 [(parallel [(set (match_operand:QI 0 "register_operand")
7724 (match_operand:QI 1 "register_operand")
7725 (match_operand:QI 2 "nonimmediate_operand")))
7726 (set (match_operand:QI 3 "register_operand")
7727 (umod:QI (match_dup 1) (match_dup 2)))
7728 (clobber (reg:CC FLAGS_REG))])]
7729 "TARGET_QIMODE_MATH"
7734 tmp0 = gen_reg_rtx (HImode);
7735 tmp1 = gen_reg_rtx (HImode);
7737 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
7738 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7739 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7741 /* Extract remainder from AH. */
7742 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7743 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
7744 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7746 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7747 set_unique_reg_note (insn, REG_EQUAL, mod);
7749 /* Extract quotient from AL. */
7750 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7752 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7753 set_unique_reg_note (insn, REG_EQUAL, div);
7758 (define_insn "udivmodhiqi3"
7759 [(set (match_operand:HI 0 "register_operand" "=a")
7764 (mod:HI (match_operand:HI 1 "register_operand" "0")
7766 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7770 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7771 (clobber (reg:CC FLAGS_REG))]
7772 "TARGET_QIMODE_MATH"
7774 [(set_attr "type" "idiv")
7775 (set_attr "mode" "QI")])
7777 ;; We cannot use div/idiv for double division, because it causes
7778 ;; "division by zero" on the overflow and that's not what we expect
7779 ;; from truncate. Because true (non truncating) double division is
7780 ;; never generated, we can't create this insn anyway.
7783 ; [(set (match_operand:SI 0 "register_operand" "=a")
7785 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7787 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7788 ; (set (match_operand:SI 3 "register_operand" "=d")
7790 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7791 ; (clobber (reg:CC FLAGS_REG))]
7793 ; "div{l}\t{%2, %0|%0, %2}"
7794 ; [(set_attr "type" "idiv")])
7796 ;;- Logical AND instructions
7798 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7799 ;; Note that this excludes ah.
7801 (define_expand "testsi_ccno_1"
7802 [(set (reg:CCNO FLAGS_REG)
7804 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7805 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7808 (define_expand "testqi_ccz_1"
7809 [(set (reg:CCZ FLAGS_REG)
7810 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7811 (match_operand:QI 1 "nonmemory_operand"))
7814 (define_expand "testdi_ccno_1"
7815 [(set (reg:CCNO FLAGS_REG)
7817 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7818 (match_operand:DI 1 "x86_64_szext_general_operand"))
7820 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7822 (define_insn "*testdi_1"
7823 [(set (reg FLAGS_REG)
7826 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7827 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7829 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7830 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7832 test{l}\t{%k1, %k0|%k0, %k1}
7833 test{l}\t{%k1, %k0|%k0, %k1}
7834 test{q}\t{%1, %0|%0, %1}
7835 test{q}\t{%1, %0|%0, %1}
7836 test{q}\t{%1, %0|%0, %1}"
7837 [(set_attr "type" "test")
7838 (set_attr "modrm" "0,1,0,1,1")
7839 (set_attr "mode" "SI,SI,DI,DI,DI")])
7841 (define_insn "*testqi_1_maybe_si"
7842 [(set (reg FLAGS_REG)
7845 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7846 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7848 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7849 && ix86_match_ccmode (insn,
7850 CONST_INT_P (operands[1])
7851 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7853 if (which_alternative == 3)
7855 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7856 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7857 return "test{l}\t{%1, %k0|%k0, %1}";
7859 return "test{b}\t{%1, %0|%0, %1}";
7861 [(set_attr "type" "test")
7862 (set_attr "modrm" "0,1,1,1")
7863 (set_attr "mode" "QI,QI,QI,SI")
7864 (set_attr "pent_pair" "uv,np,uv,np")])
7866 (define_insn "*test<mode>_1"
7867 [(set (reg FLAGS_REG)
7870 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7871 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7873 "ix86_match_ccmode (insn, CCNOmode)
7874 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7875 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7876 [(set_attr "type" "test")
7877 (set_attr "modrm" "0,1,1")
7878 (set_attr "mode" "<MODE>")
7879 (set_attr "pent_pair" "uv,np,uv")])
7881 (define_expand "testqi_ext_1_ccno"
7882 [(set (reg:CCNO FLAGS_REG)
7886 (zero_extract:SI (match_operand 0 "ext_register_operand")
7889 (match_operand 1 "const_int_operand"))
7892 (define_insn "*testqi_ext_1"
7893 [(set (reg FLAGS_REG)
7897 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q,Q")
7900 (match_operand:QI 1 "general_operand" "QnBc,m"))
7902 "ix86_match_ccmode (insn, CCNOmode)"
7903 "test{b}\t{%1, %h0|%h0, %1}"
7904 [(set_attr "isa" "*,nox64")
7905 (set_attr "type" "test")
7906 (set_attr "mode" "QI")])
7908 (define_insn "*testqi_ext_2"
7909 [(set (reg FLAGS_REG)
7913 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q")
7917 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
7921 "ix86_match_ccmode (insn, CCNOmode)"
7922 "test{b}\t{%h1, %h0|%h0, %h1}"
7923 [(set_attr "type" "test")
7924 (set_attr "mode" "QI")])
7926 ;; Combine likes to form bit extractions for some tests. Humor it.
7927 (define_insn_and_split "*testqi_ext_3"
7928 [(set (match_operand 0 "flags_reg_operand")
7929 (match_operator 1 "compare_operator"
7930 [(zero_extract:SWI248
7931 (match_operand 2 "nonimmediate_operand" "rm")
7932 (match_operand 3 "const_int_operand" "n")
7933 (match_operand 4 "const_int_operand" "n"))
7935 "ix86_match_ccmode (insn, CCNOmode)
7936 && ((TARGET_64BIT && GET_MODE (operands[2]) == DImode)
7937 || GET_MODE (operands[2]) == SImode
7938 || GET_MODE (operands[2]) == HImode
7939 || GET_MODE (operands[2]) == QImode)
7940 /* Ensure that resulting mask is zero or sign extended operand. */
7941 && INTVAL (operands[4]) >= 0
7942 && ((INTVAL (operands[3]) > 0
7943 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
7944 || (<MODE>mode == DImode
7945 && INTVAL (operands[3]) > 32
7946 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))"
7949 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7951 rtx val = operands[2];
7952 HOST_WIDE_INT len = INTVAL (operands[3]);
7953 HOST_WIDE_INT pos = INTVAL (operands[4]);
7954 machine_mode mode, submode;
7956 mode = GET_MODE (val);
7959 /* ??? Combine likes to put non-volatile mem extractions in QImode
7960 no matter the size of the test. So find a mode that works. */
7961 if (! MEM_VOLATILE_P (val))
7963 mode = smallest_mode_for_size (pos + len, MODE_INT);
7964 val = adjust_address (val, mode, 0);
7967 else if (SUBREG_P (val)
7968 && (submode = GET_MODE (SUBREG_REG (val)),
7969 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7970 && pos + len <= GET_MODE_BITSIZE (submode)
7971 && GET_MODE_CLASS (submode) == MODE_INT)
7973 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7975 val = SUBREG_REG (val);
7977 else if (mode == HImode && pos + len <= 8)
7979 /* Small HImode tests can be converted to QImode. */
7981 val = gen_lowpart (QImode, val);
7985 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
7987 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
7990 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7991 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7992 ;; this is relatively important trick.
7993 ;; Do the conversion only post-reload to avoid limiting of the register class
7996 [(set (match_operand 0 "flags_reg_operand")
7997 (match_operator 1 "compare_operator"
7998 [(and (match_operand 2 "QIreg_operand")
7999 (match_operand 3 "const_int_operand"))
8002 && GET_MODE (operands[2]) != QImode
8003 && ((ix86_match_ccmode (insn, CCZmode)
8004 && !(INTVAL (operands[3]) & ~(255 << 8)))
8005 || (ix86_match_ccmode (insn, CCNOmode)
8006 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8011 (zero_extract:SI (match_dup 2)
8017 operands[2] = gen_lowpart (SImode, operands[2]);
8018 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
8022 [(set (match_operand 0 "flags_reg_operand")
8023 (match_operator 1 "compare_operator"
8024 [(and (match_operand 2 "nonimmediate_operand")
8025 (match_operand 3 "const_int_operand"))
8028 && GET_MODE (operands[2]) != QImode
8029 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8030 && ((ix86_match_ccmode (insn, CCZmode)
8031 && !(INTVAL (operands[3]) & ~255))
8032 || (ix86_match_ccmode (insn, CCNOmode)
8033 && !(INTVAL (operands[3]) & ~127)))"
8035 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8038 operands[2] = gen_lowpart (QImode, operands[2]);
8039 operands[3] = gen_lowpart (QImode, operands[3]);
8042 ;; %%% This used to optimize known byte-wide and operations to memory,
8043 ;; and sometimes to QImode registers. If this is considered useful,
8044 ;; it should be done with splitters.
8046 (define_expand "and<mode>3"
8047 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8048 (and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8049 (match_operand:SWIM1248x 2 "<general_szext_operand>")))]
8052 machine_mode mode = <MODE>mode;
8053 rtx (*insn) (rtx, rtx);
8055 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
8057 HOST_WIDE_INT ival = INTVAL (operands[2]);
8059 if (ival == (HOST_WIDE_INT) 0xffffffff)
8061 else if (ival == 0xffff)
8063 else if (ival == 0xff)
8067 if (mode == <MODE>mode)
8069 ix86_expand_binary_operator (AND, <MODE>mode, operands);
8073 if (<MODE>mode == DImode)
8074 insn = (mode == SImode)
8075 ? gen_zero_extendsidi2
8077 ? gen_zero_extendhidi2
8078 : gen_zero_extendqidi2;
8079 else if (<MODE>mode == SImode)
8080 insn = (mode == HImode)
8081 ? gen_zero_extendhisi2
8082 : gen_zero_extendqisi2;
8083 else if (<MODE>mode == HImode)
8084 insn = gen_zero_extendqihi2;
8088 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8092 (define_insn_and_split "*anddi3_doubleword"
8093 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8095 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8096 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8097 (clobber (reg:CC FLAGS_REG))]
8098 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8099 && ix86_binary_operator_ok (AND, DImode, operands)"
8101 "&& reload_completed"
8104 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8105 if (operands[2] == const0_rtx)
8107 operands[1] = const0_rtx;
8108 ix86_expand_move (SImode, &operands[0]);
8110 else if (operands[2] != constm1_rtx)
8111 ix86_expand_binary_operator (AND, SImode, &operands[0]);
8112 else if (operands[5] == constm1_rtx)
8113 emit_note (NOTE_INSN_DELETED);
8114 if (operands[5] == const0_rtx)
8116 operands[4] = const0_rtx;
8117 ix86_expand_move (SImode, &operands[3]);
8119 else if (operands[5] != constm1_rtx)
8120 ix86_expand_binary_operator (AND, SImode, &operands[3]);
8124 (define_insn "*anddi_1"
8125 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8127 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8128 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8129 (clobber (reg:CC FLAGS_REG))]
8130 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8132 and{l}\t{%k2, %k0|%k0, %k2}
8133 and{q}\t{%2, %0|%0, %2}
8134 and{q}\t{%2, %0|%0, %2}
8136 [(set_attr "type" "alu,alu,alu,imovx")
8137 (set_attr "length_immediate" "*,*,*,0")
8138 (set (attr "prefix_rex")
8140 (and (eq_attr "type" "imovx")
8141 (and (match_test "INTVAL (operands[2]) == 0xff")
8142 (match_operand 1 "ext_QIreg_operand")))
8144 (const_string "*")))
8145 (set_attr "mode" "SI,DI,DI,SI")])
8147 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8149 [(set (match_operand:DI 0 "register_operand")
8150 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8151 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8152 (clobber (reg:CC FLAGS_REG))]
8154 [(parallel [(set (match_dup 0)
8155 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8156 (clobber (reg:CC FLAGS_REG))])]
8157 "operands[2] = gen_lowpart (SImode, operands[2]);")
8159 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8160 (define_insn "*andsi_1_zext"
8161 [(set (match_operand:DI 0 "register_operand" "=r")
8163 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8164 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8165 (clobber (reg:CC FLAGS_REG))]
8166 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8167 "and{l}\t{%2, %k0|%k0, %2}"
8168 [(set_attr "type" "alu")
8169 (set_attr "mode" "SI")])
8171 (define_insn "*and<mode>_1"
8172 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya")
8173 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm")
8174 (match_operand:SWI24 2 "<general_operand>" "r<i>,rm,L")))
8175 (clobber (reg:CC FLAGS_REG))]
8176 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8178 and{<imodesuffix>}\t{%2, %0|%0, %2}
8179 and{<imodesuffix>}\t{%2, %0|%0, %2}
8181 [(set_attr "type" "alu,alu,imovx")
8182 (set_attr "length_immediate" "*,*,0")
8183 (set (attr "prefix_rex")
8185 (and (eq_attr "type" "imovx")
8186 (and (match_test "INTVAL (operands[2]) == 0xff")
8187 (match_operand 1 "ext_QIreg_operand")))
8189 (const_string "*")))
8190 (set_attr "mode" "<MODE>,<MODE>,SI")])
8192 (define_insn "*andqi_1"
8193 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8194 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8195 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8196 (clobber (reg:CC FLAGS_REG))]
8197 "ix86_binary_operator_ok (AND, QImode, operands)"
8199 and{b}\t{%2, %0|%0, %2}
8200 and{b}\t{%2, %0|%0, %2}
8201 and{l}\t{%k2, %k0|%k0, %k2}"
8202 [(set_attr "type" "alu")
8203 (set_attr "mode" "QI,QI,SI")
8204 ;; Potential partial reg stall on alternative 2.
8205 (set (attr "preferred_for_speed")
8206 (cond [(eq_attr "alternative" "2")
8207 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8208 (symbol_ref "true")))])
8210 (define_insn "*andqi_1_slp"
8211 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8212 (and:QI (match_dup 0)
8213 (match_operand:QI 1 "general_operand" "qn,qmn")))
8214 (clobber (reg:CC FLAGS_REG))]
8215 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8216 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8217 "and{b}\t{%1, %0|%0, %1}"
8218 [(set_attr "type" "alu1")
8219 (set_attr "mode" "QI")])
8222 [(set (match_operand:SWI248 0 "register_operand")
8223 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8224 (match_operand:SWI248 2 "const_int_operand")))
8225 (clobber (reg:CC FLAGS_REG))]
8227 && (!REG_P (operands[1])
8228 || REGNO (operands[0]) != REGNO (operands[1]))"
8231 HOST_WIDE_INT ival = INTVAL (operands[2]);
8233 rtx (*insn) (rtx, rtx);
8235 if (ival == (HOST_WIDE_INT) 0xffffffff)
8237 else if (ival == 0xffff)
8241 gcc_assert (ival == 0xff);
8245 if (<MODE>mode == DImode)
8246 insn = (mode == SImode)
8247 ? gen_zero_extendsidi2
8249 ? gen_zero_extendhidi2
8250 : gen_zero_extendqidi2;
8253 if (<MODE>mode != SImode)
8254 /* Zero extend to SImode to avoid partial register stalls. */
8255 operands[0] = gen_lowpart (SImode, operands[0]);
8257 insn = (mode == HImode)
8258 ? gen_zero_extendhisi2
8259 : gen_zero_extendqisi2;
8261 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8266 [(set (match_operand:SWI48 0 "register_operand")
8267 (and:SWI48 (match_dup 0)
8268 (const_int -65536)))
8269 (clobber (reg:CC FLAGS_REG))]
8270 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8271 || optimize_function_for_size_p (cfun)"
8272 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8273 "operands[1] = gen_lowpart (HImode, operands[0]);")
8276 [(set (match_operand:SWI248 0 "any_QIreg_operand")
8277 (and:SWI248 (match_dup 0)
8279 (clobber (reg:CC FLAGS_REG))]
8280 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8281 && reload_completed"
8282 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8283 "operands[1] = gen_lowpart (QImode, operands[0]);")
8286 [(set (match_operand:SWI248 0 "QIreg_operand")
8287 (and:SWI248 (match_dup 0)
8288 (const_int -65281)))
8289 (clobber (reg:CC FLAGS_REG))]
8290 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8291 && reload_completed"
8293 [(set (zero_extract:SI (match_dup 0)
8299 (zero_extract:SI (match_dup 0)
8303 (zero_extract:SI (match_dup 0)
8305 (const_int 8)) 0)) 0))
8306 (clobber (reg:CC FLAGS_REG))])]
8307 "operands[0] = gen_lowpart (SImode, operands[0]);")
8309 (define_insn "*anddi_2"
8310 [(set (reg FLAGS_REG)
8313 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8314 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8316 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8317 (and:DI (match_dup 1) (match_dup 2)))]
8319 && ix86_match_ccmode
8321 /* If we are going to emit andl instead of andq, and the operands[2]
8322 constant might have the SImode sign bit set, make sure the sign
8323 flag isn't tested, because the instruction will set the sign flag
8324 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8325 conservatively assume it might have bit 31 set. */
8326 (satisfies_constraint_Z (operands[2])
8327 && (!CONST_INT_P (operands[2])
8328 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8329 ? CCZmode : CCNOmode)
8330 && ix86_binary_operator_ok (AND, DImode, operands)"
8332 and{l}\t{%k2, %k0|%k0, %k2}
8333 and{q}\t{%2, %0|%0, %2}
8334 and{q}\t{%2, %0|%0, %2}"
8335 [(set_attr "type" "alu")
8336 (set_attr "mode" "SI,DI,DI")])
8338 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8339 (define_insn "*andsi_2_zext"
8340 [(set (reg FLAGS_REG)
8342 (match_operand:SI 1 "nonimmediate_operand" "%0")
8343 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8345 (set (match_operand:DI 0 "register_operand" "=r")
8346 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8347 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8348 && ix86_binary_operator_ok (AND, SImode, operands)"
8349 "and{l}\t{%2, %k0|%k0, %2}"
8350 [(set_attr "type" "alu")
8351 (set_attr "mode" "SI")])
8353 (define_insn "*andqi_2_maybe_si"
8354 [(set (reg FLAGS_REG)
8356 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8357 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8359 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8360 (and:QI (match_dup 1) (match_dup 2)))]
8361 "ix86_binary_operator_ok (AND, QImode, operands)
8362 && ix86_match_ccmode (insn,
8363 CONST_INT_P (operands[2])
8364 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8366 if (which_alternative == 2)
8368 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8369 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8370 return "and{l}\t{%2, %k0|%k0, %2}";
8372 return "and{b}\t{%2, %0|%0, %2}";
8374 [(set_attr "type" "alu")
8375 (set_attr "mode" "QI,QI,SI")])
8377 (define_insn "*and<mode>_2"
8378 [(set (reg FLAGS_REG)
8379 (compare (and:SWI124
8380 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8381 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8383 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8384 (and:SWI124 (match_dup 1) (match_dup 2)))]
8385 "ix86_match_ccmode (insn, CCNOmode)
8386 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8387 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8388 [(set_attr "type" "alu")
8389 (set_attr "mode" "<MODE>")])
8391 (define_insn "*andqi_2_slp"
8392 [(set (reg FLAGS_REG)
8394 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8395 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8397 (set (strict_low_part (match_dup 0))
8398 (and:QI (match_dup 0) (match_dup 1)))]
8399 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8400 && ix86_match_ccmode (insn, CCNOmode)
8401 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8402 "and{b}\t{%1, %0|%0, %1}"
8403 [(set_attr "type" "alu1")
8404 (set_attr "mode" "QI")])
8406 (define_insn "andqi_ext_1"
8407 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8413 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
8416 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
8417 (clobber (reg:CC FLAGS_REG))]
8419 "and{b}\t{%2, %h0|%h0, %2}"
8420 [(set_attr "isa" "*,nox64")
8421 (set_attr "type" "alu")
8422 (set_attr "mode" "QI")])
8424 ;; Generated by peephole translating test to and. This shows up
8425 ;; often in fp comparisons.
8426 (define_insn "*andqi_ext_1_cc"
8427 [(set (reg FLAGS_REG)
8431 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
8434 (match_operand:QI 2 "general_operand" "QnBc,m"))
8436 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8442 (zero_extract:SI (match_dup 1)
8446 "ix86_match_ccmode (insn, CCNOmode)"
8447 "and{b}\t{%2, %h0|%h0, %2}"
8448 [(set_attr "isa" "*,nox64")
8449 (set_attr "type" "alu")
8450 (set_attr "mode" "QI")])
8452 (define_insn "*andqi_ext_2"
8453 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8459 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
8463 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8465 (const_int 8)) 0)) 0))
8466 (clobber (reg:CC FLAGS_REG))]
8468 "and{b}\t{%h2, %h0|%h0, %h2}"
8469 [(set_attr "type" "alu")
8470 (set_attr "mode" "QI")])
8472 ;; Convert wide AND instructions with immediate operand to shorter QImode
8473 ;; equivalents when possible.
8474 ;; Don't do the splitting with memory operands, since it introduces risk
8475 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8476 ;; for size, but that can (should?) be handled by generic code instead.
8478 [(set (match_operand:SWI248 0 "QIreg_operand")
8479 (and:SWI248 (match_operand:SWI248 1 "register_operand")
8480 (match_operand:SWI248 2 "const_int_operand")))
8481 (clobber (reg:CC FLAGS_REG))]
8483 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8484 && !(~INTVAL (operands[2]) & ~(255 << 8))"
8486 [(set (zero_extract:SI (match_dup 0)
8492 (zero_extract:SI (match_dup 1)
8496 (clobber (reg:CC FLAGS_REG))])]
8498 operands[0] = gen_lowpart (SImode, operands[0]);
8499 operands[1] = gen_lowpart (SImode, operands[1]);
8500 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
8503 ;; Since AND can be encoded with sign extended immediate, this is only
8504 ;; profitable when 7th bit is not set.
8506 [(set (match_operand:SWI248 0 "any_QIreg_operand")
8507 (and:SWI248 (match_operand:SWI248 1 "general_operand")
8508 (match_operand:SWI248 2 "const_int_operand")))
8509 (clobber (reg:CC FLAGS_REG))]
8511 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8512 && !(~INTVAL (operands[2]) & ~255)
8513 && !(INTVAL (operands[2]) & 128)"
8514 [(parallel [(set (strict_low_part (match_dup 0))
8515 (and:QI (match_dup 1)
8517 (clobber (reg:CC FLAGS_REG))])]
8519 operands[0] = gen_lowpart (QImode, operands[0]);
8520 operands[1] = gen_lowpart (QImode, operands[1]);
8521 operands[2] = gen_lowpart (QImode, operands[2]);
8524 (define_insn "*andndi3_doubleword"
8525 [(set (match_operand:DI 0 "register_operand" "=r,&r")
8527 (not:DI (match_operand:DI 1 "register_operand" "r,0"))
8528 (match_operand:DI 2 "nonimmediate_operand" "rm,rm")))
8529 (clobber (reg:CC FLAGS_REG))]
8530 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
8532 [(set_attr "isa" "bmi,*")])
8535 [(set (match_operand:DI 0 "register_operand")
8537 (not:DI (match_operand:DI 1 "register_operand"))
8538 (match_operand:DI 2 "nonimmediate_operand")))
8539 (clobber (reg:CC FLAGS_REG))]
8540 "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2
8541 && reload_completed"
8542 [(parallel [(set (match_dup 0)
8543 (and:SI (not:SI (match_dup 1)) (match_dup 2)))
8544 (clobber (reg:CC FLAGS_REG))])
8545 (parallel [(set (match_dup 3)
8546 (and:SI (not:SI (match_dup 4)) (match_dup 5)))
8547 (clobber (reg:CC FLAGS_REG))])]
8548 "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
8551 [(set (match_operand:DI 0 "register_operand")
8553 (not:DI (match_dup 0))
8554 (match_operand:DI 1 "nonimmediate_operand")))
8555 (clobber (reg:CC FLAGS_REG))]
8556 "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2
8557 && reload_completed"
8558 [(set (match_dup 0) (not:SI (match_dup 0)))
8559 (parallel [(set (match_dup 0)
8560 (and:SI (match_dup 0) (match_dup 1)))
8561 (clobber (reg:CC FLAGS_REG))])
8562 (set (match_dup 2) (not:SI (match_dup 2)))
8563 (parallel [(set (match_dup 2)
8564 (and:SI (match_dup 2) (match_dup 3)))
8565 (clobber (reg:CC FLAGS_REG))])]
8566 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
8568 (define_insn "*andn<mode>_1"
8569 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
8571 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
8572 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
8573 (clobber (reg:CC FLAGS_REG))]
8575 "andn\t{%2, %1, %0|%0, %1, %2}"
8576 [(set_attr "type" "bitmanip")
8577 (set_attr "btver2_decode" "direct, double")
8578 (set_attr "mode" "<MODE>")])
8580 (define_insn "*andn<mode>_1"
8581 [(set (match_operand:SWI12 0 "register_operand" "=r")
8583 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r"))
8584 (match_operand:SWI12 2 "register_operand" "r")))
8585 (clobber (reg:CC FLAGS_REG))]
8587 "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}"
8588 [(set_attr "type" "bitmanip")
8589 (set_attr "btver2_decode" "direct")
8590 (set_attr "mode" "SI")])
8592 (define_insn "*andn_<mode>_ccno"
8593 [(set (reg FLAGS_REG)
8596 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
8597 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
8599 (clobber (match_scratch:SWI48 0 "=r,r"))]
8600 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
8601 "andn\t{%2, %1, %0|%0, %1, %2}"
8602 [(set_attr "type" "bitmanip")
8603 (set_attr "btver2_decode" "direct, double")
8604 (set_attr "mode" "<MODE>")])
8606 ;; Logical inclusive and exclusive OR instructions
8608 ;; %%% This used to optimize known byte-wide and operations to memory.
8609 ;; If this is considered useful, it should be done with splitters.
8611 (define_expand "<code><mode>3"
8612 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8613 (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8614 (match_operand:SWIM1248x 2 "<general_operand>")))]
8616 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8618 (define_insn_and_split "*<code>di3_doubleword"
8619 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8621 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8622 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8623 (clobber (reg:CC FLAGS_REG))]
8624 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8625 && ix86_binary_operator_ok (<CODE>, DImode, operands)"
8627 "&& reload_completed"
8630 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8631 if (operands[2] == constm1_rtx)
8635 operands[1] = constm1_rtx;
8636 ix86_expand_move (SImode, &operands[0]);
8639 ix86_expand_unary_operator (NOT, SImode, &operands[0]);
8641 else if (operands[2] != const0_rtx)
8642 ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
8643 else if (operands[5] == const0_rtx)
8644 emit_note (NOTE_INSN_DELETED);
8645 if (operands[5] == constm1_rtx)
8649 operands[4] = constm1_rtx;
8650 ix86_expand_move (SImode, &operands[3]);
8653 ix86_expand_unary_operator (NOT, SImode, &operands[3]);
8655 else if (operands[5] != const0_rtx)
8656 ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
8660 (define_insn "*<code><mode>_1"
8661 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8663 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8664 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8665 (clobber (reg:CC FLAGS_REG))]
8666 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8667 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8668 [(set_attr "type" "alu")
8669 (set_attr "mode" "<MODE>")])
8671 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8672 (define_insn "*<code>si_1_zext"
8673 [(set (match_operand:DI 0 "register_operand" "=r")
8675 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8676 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8677 (clobber (reg:CC FLAGS_REG))]
8678 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8679 "<logic>{l}\t{%2, %k0|%k0, %2}"
8680 [(set_attr "type" "alu")
8681 (set_attr "mode" "SI")])
8683 (define_insn "*<code>si_1_zext_imm"
8684 [(set (match_operand:DI 0 "register_operand" "=r")
8686 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8687 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8688 (clobber (reg:CC FLAGS_REG))]
8689 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8690 "<logic>{l}\t{%2, %k0|%k0, %2}"
8691 [(set_attr "type" "alu")
8692 (set_attr "mode" "SI")])
8694 (define_insn "*<code>qi_1"
8695 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8696 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8697 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8698 (clobber (reg:CC FLAGS_REG))]
8699 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8701 <logic>{b}\t{%2, %0|%0, %2}
8702 <logic>{b}\t{%2, %0|%0, %2}
8703 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8704 [(set_attr "type" "alu")
8705 (set_attr "mode" "QI,QI,SI")
8706 ;; Potential partial reg stall on alternative 2.
8707 (set (attr "preferred_for_speed")
8708 (cond [(eq_attr "alternative" "2")
8709 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8710 (symbol_ref "true")))])
8712 (define_insn "*<code>qi_1_slp"
8713 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8714 (any_or:QI (match_dup 0)
8715 (match_operand:QI 1 "general_operand" "qmn,qn")))
8716 (clobber (reg:CC FLAGS_REG))]
8717 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8718 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8719 "<logic>{b}\t{%1, %0|%0, %1}"
8720 [(set_attr "type" "alu1")
8721 (set_attr "mode" "QI")])
8723 (define_insn "*<code><mode>_2"
8724 [(set (reg FLAGS_REG)
8725 (compare (any_or:SWI
8726 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8727 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8729 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8730 (any_or:SWI (match_dup 1) (match_dup 2)))]
8731 "ix86_match_ccmode (insn, CCNOmode)
8732 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8733 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8734 [(set_attr "type" "alu")
8735 (set_attr "mode" "<MODE>")])
8737 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8738 ;; ??? Special case for immediate operand is missing - it is tricky.
8739 (define_insn "*<code>si_2_zext"
8740 [(set (reg FLAGS_REG)
8741 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8742 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8744 (set (match_operand:DI 0 "register_operand" "=r")
8745 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8746 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8747 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8748 "<logic>{l}\t{%2, %k0|%k0, %2}"
8749 [(set_attr "type" "alu")
8750 (set_attr "mode" "SI")])
8752 (define_insn "*<code>si_2_zext_imm"
8753 [(set (reg FLAGS_REG)
8755 (match_operand:SI 1 "nonimmediate_operand" "%0")
8756 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8758 (set (match_operand:DI 0 "register_operand" "=r")
8759 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8760 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8761 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8762 "<logic>{l}\t{%2, %k0|%k0, %2}"
8763 [(set_attr "type" "alu")
8764 (set_attr "mode" "SI")])
8766 (define_insn "*<code>qi_2_slp"
8767 [(set (reg FLAGS_REG)
8768 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8769 (match_operand:QI 1 "general_operand" "qmn,qn"))
8771 (set (strict_low_part (match_dup 0))
8772 (any_or:QI (match_dup 0) (match_dup 1)))]
8773 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8774 && ix86_match_ccmode (insn, CCNOmode)
8775 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8776 "<logic>{b}\t{%1, %0|%0, %1}"
8777 [(set_attr "type" "alu1")
8778 (set_attr "mode" "QI")])
8780 (define_insn "*<code><mode>_3"
8781 [(set (reg FLAGS_REG)
8782 (compare (any_or:SWI
8783 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8784 (match_operand:SWI 2 "<general_operand>" "<g>"))
8786 (clobber (match_scratch:SWI 0 "=<r>"))]
8787 "ix86_match_ccmode (insn, CCNOmode)
8788 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8789 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8790 [(set_attr "type" "alu")
8791 (set_attr "mode" "<MODE>")])
8793 (define_insn "*<code>qi_ext_1"
8794 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8800 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
8803 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
8804 (clobber (reg:CC FLAGS_REG))]
8805 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8806 "<logic>{b}\t{%2, %h0|%h0, %2}"
8807 [(set_attr "isa" "*,nox64")
8808 (set_attr "type" "alu")
8809 (set_attr "mode" "QI")])
8811 (define_insn "*<code>qi_ext_2"
8812 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8818 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
8822 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8824 (const_int 8)) 0)) 0))
8825 (clobber (reg:CC FLAGS_REG))]
8826 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8827 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8828 [(set_attr "type" "alu")
8829 (set_attr "mode" "QI")])
8831 ;; Convert wide OR instructions with immediate operand to shorter QImode
8832 ;; equivalents when possible.
8833 ;; Don't do the splitting with memory operands, since it introduces risk
8834 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8835 ;; for size, but that can (should?) be handled by generic code instead.
8837 [(set (match_operand:SWI248 0 "QIreg_operand")
8838 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
8839 (match_operand:SWI248 2 "const_int_operand")))
8840 (clobber (reg:CC FLAGS_REG))]
8842 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8843 && !(INTVAL (operands[2]) & ~(255 << 8))"
8845 [(set (zero_extract:SI (match_dup 0)
8851 (zero_extract:SI (match_dup 1)
8855 (clobber (reg:CC FLAGS_REG))])]
8857 operands[0] = gen_lowpart (SImode, operands[0]);
8858 operands[1] = gen_lowpart (SImode, operands[1]);
8859 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
8862 ;; Since OR can be encoded with sign extended immediate, this is only
8863 ;; profitable when 7th bit is set.
8865 [(set (match_operand:SWI248 0 "any_QIreg_operand")
8866 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
8867 (match_operand:SWI248 2 "const_int_operand")))
8868 (clobber (reg:CC FLAGS_REG))]
8870 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8871 && !(INTVAL (operands[2]) & ~255)
8872 && (INTVAL (operands[2]) & 128)"
8873 [(parallel [(set (strict_low_part (match_dup 0))
8874 (any_or:QI (match_dup 1)
8876 (clobber (reg:CC FLAGS_REG))])]
8878 operands[0] = gen_lowpart (QImode, operands[0]);
8879 operands[1] = gen_lowpart (QImode, operands[1]);
8880 operands[2] = gen_lowpart (QImode, operands[2]);
8883 (define_expand "xorqi_ext_1_cc"
8885 (set (reg:CCNO FLAGS_REG)
8889 (zero_extract:SI (match_operand 1 "ext_register_operand")
8892 (match_operand 2 "const_int_operand"))
8894 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8900 (zero_extract:SI (match_dup 1)
8903 (match_dup 2)) 0))])])
8905 (define_insn "*xorqi_ext_1_cc"
8906 [(set (reg FLAGS_REG)
8910 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
8913 (match_operand:QI 2 "general_operand" "QnBc,m"))
8915 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8921 (zero_extract:SI (match_dup 1)
8925 "ix86_match_ccmode (insn, CCNOmode)"
8926 "xor{b}\t{%2, %h0|%h0, %2}"
8927 [(set_attr "isa" "*,nox64")
8928 (set_attr "type" "alu")
8929 (set_attr "mode" "QI")])
8931 ;; Negation instructions
8933 (define_expand "neg<mode>2"
8934 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8935 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8937 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8939 (define_insn_and_split "*neg<dwi>2_doubleword"
8940 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8941 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8942 (clobber (reg:CC FLAGS_REG))]
8943 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8947 [(set (reg:CCZ FLAGS_REG)
8948 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8949 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8952 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8955 (clobber (reg:CC FLAGS_REG))])
8958 (neg:DWIH (match_dup 2)))
8959 (clobber (reg:CC FLAGS_REG))])]
8960 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8962 (define_insn "*neg<mode>2_1"
8963 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8964 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8965 (clobber (reg:CC FLAGS_REG))]
8966 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8967 "neg{<imodesuffix>}\t%0"
8968 [(set_attr "type" "negnot")
8969 (set_attr "mode" "<MODE>")])
8971 ;; Combine is quite creative about this pattern.
8972 (define_insn "*negsi2_1_zext"
8973 [(set (match_operand:DI 0 "register_operand" "=r")
8975 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8978 (clobber (reg:CC FLAGS_REG))]
8979 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8981 [(set_attr "type" "negnot")
8982 (set_attr "mode" "SI")])
8984 ;; The problem with neg is that it does not perform (compare x 0),
8985 ;; it really performs (compare 0 x), which leaves us with the zero
8986 ;; flag being the only useful item.
8988 (define_insn "*neg<mode>2_cmpz"
8989 [(set (reg:CCZ FLAGS_REG)
8991 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8993 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8994 (neg:SWI (match_dup 1)))]
8995 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8996 "neg{<imodesuffix>}\t%0"
8997 [(set_attr "type" "negnot")
8998 (set_attr "mode" "<MODE>")])
9000 (define_insn "*negsi2_cmpz_zext"
9001 [(set (reg:CCZ FLAGS_REG)
9005 (match_operand:DI 1 "register_operand" "0")
9009 (set (match_operand:DI 0 "register_operand" "=r")
9010 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9013 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9015 [(set_attr "type" "negnot")
9016 (set_attr "mode" "SI")])
9018 ;; Negate with jump on overflow.
9019 (define_expand "negv<mode>3"
9020 [(parallel [(set (reg:CCO FLAGS_REG)
9021 (ne:CCO (match_operand:SWI 1 "register_operand")
9023 (set (match_operand:SWI 0 "register_operand")
9024 (neg:SWI (match_dup 1)))])
9025 (set (pc) (if_then_else
9026 (eq (reg:CCO FLAGS_REG) (const_int 0))
9027 (label_ref (match_operand 2))
9032 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
9036 (define_insn "*negv<mode>3"
9037 [(set (reg:CCO FLAGS_REG)
9038 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
9039 (match_operand:SWI 2 "const_int_operand")))
9040 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9041 (neg:SWI (match_dup 1)))]
9042 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
9043 && mode_signbit_p (<MODE>mode, operands[2])"
9044 "neg{<imodesuffix>}\t%0"
9045 [(set_attr "type" "negnot")
9046 (set_attr "mode" "<MODE>")])
9048 ;; Changing of sign for FP values is doable using integer unit too.
9050 (define_expand "<code><mode>2"
9051 [(set (match_operand:X87MODEF 0 "register_operand")
9052 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
9053 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9054 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9056 (define_insn "*absneg<mode>2"
9057 [(set (match_operand:MODEF 0 "register_operand" "=Yv,Yv,f,!r")
9058 (match_operator:MODEF 3 "absneg_operator"
9059 [(match_operand:MODEF 1 "register_operand" "0,Yv,0,0")]))
9060 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "Yvm,0,X,X"))
9061 (clobber (reg:CC FLAGS_REG))]
9062 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9064 [(set (attr "enabled")
9066 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
9068 (eq_attr "alternative" "2")
9069 (symbol_ref "TARGET_MIX_SSE_I387")
9070 (symbol_ref "true"))
9072 (eq_attr "alternative" "2,3")
9074 (symbol_ref "false"))))])
9076 (define_insn "*absnegxf2_i387"
9077 [(set (match_operand:XF 0 "register_operand" "=f,!r")
9078 (match_operator:XF 3 "absneg_operator"
9079 [(match_operand:XF 1 "register_operand" "0,0")]))
9080 (use (match_operand 2))
9081 (clobber (reg:CC FLAGS_REG))]
9085 (define_expand "<code>tf2"
9086 [(set (match_operand:TF 0 "register_operand")
9087 (absneg:TF (match_operand:TF 1 "register_operand")))]
9089 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9091 (define_insn "*absnegtf2_sse"
9092 [(set (match_operand:TF 0 "register_operand" "=Yv,Yv")
9093 (match_operator:TF 3 "absneg_operator"
9094 [(match_operand:TF 1 "register_operand" "0,Yv")]))
9095 (use (match_operand:TF 2 "nonimmediate_operand" "Yvm,0"))
9096 (clobber (reg:CC FLAGS_REG))]
9100 ;; Splitters for fp abs and neg.
9103 [(set (match_operand 0 "fp_register_operand")
9104 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9105 (use (match_operand 2))
9106 (clobber (reg:CC FLAGS_REG))]
9108 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9111 [(set (match_operand 0 "sse_reg_operand")
9112 (match_operator 3 "absneg_operator"
9113 [(match_operand 1 "register_operand")]))
9114 (use (match_operand 2 "nonimmediate_operand"))
9115 (clobber (reg:CC FLAGS_REG))]
9117 [(set (match_dup 0) (match_dup 3))]
9119 machine_mode mode = GET_MODE (operands[0]);
9120 machine_mode vmode = GET_MODE (operands[2]);
9123 operands[0] = lowpart_subreg (vmode, operands[0], mode);
9124 operands[1] = lowpart_subreg (vmode, operands[1], mode);
9125 if (operands_match_p (operands[0], operands[2]))
9126 std::swap (operands[1], operands[2]);
9127 if (GET_CODE (operands[3]) == ABS)
9128 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9130 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9135 [(set (match_operand:SF 0 "general_reg_operand")
9136 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9137 (use (match_operand:V4SF 2))
9138 (clobber (reg:CC FLAGS_REG))]
9140 [(parallel [(set (match_dup 0) (match_dup 1))
9141 (clobber (reg:CC FLAGS_REG))])]
9144 operands[0] = gen_lowpart (SImode, operands[0]);
9145 if (GET_CODE (operands[1]) == ABS)
9147 tmp = gen_int_mode (0x7fffffff, SImode);
9148 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9152 tmp = gen_int_mode (0x80000000, SImode);
9153 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9159 [(set (match_operand:DF 0 "general_reg_operand")
9160 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9161 (use (match_operand 2))
9162 (clobber (reg:CC FLAGS_REG))]
9164 [(parallel [(set (match_dup 0) (match_dup 1))
9165 (clobber (reg:CC FLAGS_REG))])]
9170 tmp = gen_lowpart (DImode, operands[0]);
9171 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9174 if (GET_CODE (operands[1]) == ABS)
9177 tmp = gen_rtx_NOT (DImode, tmp);
9181 operands[0] = gen_highpart (SImode, operands[0]);
9182 if (GET_CODE (operands[1]) == ABS)
9184 tmp = gen_int_mode (0x7fffffff, SImode);
9185 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9189 tmp = gen_int_mode (0x80000000, SImode);
9190 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9197 [(set (match_operand:XF 0 "general_reg_operand")
9198 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9199 (use (match_operand 2))
9200 (clobber (reg:CC FLAGS_REG))]
9202 [(parallel [(set (match_dup 0) (match_dup 1))
9203 (clobber (reg:CC FLAGS_REG))])]
9206 operands[0] = gen_rtx_REG (SImode,
9207 REGNO (operands[0]) + (TARGET_64BIT ? 1 : 2));
9208 if (GET_CODE (operands[1]) == ABS)
9210 tmp = GEN_INT (0x7fff);
9211 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9215 tmp = GEN_INT (0x8000);
9216 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9221 ;; Conditionalize these after reload. If they match before reload, we
9222 ;; lose the clobber and ability to use integer instructions.
9224 (define_insn "*<code><mode>2_1"
9225 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9226 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9228 && (reload_completed
9229 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9230 "f<absneg_mnemonic>"
9231 [(set_attr "type" "fsgn")
9232 (set_attr "mode" "<MODE>")])
9234 (define_insn "*<code>extendsfdf2"
9235 [(set (match_operand:DF 0 "register_operand" "=f")
9236 (absneg:DF (float_extend:DF
9237 (match_operand:SF 1 "register_operand" "0"))))]
9238 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9239 "f<absneg_mnemonic>"
9240 [(set_attr "type" "fsgn")
9241 (set_attr "mode" "DF")])
9243 (define_insn "*<code>extendsfxf2"
9244 [(set (match_operand:XF 0 "register_operand" "=f")
9245 (absneg:XF (float_extend:XF
9246 (match_operand:SF 1 "register_operand" "0"))))]
9248 "f<absneg_mnemonic>"
9249 [(set_attr "type" "fsgn")
9250 (set_attr "mode" "XF")])
9252 (define_insn "*<code>extenddfxf2"
9253 [(set (match_operand:XF 0 "register_operand" "=f")
9254 (absneg:XF (float_extend:XF
9255 (match_operand:DF 1 "register_operand" "0"))))]
9257 "f<absneg_mnemonic>"
9258 [(set_attr "type" "fsgn")
9259 (set_attr "mode" "XF")])
9261 ;; Copysign instructions
9263 (define_mode_iterator CSGNMODE [SF DF TF])
9264 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9266 (define_expand "copysign<mode>3"
9267 [(match_operand:CSGNMODE 0 "register_operand")
9268 (match_operand:CSGNMODE 1 "nonmemory_operand")
9269 (match_operand:CSGNMODE 2 "register_operand")]
9270 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9271 || (TARGET_SSE && (<MODE>mode == TFmode))"
9272 "ix86_expand_copysign (operands); DONE;")
9274 (define_insn_and_split "copysign<mode>3_const"
9275 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv")
9277 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "YvmC")
9278 (match_operand:CSGNMODE 2 "register_operand" "0")
9279 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "Yvm")]
9281 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9282 || (TARGET_SSE && (<MODE>mode == TFmode))"
9284 "&& reload_completed"
9286 "ix86_split_copysign_const (operands); DONE;")
9288 (define_insn "copysign<mode>3_var"
9289 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
9291 [(match_operand:CSGNMODE 2 "register_operand" "Yv,0,0,Yv,Yv")
9292 (match_operand:CSGNMODE 3 "register_operand" "1,1,Yv,1,Yv")
9293 (match_operand:<CSGNVMODE> 4
9294 "nonimmediate_operand" "X,Yvm,Yvm,0,0")
9295 (match_operand:<CSGNVMODE> 5
9296 "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
9298 (clobber (match_scratch:<CSGNVMODE> 1 "=Yv,Yv,Yv,Yv,Yv"))]
9299 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9300 || (TARGET_SSE && (<MODE>mode == TFmode))"
9304 [(set (match_operand:CSGNMODE 0 "register_operand")
9306 [(match_operand:CSGNMODE 2 "register_operand")
9307 (match_operand:CSGNMODE 3 "register_operand")
9308 (match_operand:<CSGNVMODE> 4)
9309 (match_operand:<CSGNVMODE> 5)]
9311 (clobber (match_scratch:<CSGNVMODE> 1))]
9312 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9313 || (TARGET_SSE && (<MODE>mode == TFmode)))
9314 && reload_completed"
9316 "ix86_split_copysign_var (operands); DONE;")
9318 ;; One complement instructions
9320 (define_expand "one_cmpl<mode>2"
9321 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
9322 (not:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")))]
9324 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9326 (define_insn_and_split "*one_cmpldi2_doubleword"
9327 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9328 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9329 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9330 && ix86_unary_operator_ok (NOT, DImode, operands)"
9332 "&& reload_completed"
9334 (not:SI (match_dup 1)))
9336 (not:SI (match_dup 3)))]
9337 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
9339 (define_insn "*one_cmpl<mode>2_1"
9340 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9341 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9342 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9343 "not{<imodesuffix>}\t%0"
9344 [(set_attr "type" "negnot")
9345 (set_attr "mode" "<MODE>")])
9347 ;; ??? Currently never generated - xor is used instead.
9348 (define_insn "*one_cmplsi2_1_zext"
9349 [(set (match_operand:DI 0 "register_operand" "=r")
9351 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9352 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9354 [(set_attr "type" "negnot")
9355 (set_attr "mode" "SI")])
9357 (define_insn "*one_cmplqi2_1"
9358 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9359 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9360 "ix86_unary_operator_ok (NOT, QImode, operands)"
9364 [(set_attr "type" "negnot")
9365 (set_attr "mode" "QI,SI")
9366 ;; Potential partial reg stall on alternative 1.
9367 (set (attr "preferred_for_speed")
9368 (cond [(eq_attr "alternative" "1")
9369 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9370 (symbol_ref "true")))])
9372 (define_insn "*one_cmpl<mode>2_2"
9373 [(set (reg FLAGS_REG)
9374 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9376 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9377 (not:SWI (match_dup 1)))]
9378 "ix86_match_ccmode (insn, CCNOmode)
9379 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9381 [(set_attr "type" "alu1")
9382 (set_attr "mode" "<MODE>")])
9385 [(set (match_operand 0 "flags_reg_operand")
9386 (match_operator 2 "compare_operator"
9387 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9389 (set (match_operand:SWI 1 "nonimmediate_operand")
9390 (not:SWI (match_dup 3)))]
9391 "ix86_match_ccmode (insn, CCNOmode)"
9392 [(parallel [(set (match_dup 0)
9393 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9396 (xor:SWI (match_dup 3) (const_int -1)))])])
9398 ;; ??? Currently never generated - xor is used instead.
9399 (define_insn "*one_cmplsi2_2_zext"
9400 [(set (reg FLAGS_REG)
9401 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9403 (set (match_operand:DI 0 "register_operand" "=r")
9404 (zero_extend:DI (not:SI (match_dup 1))))]
9405 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9406 && ix86_unary_operator_ok (NOT, SImode, operands)"
9408 [(set_attr "type" "alu1")
9409 (set_attr "mode" "SI")])
9412 [(set (match_operand 0 "flags_reg_operand")
9413 (match_operator 2 "compare_operator"
9414 [(not:SI (match_operand:SI 3 "register_operand"))
9416 (set (match_operand:DI 1 "register_operand")
9417 (zero_extend:DI (not:SI (match_dup 3))))]
9418 "ix86_match_ccmode (insn, CCNOmode)"
9419 [(parallel [(set (match_dup 0)
9420 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9423 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9425 ;; Shift instructions
9427 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9428 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9429 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9430 ;; from the assembler input.
9432 ;; This instruction shifts the target reg/mem as usual, but instead of
9433 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9434 ;; is a left shift double, bits are taken from the high order bits of
9435 ;; reg, else if the insn is a shift right double, bits are taken from the
9436 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9437 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9439 ;; Since sh[lr]d does not change the `reg' operand, that is done
9440 ;; separately, making all shifts emit pairs of shift double and normal
9441 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9442 ;; support a 63 bit shift, each shift where the count is in a reg expands
9443 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9445 ;; If the shift count is a constant, we need never emit more than one
9446 ;; shift pair, instead using moves and sign extension for counts greater
9449 (define_expand "ashl<mode>3"
9450 [(set (match_operand:SDWIM 0 "<shift_operand>")
9451 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9452 (match_operand:QI 2 "nonmemory_operand")))]
9454 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9456 (define_insn "*ashl<mode>3_doubleword"
9457 [(set (match_operand:DWI 0 "register_operand" "=&r")
9458 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
9459 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9460 (clobber (reg:CC FLAGS_REG))]
9463 [(set_attr "type" "multi")])
9466 [(set (match_operand:DWI 0 "register_operand")
9467 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9468 (match_operand:QI 2 "nonmemory_operand")))
9469 (clobber (reg:CC FLAGS_REG))]
9470 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9472 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9474 ;; By default we don't ask for a scratch register, because when DWImode
9475 ;; values are manipulated, registers are already at a premium. But if
9476 ;; we have one handy, we won't turn it away.
9479 [(match_scratch:DWIH 3 "r")
9480 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9482 (match_operand:<DWI> 1 "nonmemory_operand")
9483 (match_operand:QI 2 "nonmemory_operand")))
9484 (clobber (reg:CC FLAGS_REG))])
9488 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9490 (define_insn "x86_64_shld"
9491 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9492 (ior:DI (ashift:DI (match_dup 0)
9493 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9494 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9495 (minus:QI (const_int 64) (match_dup 2)))))
9496 (clobber (reg:CC FLAGS_REG))]
9498 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9499 [(set_attr "type" "ishift")
9500 (set_attr "prefix_0f" "1")
9501 (set_attr "mode" "DI")
9502 (set_attr "athlon_decode" "vector")
9503 (set_attr "amdfam10_decode" "vector")
9504 (set_attr "bdver1_decode" "vector")])
9506 (define_insn "x86_shld"
9507 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9508 (ior:SI (ashift:SI (match_dup 0)
9509 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9510 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9511 (minus:QI (const_int 32) (match_dup 2)))))
9512 (clobber (reg:CC FLAGS_REG))]
9514 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9515 [(set_attr "type" "ishift")
9516 (set_attr "prefix_0f" "1")
9517 (set_attr "mode" "SI")
9518 (set_attr "pent_pair" "np")
9519 (set_attr "athlon_decode" "vector")
9520 (set_attr "amdfam10_decode" "vector")
9521 (set_attr "bdver1_decode" "vector")])
9523 (define_expand "x86_shift<mode>_adj_1"
9524 [(set (reg:CCZ FLAGS_REG)
9525 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9528 (set (match_operand:SWI48 0 "register_operand")
9529 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9530 (match_operand:SWI48 1 "register_operand")
9533 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9534 (match_operand:SWI48 3 "register_operand")
9537 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9539 (define_expand "x86_shift<mode>_adj_2"
9540 [(use (match_operand:SWI48 0 "register_operand"))
9541 (use (match_operand:SWI48 1 "register_operand"))
9542 (use (match_operand:QI 2 "register_operand"))]
9545 rtx_code_label *label = gen_label_rtx ();
9548 emit_insn (gen_testqi_ccz_1 (operands[2],
9549 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9551 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9552 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9553 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9554 gen_rtx_LABEL_REF (VOIDmode, label),
9556 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
9557 JUMP_LABEL (tmp) = label;
9559 emit_move_insn (operands[0], operands[1]);
9560 ix86_expand_clear (operands[1]);
9563 LABEL_NUSES (label) = 1;
9568 ;; Avoid useless masking of count operand.
9569 (define_insn_and_split "*ashl<mode>3_mask"
9570 [(set (match_operand:SWI48 0 "nonimmediate_operand")
9572 (match_operand:SWI48 1 "nonimmediate_operand")
9575 (match_operand:SI 2 "register_operand")
9576 (match_operand:SI 3 "const_int_operand")) 0)))
9577 (clobber (reg:CC FLAGS_REG))]
9578 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9579 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9580 == GET_MODE_BITSIZE (<MODE>mode)-1
9581 && can_create_pseudo_p ()"
9586 (ashift:SWI48 (match_dup 1)
9588 (clobber (reg:CC FLAGS_REG))])]
9589 "operands[2] = gen_lowpart (QImode, operands[2]);")
9591 (define_insn "*bmi2_ashl<mode>3_1"
9592 [(set (match_operand:SWI48 0 "register_operand" "=r")
9593 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9594 (match_operand:SWI48 2 "register_operand" "r")))]
9596 "shlx\t{%2, %1, %0|%0, %1, %2}"
9597 [(set_attr "type" "ishiftx")
9598 (set_attr "mode" "<MODE>")])
9600 (define_insn "*ashl<mode>3_1"
9601 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9602 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9603 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9604 (clobber (reg:CC FLAGS_REG))]
9605 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9607 switch (get_attr_type (insn))
9614 gcc_assert (operands[2] == const1_rtx);
9615 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9616 return "add{<imodesuffix>}\t%0, %0";
9619 if (operands[2] == const1_rtx
9620 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9621 return "sal{<imodesuffix>}\t%0";
9623 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9626 [(set_attr "isa" "*,*,bmi2")
9628 (cond [(eq_attr "alternative" "1")
9629 (const_string "lea")
9630 (eq_attr "alternative" "2")
9631 (const_string "ishiftx")
9632 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9633 (match_operand 0 "register_operand"))
9634 (match_operand 2 "const1_operand"))
9635 (const_string "alu")
9637 (const_string "ishift")))
9638 (set (attr "length_immediate")
9640 (ior (eq_attr "type" "alu")
9641 (and (eq_attr "type" "ishift")
9642 (and (match_operand 2 "const1_operand")
9643 (ior (match_test "TARGET_SHIFT1")
9644 (match_test "optimize_function_for_size_p (cfun)")))))
9646 (const_string "*")))
9647 (set_attr "mode" "<MODE>")])
9649 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9651 [(set (match_operand:SWI48 0 "register_operand")
9652 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9653 (match_operand:QI 2 "register_operand")))
9654 (clobber (reg:CC FLAGS_REG))]
9655 "TARGET_BMI2 && reload_completed"
9657 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9658 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9660 (define_insn "*bmi2_ashlsi3_1_zext"
9661 [(set (match_operand:DI 0 "register_operand" "=r")
9663 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9664 (match_operand:SI 2 "register_operand" "r"))))]
9665 "TARGET_64BIT && TARGET_BMI2"
9666 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9667 [(set_attr "type" "ishiftx")
9668 (set_attr "mode" "SI")])
9670 (define_insn "*ashlsi3_1_zext"
9671 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9673 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9674 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9675 (clobber (reg:CC FLAGS_REG))]
9676 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9678 switch (get_attr_type (insn))
9685 gcc_assert (operands[2] == const1_rtx);
9686 return "add{l}\t%k0, %k0";
9689 if (operands[2] == const1_rtx
9690 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9691 return "sal{l}\t%k0";
9693 return "sal{l}\t{%2, %k0|%k0, %2}";
9696 [(set_attr "isa" "*,*,bmi2")
9698 (cond [(eq_attr "alternative" "1")
9699 (const_string "lea")
9700 (eq_attr "alternative" "2")
9701 (const_string "ishiftx")
9702 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9703 (match_operand 2 "const1_operand"))
9704 (const_string "alu")
9706 (const_string "ishift")))
9707 (set (attr "length_immediate")
9709 (ior (eq_attr "type" "alu")
9710 (and (eq_attr "type" "ishift")
9711 (and (match_operand 2 "const1_operand")
9712 (ior (match_test "TARGET_SHIFT1")
9713 (match_test "optimize_function_for_size_p (cfun)")))))
9715 (const_string "*")))
9716 (set_attr "mode" "SI")])
9718 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9720 [(set (match_operand:DI 0 "register_operand")
9722 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9723 (match_operand:QI 2 "register_operand"))))
9724 (clobber (reg:CC FLAGS_REG))]
9725 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9727 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9728 "operands[2] = gen_lowpart (SImode, operands[2]);")
9730 (define_insn "*ashlhi3_1"
9731 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9732 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9733 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9734 (clobber (reg:CC FLAGS_REG))]
9735 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9737 switch (get_attr_type (insn))
9743 gcc_assert (operands[2] == const1_rtx);
9744 return "add{w}\t%0, %0";
9747 if (operands[2] == const1_rtx
9748 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9749 return "sal{w}\t%0";
9751 return "sal{w}\t{%2, %0|%0, %2}";
9755 (cond [(eq_attr "alternative" "1")
9756 (const_string "lea")
9757 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9758 (match_operand 0 "register_operand"))
9759 (match_operand 2 "const1_operand"))
9760 (const_string "alu")
9762 (const_string "ishift")))
9763 (set (attr "length_immediate")
9765 (ior (eq_attr "type" "alu")
9766 (and (eq_attr "type" "ishift")
9767 (and (match_operand 2 "const1_operand")
9768 (ior (match_test "TARGET_SHIFT1")
9769 (match_test "optimize_function_for_size_p (cfun)")))))
9771 (const_string "*")))
9772 (set_attr "mode" "HI,SI")])
9774 (define_insn "*ashlqi3_1"
9775 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9776 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9777 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9778 (clobber (reg:CC FLAGS_REG))]
9779 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9781 switch (get_attr_type (insn))
9787 gcc_assert (operands[2] == const1_rtx);
9788 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
9789 return "add{l}\t%k0, %k0";
9791 return "add{b}\t%0, %0";
9794 if (operands[2] == const1_rtx
9795 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9797 if (get_attr_mode (insn) == MODE_SI)
9798 return "sal{l}\t%k0";
9800 return "sal{b}\t%0";
9804 if (get_attr_mode (insn) == MODE_SI)
9805 return "sal{l}\t{%2, %k0|%k0, %2}";
9807 return "sal{b}\t{%2, %0|%0, %2}";
9812 (cond [(eq_attr "alternative" "2")
9813 (const_string "lea")
9814 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9815 (match_operand 0 "register_operand"))
9816 (match_operand 2 "const1_operand"))
9817 (const_string "alu")
9819 (const_string "ishift")))
9820 (set (attr "length_immediate")
9822 (ior (eq_attr "type" "alu")
9823 (and (eq_attr "type" "ishift")
9824 (and (match_operand 2 "const1_operand")
9825 (ior (match_test "TARGET_SHIFT1")
9826 (match_test "optimize_function_for_size_p (cfun)")))))
9828 (const_string "*")))
9829 (set_attr "mode" "QI,SI,SI")
9830 ;; Potential partial reg stall on alternative 1.
9831 (set (attr "preferred_for_speed")
9832 (cond [(eq_attr "alternative" "1")
9833 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9834 (symbol_ref "true")))])
9836 (define_insn "*ashlqi3_1_slp"
9837 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9838 (ashift:QI (match_dup 0)
9839 (match_operand:QI 1 "nonmemory_operand" "cI")))
9840 (clobber (reg:CC FLAGS_REG))]
9841 "(optimize_function_for_size_p (cfun)
9842 || !TARGET_PARTIAL_FLAG_REG_STALL
9843 || (operands[1] == const1_rtx
9845 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9847 switch (get_attr_type (insn))
9850 gcc_assert (operands[1] == const1_rtx);
9851 return "add{b}\t%0, %0";
9854 if (operands[1] == const1_rtx
9855 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9856 return "sal{b}\t%0";
9858 return "sal{b}\t{%1, %0|%0, %1}";
9862 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9863 (match_operand 0 "register_operand"))
9864 (match_operand 1 "const1_operand"))
9865 (const_string "alu")
9867 (const_string "ishift1")))
9868 (set (attr "length_immediate")
9870 (ior (eq_attr "type" "alu")
9871 (and (eq_attr "type" "ishift1")
9872 (and (match_operand 1 "const1_operand")
9873 (ior (match_test "TARGET_SHIFT1")
9874 (match_test "optimize_function_for_size_p (cfun)")))))
9876 (const_string "*")))
9877 (set_attr "mode" "QI")])
9879 ;; Convert ashift to the lea pattern to avoid flags dependency.
9881 [(set (match_operand:SWI 0 "register_operand")
9882 (ashift:SWI (match_operand:SWI 1 "index_register_operand")
9883 (match_operand 2 "const_0_to_3_operand")))
9884 (clobber (reg:CC FLAGS_REG))]
9886 && REGNO (operands[0]) != REGNO (operands[1])"
9888 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
9890 if (<MODE>mode != <LEAMODE>mode)
9892 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
9893 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
9895 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
9898 ;; Convert ashift to the lea pattern to avoid flags dependency.
9900 [(set (match_operand:DI 0 "register_operand")
9902 (ashift:SI (match_operand:SI 1 "index_register_operand")
9903 (match_operand 2 "const_0_to_3_operand"))))
9904 (clobber (reg:CC FLAGS_REG))]
9905 "TARGET_64BIT && reload_completed
9906 && REGNO (operands[0]) != REGNO (operands[1])"
9908 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9910 operands[1] = gen_lowpart (SImode, operands[1]);
9911 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
9914 ;; This pattern can't accept a variable shift count, since shifts by
9915 ;; zero don't affect the flags. We assume that shifts by constant
9916 ;; zero are optimized away.
9917 (define_insn "*ashl<mode>3_cmp"
9918 [(set (reg FLAGS_REG)
9920 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9921 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9923 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9924 (ashift:SWI (match_dup 1) (match_dup 2)))]
9925 "(optimize_function_for_size_p (cfun)
9926 || !TARGET_PARTIAL_FLAG_REG_STALL
9927 || (operands[2] == const1_rtx
9929 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9930 && ix86_match_ccmode (insn, CCGOCmode)
9931 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9933 switch (get_attr_type (insn))
9936 gcc_assert (operands[2] == const1_rtx);
9937 return "add{<imodesuffix>}\t%0, %0";
9940 if (operands[2] == const1_rtx
9941 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9942 return "sal{<imodesuffix>}\t%0";
9944 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9948 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9949 (match_operand 0 "register_operand"))
9950 (match_operand 2 "const1_operand"))
9951 (const_string "alu")
9953 (const_string "ishift")))
9954 (set (attr "length_immediate")
9956 (ior (eq_attr "type" "alu")
9957 (and (eq_attr "type" "ishift")
9958 (and (match_operand 2 "const1_operand")
9959 (ior (match_test "TARGET_SHIFT1")
9960 (match_test "optimize_function_for_size_p (cfun)")))))
9962 (const_string "*")))
9963 (set_attr "mode" "<MODE>")])
9965 (define_insn "*ashlsi3_cmp_zext"
9966 [(set (reg FLAGS_REG)
9968 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9969 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9971 (set (match_operand:DI 0 "register_operand" "=r")
9972 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9974 && (optimize_function_for_size_p (cfun)
9975 || !TARGET_PARTIAL_FLAG_REG_STALL
9976 || (operands[2] == const1_rtx
9978 || TARGET_DOUBLE_WITH_ADD)))
9979 && ix86_match_ccmode (insn, CCGOCmode)
9980 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9982 switch (get_attr_type (insn))
9985 gcc_assert (operands[2] == const1_rtx);
9986 return "add{l}\t%k0, %k0";
9989 if (operands[2] == const1_rtx
9990 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9991 return "sal{l}\t%k0";
9993 return "sal{l}\t{%2, %k0|%k0, %2}";
9997 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9998 (match_operand 2 "const1_operand"))
9999 (const_string "alu")
10001 (const_string "ishift")))
10002 (set (attr "length_immediate")
10004 (ior (eq_attr "type" "alu")
10005 (and (eq_attr "type" "ishift")
10006 (and (match_operand 2 "const1_operand")
10007 (ior (match_test "TARGET_SHIFT1")
10008 (match_test "optimize_function_for_size_p (cfun)")))))
10010 (const_string "*")))
10011 (set_attr "mode" "SI")])
10013 (define_insn "*ashl<mode>3_cconly"
10014 [(set (reg FLAGS_REG)
10016 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
10017 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10019 (clobber (match_scratch:SWI 0 "=<r>"))]
10020 "(optimize_function_for_size_p (cfun)
10021 || !TARGET_PARTIAL_FLAG_REG_STALL
10022 || (operands[2] == const1_rtx
10024 || TARGET_DOUBLE_WITH_ADD)))
10025 && ix86_match_ccmode (insn, CCGOCmode)"
10027 switch (get_attr_type (insn))
10030 gcc_assert (operands[2] == const1_rtx);
10031 return "add{<imodesuffix>}\t%0, %0";
10034 if (operands[2] == const1_rtx
10035 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10036 return "sal{<imodesuffix>}\t%0";
10038 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10041 [(set (attr "type")
10042 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10043 (match_operand 0 "register_operand"))
10044 (match_operand 2 "const1_operand"))
10045 (const_string "alu")
10047 (const_string "ishift")))
10048 (set (attr "length_immediate")
10050 (ior (eq_attr "type" "alu")
10051 (and (eq_attr "type" "ishift")
10052 (and (match_operand 2 "const1_operand")
10053 (ior (match_test "TARGET_SHIFT1")
10054 (match_test "optimize_function_for_size_p (cfun)")))))
10056 (const_string "*")))
10057 (set_attr "mode" "<MODE>")])
10059 ;; See comment above `ashl<mode>3' about how this works.
10061 (define_expand "<shift_insn><mode>3"
10062 [(set (match_operand:SDWIM 0 "<shift_operand>")
10063 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
10064 (match_operand:QI 2 "nonmemory_operand")))]
10066 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10068 ;; Avoid useless masking of count operand.
10069 (define_insn_and_split "*<shift_insn><mode>3_mask"
10070 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10072 (match_operand:SWI48 1 "nonimmediate_operand")
10075 (match_operand:SI 2 "register_operand")
10076 (match_operand:SI 3 "const_int_operand")) 0)))
10077 (clobber (reg:CC FLAGS_REG))]
10078 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10079 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10080 == GET_MODE_BITSIZE (<MODE>mode)-1
10081 && can_create_pseudo_p ()"
10085 [(set (match_dup 0)
10086 (any_shiftrt:SWI48 (match_dup 1)
10088 (clobber (reg:CC FLAGS_REG))])]
10089 "operands[2] = gen_lowpart (QImode, operands[2]);")
10091 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
10092 [(set (match_operand:DWI 0 "register_operand" "=&r")
10093 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10094 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10095 (clobber (reg:CC FLAGS_REG))]
10098 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10100 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10101 [(set_attr "type" "multi")])
10103 ;; By default we don't ask for a scratch register, because when DWImode
10104 ;; values are manipulated, registers are already at a premium. But if
10105 ;; we have one handy, we won't turn it away.
10108 [(match_scratch:DWIH 3 "r")
10109 (parallel [(set (match_operand:<DWI> 0 "register_operand")
10111 (match_operand:<DWI> 1 "register_operand")
10112 (match_operand:QI 2 "nonmemory_operand")))
10113 (clobber (reg:CC FLAGS_REG))])
10117 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
10119 (define_insn "x86_64_shrd"
10120 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10121 (ior:DI (lshiftrt:DI (match_dup 0)
10122 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10123 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10124 (minus:QI (const_int 64) (match_dup 2)))))
10125 (clobber (reg:CC FLAGS_REG))]
10127 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10128 [(set_attr "type" "ishift")
10129 (set_attr "prefix_0f" "1")
10130 (set_attr "mode" "DI")
10131 (set_attr "athlon_decode" "vector")
10132 (set_attr "amdfam10_decode" "vector")
10133 (set_attr "bdver1_decode" "vector")])
10135 (define_insn "x86_shrd"
10136 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10137 (ior:SI (lshiftrt:SI (match_dup 0)
10138 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10139 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10140 (minus:QI (const_int 32) (match_dup 2)))))
10141 (clobber (reg:CC FLAGS_REG))]
10143 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10144 [(set_attr "type" "ishift")
10145 (set_attr "prefix_0f" "1")
10146 (set_attr "mode" "SI")
10147 (set_attr "pent_pair" "np")
10148 (set_attr "athlon_decode" "vector")
10149 (set_attr "amdfam10_decode" "vector")
10150 (set_attr "bdver1_decode" "vector")])
10152 (define_insn "ashrdi3_cvt"
10153 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10154 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10155 (match_operand:QI 2 "const_int_operand")))
10156 (clobber (reg:CC FLAGS_REG))]
10157 "TARGET_64BIT && INTVAL (operands[2]) == 63
10158 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10159 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10162 sar{q}\t{%2, %0|%0, %2}"
10163 [(set_attr "type" "imovx,ishift")
10164 (set_attr "prefix_0f" "0,*")
10165 (set_attr "length_immediate" "0,*")
10166 (set_attr "modrm" "0,1")
10167 (set_attr "mode" "DI")])
10169 (define_insn "*ashrsi3_cvt_zext"
10170 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10172 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10173 (match_operand:QI 2 "const_int_operand"))))
10174 (clobber (reg:CC FLAGS_REG))]
10175 "TARGET_64BIT && INTVAL (operands[2]) == 31
10176 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10177 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10180 sar{l}\t{%2, %k0|%k0, %2}"
10181 [(set_attr "type" "imovx,ishift")
10182 (set_attr "prefix_0f" "0,*")
10183 (set_attr "length_immediate" "0,*")
10184 (set_attr "modrm" "0,1")
10185 (set_attr "mode" "SI")])
10187 (define_insn "ashrsi3_cvt"
10188 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10189 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10190 (match_operand:QI 2 "const_int_operand")))
10191 (clobber (reg:CC FLAGS_REG))]
10192 "INTVAL (operands[2]) == 31
10193 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10194 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10197 sar{l}\t{%2, %0|%0, %2}"
10198 [(set_attr "type" "imovx,ishift")
10199 (set_attr "prefix_0f" "0,*")
10200 (set_attr "length_immediate" "0,*")
10201 (set_attr "modrm" "0,1")
10202 (set_attr "mode" "SI")])
10204 (define_expand "x86_shift<mode>_adj_3"
10205 [(use (match_operand:SWI48 0 "register_operand"))
10206 (use (match_operand:SWI48 1 "register_operand"))
10207 (use (match_operand:QI 2 "register_operand"))]
10210 rtx_code_label *label = gen_label_rtx ();
10213 emit_insn (gen_testqi_ccz_1 (operands[2],
10214 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10216 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10217 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10218 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10219 gen_rtx_LABEL_REF (VOIDmode, label),
10221 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10222 JUMP_LABEL (tmp) = label;
10224 emit_move_insn (operands[0], operands[1]);
10225 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10226 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10227 emit_label (label);
10228 LABEL_NUSES (label) = 1;
10233 (define_insn "*bmi2_<shift_insn><mode>3_1"
10234 [(set (match_operand:SWI48 0 "register_operand" "=r")
10235 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10236 (match_operand:SWI48 2 "register_operand" "r")))]
10238 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10239 [(set_attr "type" "ishiftx")
10240 (set_attr "mode" "<MODE>")])
10242 (define_insn "*<shift_insn><mode>3_1"
10243 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10245 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10246 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10247 (clobber (reg:CC FLAGS_REG))]
10248 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10250 switch (get_attr_type (insn))
10256 if (operands[2] == const1_rtx
10257 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10258 return "<shift>{<imodesuffix>}\t%0";
10260 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10263 [(set_attr "isa" "*,bmi2")
10264 (set_attr "type" "ishift,ishiftx")
10265 (set (attr "length_immediate")
10267 (and (match_operand 2 "const1_operand")
10268 (ior (match_test "TARGET_SHIFT1")
10269 (match_test "optimize_function_for_size_p (cfun)")))
10271 (const_string "*")))
10272 (set_attr "mode" "<MODE>")])
10274 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10276 [(set (match_operand:SWI48 0 "register_operand")
10277 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10278 (match_operand:QI 2 "register_operand")))
10279 (clobber (reg:CC FLAGS_REG))]
10280 "TARGET_BMI2 && reload_completed"
10281 [(set (match_dup 0)
10282 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10283 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10285 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10286 [(set (match_operand:DI 0 "register_operand" "=r")
10288 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10289 (match_operand:SI 2 "register_operand" "r"))))]
10290 "TARGET_64BIT && TARGET_BMI2"
10291 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10292 [(set_attr "type" "ishiftx")
10293 (set_attr "mode" "SI")])
10295 (define_insn "*<shift_insn>si3_1_zext"
10296 [(set (match_operand:DI 0 "register_operand" "=r,r")
10298 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10299 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10300 (clobber (reg:CC FLAGS_REG))]
10301 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10303 switch (get_attr_type (insn))
10309 if (operands[2] == const1_rtx
10310 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10311 return "<shift>{l}\t%k0";
10313 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10316 [(set_attr "isa" "*,bmi2")
10317 (set_attr "type" "ishift,ishiftx")
10318 (set (attr "length_immediate")
10320 (and (match_operand 2 "const1_operand")
10321 (ior (match_test "TARGET_SHIFT1")
10322 (match_test "optimize_function_for_size_p (cfun)")))
10324 (const_string "*")))
10325 (set_attr "mode" "SI")])
10327 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10329 [(set (match_operand:DI 0 "register_operand")
10331 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10332 (match_operand:QI 2 "register_operand"))))
10333 (clobber (reg:CC FLAGS_REG))]
10334 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10335 [(set (match_dup 0)
10336 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10337 "operands[2] = gen_lowpart (SImode, operands[2]);")
10339 (define_insn "*<shift_insn><mode>3_1"
10340 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10342 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10343 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10344 (clobber (reg:CC FLAGS_REG))]
10345 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10347 if (operands[2] == const1_rtx
10348 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10349 return "<shift>{<imodesuffix>}\t%0";
10351 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10353 [(set_attr "type" "ishift")
10354 (set (attr "length_immediate")
10356 (and (match_operand 2 "const1_operand")
10357 (ior (match_test "TARGET_SHIFT1")
10358 (match_test "optimize_function_for_size_p (cfun)")))
10360 (const_string "*")))
10361 (set_attr "mode" "<MODE>")])
10363 (define_insn "*<shift_insn>qi3_1_slp"
10364 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10365 (any_shiftrt:QI (match_dup 0)
10366 (match_operand:QI 1 "nonmemory_operand" "cI")))
10367 (clobber (reg:CC FLAGS_REG))]
10368 "(optimize_function_for_size_p (cfun)
10369 || !TARGET_PARTIAL_REG_STALL
10370 || (operands[1] == const1_rtx
10371 && TARGET_SHIFT1))"
10373 if (operands[1] == const1_rtx
10374 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10375 return "<shift>{b}\t%0";
10377 return "<shift>{b}\t{%1, %0|%0, %1}";
10379 [(set_attr "type" "ishift1")
10380 (set (attr "length_immediate")
10382 (and (match_operand 1 "const1_operand")
10383 (ior (match_test "TARGET_SHIFT1")
10384 (match_test "optimize_function_for_size_p (cfun)")))
10386 (const_string "*")))
10387 (set_attr "mode" "QI")])
10389 ;; This pattern can't accept a variable shift count, since shifts by
10390 ;; zero don't affect the flags. We assume that shifts by constant
10391 ;; zero are optimized away.
10392 (define_insn "*<shift_insn><mode>3_cmp"
10393 [(set (reg FLAGS_REG)
10396 (match_operand:SWI 1 "nonimmediate_operand" "0")
10397 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10399 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10400 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10401 "(optimize_function_for_size_p (cfun)
10402 || !TARGET_PARTIAL_FLAG_REG_STALL
10403 || (operands[2] == const1_rtx
10405 && ix86_match_ccmode (insn, CCGOCmode)
10406 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10408 if (operands[2] == const1_rtx
10409 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10410 return "<shift>{<imodesuffix>}\t%0";
10412 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10414 [(set_attr "type" "ishift")
10415 (set (attr "length_immediate")
10417 (and (match_operand 2 "const1_operand")
10418 (ior (match_test "TARGET_SHIFT1")
10419 (match_test "optimize_function_for_size_p (cfun)")))
10421 (const_string "*")))
10422 (set_attr "mode" "<MODE>")])
10424 (define_insn "*<shift_insn>si3_cmp_zext"
10425 [(set (reg FLAGS_REG)
10427 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10428 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10430 (set (match_operand:DI 0 "register_operand" "=r")
10431 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10433 && (optimize_function_for_size_p (cfun)
10434 || !TARGET_PARTIAL_FLAG_REG_STALL
10435 || (operands[2] == const1_rtx
10437 && ix86_match_ccmode (insn, CCGOCmode)
10438 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10440 if (operands[2] == const1_rtx
10441 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10442 return "<shift>{l}\t%k0";
10444 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10446 [(set_attr "type" "ishift")
10447 (set (attr "length_immediate")
10449 (and (match_operand 2 "const1_operand")
10450 (ior (match_test "TARGET_SHIFT1")
10451 (match_test "optimize_function_for_size_p (cfun)")))
10453 (const_string "*")))
10454 (set_attr "mode" "SI")])
10456 (define_insn "*<shift_insn><mode>3_cconly"
10457 [(set (reg FLAGS_REG)
10460 (match_operand:SWI 1 "register_operand" "0")
10461 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10463 (clobber (match_scratch:SWI 0 "=<r>"))]
10464 "(optimize_function_for_size_p (cfun)
10465 || !TARGET_PARTIAL_FLAG_REG_STALL
10466 || (operands[2] == const1_rtx
10468 && ix86_match_ccmode (insn, CCGOCmode)"
10470 if (operands[2] == const1_rtx
10471 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10472 return "<shift>{<imodesuffix>}\t%0";
10474 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10476 [(set_attr "type" "ishift")
10477 (set (attr "length_immediate")
10479 (and (match_operand 2 "const1_operand")
10480 (ior (match_test "TARGET_SHIFT1")
10481 (match_test "optimize_function_for_size_p (cfun)")))
10483 (const_string "*")))
10484 (set_attr "mode" "<MODE>")])
10486 ;; Rotate instructions
10488 (define_expand "<rotate_insn>ti3"
10489 [(set (match_operand:TI 0 "register_operand")
10490 (any_rotate:TI (match_operand:TI 1 "register_operand")
10491 (match_operand:QI 2 "nonmemory_operand")))]
10494 if (const_1_to_63_operand (operands[2], VOIDmode))
10495 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10496 (operands[0], operands[1], operands[2]));
10503 (define_expand "<rotate_insn>di3"
10504 [(set (match_operand:DI 0 "shiftdi_operand")
10505 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10506 (match_operand:QI 2 "nonmemory_operand")))]
10510 ix86_expand_binary_operator (<CODE>, DImode, operands);
10511 else if (const_1_to_31_operand (operands[2], VOIDmode))
10512 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10513 (operands[0], operands[1], operands[2]));
10520 (define_expand "<rotate_insn><mode>3"
10521 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10522 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10523 (match_operand:QI 2 "nonmemory_operand")))]
10525 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10527 ;; Avoid useless masking of count operand.
10528 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10529 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10531 (match_operand:SWI48 1 "nonimmediate_operand")
10534 (match_operand:SI 2 "register_operand")
10535 (match_operand:SI 3 "const_int_operand")) 0)))
10536 (clobber (reg:CC FLAGS_REG))]
10537 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10538 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10539 == GET_MODE_BITSIZE (<MODE>mode)-1
10540 && can_create_pseudo_p ()"
10544 [(set (match_dup 0)
10545 (any_rotate:SWI48 (match_dup 1)
10547 (clobber (reg:CC FLAGS_REG))])]
10548 "operands[2] = gen_lowpart (QImode, operands[2]);")
10550 ;; Implement rotation using two double-precision
10551 ;; shift instructions and a scratch register.
10553 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10554 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10555 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10556 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10557 (clobber (reg:CC FLAGS_REG))
10558 (clobber (match_scratch:DWIH 3 "=&r"))]
10562 [(set (match_dup 3) (match_dup 4))
10564 [(set (match_dup 4)
10565 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10566 (lshiftrt:DWIH (match_dup 5)
10567 (minus:QI (match_dup 6) (match_dup 2)))))
10568 (clobber (reg:CC FLAGS_REG))])
10570 [(set (match_dup 5)
10571 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10572 (lshiftrt:DWIH (match_dup 3)
10573 (minus:QI (match_dup 6) (match_dup 2)))))
10574 (clobber (reg:CC FLAGS_REG))])]
10576 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10578 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10581 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10582 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10583 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10584 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10585 (clobber (reg:CC FLAGS_REG))
10586 (clobber (match_scratch:DWIH 3 "=&r"))]
10590 [(set (match_dup 3) (match_dup 4))
10592 [(set (match_dup 4)
10593 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10594 (ashift:DWIH (match_dup 5)
10595 (minus:QI (match_dup 6) (match_dup 2)))))
10596 (clobber (reg:CC FLAGS_REG))])
10598 [(set (match_dup 5)
10599 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10600 (ashift:DWIH (match_dup 3)
10601 (minus:QI (match_dup 6) (match_dup 2)))))
10602 (clobber (reg:CC FLAGS_REG))])]
10604 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10606 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10609 (define_insn "*bmi2_rorx<mode>3_1"
10610 [(set (match_operand:SWI48 0 "register_operand" "=r")
10611 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10612 (match_operand:QI 2 "immediate_operand" "<S>")))]
10614 "rorx\t{%2, %1, %0|%0, %1, %2}"
10615 [(set_attr "type" "rotatex")
10616 (set_attr "mode" "<MODE>")])
10618 (define_insn "*<rotate_insn><mode>3_1"
10619 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10621 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10622 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10623 (clobber (reg:CC FLAGS_REG))]
10624 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10626 switch (get_attr_type (insn))
10632 if (operands[2] == const1_rtx
10633 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10634 return "<rotate>{<imodesuffix>}\t%0";
10636 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10639 [(set_attr "isa" "*,bmi2")
10640 (set_attr "type" "rotate,rotatex")
10641 (set (attr "length_immediate")
10643 (and (eq_attr "type" "rotate")
10644 (and (match_operand 2 "const1_operand")
10645 (ior (match_test "TARGET_SHIFT1")
10646 (match_test "optimize_function_for_size_p (cfun)"))))
10648 (const_string "*")))
10649 (set_attr "mode" "<MODE>")])
10651 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10653 [(set (match_operand:SWI48 0 "register_operand")
10654 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10655 (match_operand:QI 2 "immediate_operand")))
10656 (clobber (reg:CC FLAGS_REG))]
10657 "TARGET_BMI2 && reload_completed"
10658 [(set (match_dup 0)
10659 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10661 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
10663 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
10667 [(set (match_operand:SWI48 0 "register_operand")
10668 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10669 (match_operand:QI 2 "immediate_operand")))
10670 (clobber (reg:CC FLAGS_REG))]
10671 "TARGET_BMI2 && reload_completed"
10672 [(set (match_dup 0)
10673 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10675 (define_insn "*bmi2_rorxsi3_1_zext"
10676 [(set (match_operand:DI 0 "register_operand" "=r")
10678 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10679 (match_operand:QI 2 "immediate_operand" "I"))))]
10680 "TARGET_64BIT && TARGET_BMI2"
10681 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10682 [(set_attr "type" "rotatex")
10683 (set_attr "mode" "SI")])
10685 (define_insn "*<rotate_insn>si3_1_zext"
10686 [(set (match_operand:DI 0 "register_operand" "=r,r")
10688 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10689 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10690 (clobber (reg:CC FLAGS_REG))]
10691 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10693 switch (get_attr_type (insn))
10699 if (operands[2] == const1_rtx
10700 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10701 return "<rotate>{l}\t%k0";
10703 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10706 [(set_attr "isa" "*,bmi2")
10707 (set_attr "type" "rotate,rotatex")
10708 (set (attr "length_immediate")
10710 (and (eq_attr "type" "rotate")
10711 (and (match_operand 2 "const1_operand")
10712 (ior (match_test "TARGET_SHIFT1")
10713 (match_test "optimize_function_for_size_p (cfun)"))))
10715 (const_string "*")))
10716 (set_attr "mode" "SI")])
10718 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10720 [(set (match_operand:DI 0 "register_operand")
10722 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10723 (match_operand:QI 2 "immediate_operand"))))
10724 (clobber (reg:CC FLAGS_REG))]
10725 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10726 [(set (match_dup 0)
10727 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10729 int bitsize = GET_MODE_BITSIZE (SImode);
10731 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
10735 [(set (match_operand:DI 0 "register_operand")
10737 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10738 (match_operand:QI 2 "immediate_operand"))))
10739 (clobber (reg:CC FLAGS_REG))]
10740 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10741 [(set (match_dup 0)
10742 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10744 (define_insn "*<rotate_insn><mode>3_1"
10745 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10746 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10747 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10748 (clobber (reg:CC FLAGS_REG))]
10749 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10751 if (operands[2] == const1_rtx
10752 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10753 return "<rotate>{<imodesuffix>}\t%0";
10755 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10757 [(set_attr "type" "rotate")
10758 (set (attr "length_immediate")
10760 (and (match_operand 2 "const1_operand")
10761 (ior (match_test "TARGET_SHIFT1")
10762 (match_test "optimize_function_for_size_p (cfun)")))
10764 (const_string "*")))
10765 (set_attr "mode" "<MODE>")])
10767 (define_insn "*<rotate_insn>qi3_1_slp"
10768 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10769 (any_rotate:QI (match_dup 0)
10770 (match_operand:QI 1 "nonmemory_operand" "cI")))
10771 (clobber (reg:CC FLAGS_REG))]
10772 "(optimize_function_for_size_p (cfun)
10773 || !TARGET_PARTIAL_REG_STALL
10774 || (operands[1] == const1_rtx
10775 && TARGET_SHIFT1))"
10777 if (operands[1] == const1_rtx
10778 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10779 return "<rotate>{b}\t%0";
10781 return "<rotate>{b}\t{%1, %0|%0, %1}";
10783 [(set_attr "type" "rotate1")
10784 (set (attr "length_immediate")
10786 (and (match_operand 1 "const1_operand")
10787 (ior (match_test "TARGET_SHIFT1")
10788 (match_test "optimize_function_for_size_p (cfun)")))
10790 (const_string "*")))
10791 (set_attr "mode" "QI")])
10794 [(set (match_operand:HI 0 "register_operand")
10795 (any_rotate:HI (match_dup 0) (const_int 8)))
10796 (clobber (reg:CC FLAGS_REG))]
10798 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10799 [(parallel [(set (strict_low_part (match_dup 0))
10800 (bswap:HI (match_dup 0)))
10801 (clobber (reg:CC FLAGS_REG))])])
10803 ;; Bit set / bit test instructions
10805 ;; %%% bts, btr, btc, bt.
10806 ;; In general these instructions are *slow* when applied to memory,
10807 ;; since they enforce atomic operation. When applied to registers,
10808 ;; it depends on the cpu implementation. They're never faster than
10809 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10810 ;; no point. But in 64-bit, we can't hold the relevant immediates
10811 ;; within the instruction itself, so operating on bits in the high
10812 ;; 32-bits of a register becomes easier.
10814 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10815 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10816 ;; negdf respectively, so they can never be disabled entirely.
10818 (define_insn "*btsq"
10819 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10821 (match_operand 1 "const_0_to_63_operand" "J"))
10823 (clobber (reg:CC FLAGS_REG))]
10824 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10825 "bts{q}\t{%1, %0|%0, %1}"
10826 [(set_attr "type" "alu1")
10827 (set_attr "prefix_0f" "1")
10828 (set_attr "znver1_decode" "double")
10829 (set_attr "mode" "DI")])
10831 (define_insn "*btrq"
10832 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10834 (match_operand 1 "const_0_to_63_operand" "J"))
10836 (clobber (reg:CC FLAGS_REG))]
10837 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10838 "btr{q}\t{%1, %0|%0, %1}"
10839 [(set_attr "type" "alu1")
10840 (set_attr "prefix_0f" "1")
10841 (set_attr "znver1_decode" "double")
10842 (set_attr "mode" "DI")])
10844 (define_insn "*btcq"
10845 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10847 (match_operand 1 "const_0_to_63_operand" "J"))
10848 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10849 (clobber (reg:CC FLAGS_REG))]
10850 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10851 "btc{q}\t{%1, %0|%0, %1}"
10852 [(set_attr "type" "alu1")
10853 (set_attr "prefix_0f" "1")
10854 (set_attr "znver1_decode" "double")
10855 (set_attr "mode" "DI")])
10857 ;; Allow Nocona to avoid these instructions if a register is available.
10860 [(match_scratch:DI 2 "r")
10861 (parallel [(set (zero_extract:DI
10862 (match_operand:DI 0 "register_operand")
10864 (match_operand 1 "const_0_to_63_operand"))
10866 (clobber (reg:CC FLAGS_REG))])]
10867 "TARGET_64BIT && !TARGET_USE_BT"
10868 [(parallel [(set (match_dup 0)
10869 (ior:DI (match_dup 0) (match_dup 3)))
10870 (clobber (reg:CC FLAGS_REG))])]
10872 int i = INTVAL (operands[1]);
10874 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
10876 if (!x86_64_immediate_operand (operands[3], DImode))
10878 emit_move_insn (operands[2], operands[3]);
10879 operands[3] = operands[2];
10884 [(match_scratch:DI 2 "r")
10885 (parallel [(set (zero_extract:DI
10886 (match_operand:DI 0 "register_operand")
10888 (match_operand 1 "const_0_to_63_operand"))
10890 (clobber (reg:CC FLAGS_REG))])]
10891 "TARGET_64BIT && !TARGET_USE_BT"
10892 [(parallel [(set (match_dup 0)
10893 (and:DI (match_dup 0) (match_dup 3)))
10894 (clobber (reg:CC FLAGS_REG))])]
10896 int i = INTVAL (operands[1]);
10898 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
10900 if (!x86_64_immediate_operand (operands[3], DImode))
10902 emit_move_insn (operands[2], operands[3]);
10903 operands[3] = operands[2];
10908 [(match_scratch:DI 2 "r")
10909 (parallel [(set (zero_extract:DI
10910 (match_operand:DI 0 "register_operand")
10912 (match_operand 1 "const_0_to_63_operand"))
10913 (not:DI (zero_extract:DI
10914 (match_dup 0) (const_int 1) (match_dup 1))))
10915 (clobber (reg:CC FLAGS_REG))])]
10916 "TARGET_64BIT && !TARGET_USE_BT"
10917 [(parallel [(set (match_dup 0)
10918 (xor:DI (match_dup 0) (match_dup 3)))
10919 (clobber (reg:CC FLAGS_REG))])]
10921 int i = INTVAL (operands[1]);
10923 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
10925 if (!x86_64_immediate_operand (operands[3], DImode))
10927 emit_move_insn (operands[2], operands[3]);
10928 operands[3] = operands[2];
10932 (define_insn "*bt<mode>"
10933 [(set (reg:CCC FLAGS_REG)
10935 (zero_extract:SWI48
10936 (match_operand:SWI48 0 "register_operand" "r")
10938 (match_operand:SI 1 "nonmemory_operand" "rN"))
10942 switch (get_attr_mode (insn))
10945 return "bt{l}\t{%1, %k0|%k0, %1}";
10948 return "bt{q}\t{%q1, %0|%0, %q1}";
10951 gcc_unreachable ();
10954 [(set_attr "type" "alu1")
10955 (set_attr "prefix_0f" "1")
10958 (and (match_test "CONST_INT_P (operands[1])")
10959 (match_test "INTVAL (operands[1]) < 32"))
10960 (const_string "SI")
10961 (const_string "<MODE>")))])
10963 (define_insn_and_split "*jcc_bt<mode>"
10965 (if_then_else (match_operator 0 "bt_comparison_operator"
10966 [(zero_extract:SWI48
10967 (match_operand:SWI48 1 "register_operand")
10969 (match_operand:SI 2 "nonmemory_operand"))
10971 (label_ref (match_operand 3))
10973 (clobber (reg:CC FLAGS_REG))]
10974 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10975 && (CONST_INT_P (operands[2])
10976 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
10977 && INTVAL (operands[2])
10978 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
10979 : register_operand (operands[2], SImode))
10980 && can_create_pseudo_p ()"
10983 [(set (reg:CCC FLAGS_REG)
10985 (zero_extract:SWI48
10991 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10992 (label_ref (match_dup 3))
10995 operands[0] = shallow_copy_rtx (operands[0]);
10996 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10999 (define_insn_and_split "*jcc_bt<mode>_1"
11001 (if_then_else (match_operator 0 "bt_comparison_operator"
11002 [(zero_extract:SWI48
11003 (match_operand:SWI48 1 "register_operand")
11006 (match_operand:QI 2 "register_operand")))
11008 (label_ref (match_operand 3))
11010 (clobber (reg:CC FLAGS_REG))]
11011 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11012 && can_create_pseudo_p ()"
11015 [(set (reg:CCC FLAGS_REG)
11017 (zero_extract:SWI48
11023 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11024 (label_ref (match_dup 3))
11027 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
11028 operands[0] = shallow_copy_rtx (operands[0]);
11029 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11032 ;; Avoid useless masking of bit offset operand.
11033 (define_insn_and_split "*jcc_bt<mode>_mask"
11035 (if_then_else (match_operator 0 "bt_comparison_operator"
11036 [(zero_extract:SWI48
11037 (match_operand:SWI48 1 "register_operand")
11040 (match_operand:SI 2 "register_operand")
11041 (match_operand 3 "const_int_operand")))])
11042 (label_ref (match_operand 4))
11044 (clobber (reg:CC FLAGS_REG))]
11045 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11046 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11047 == GET_MODE_BITSIZE (<MODE>mode)-1
11048 && can_create_pseudo_p ()"
11051 [(set (reg:CCC FLAGS_REG)
11053 (zero_extract:SWI48
11059 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11060 (label_ref (match_dup 4))
11063 operands[0] = shallow_copy_rtx (operands[0]);
11064 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11067 ;; Store-flag instructions.
11069 ;; For all sCOND expanders, also expand the compare or test insn that
11070 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
11072 (define_insn_and_split "*setcc_di_1"
11073 [(set (match_operand:DI 0 "register_operand" "=q")
11074 (match_operator:DI 1 "ix86_comparison_operator"
11075 [(reg FLAGS_REG) (const_int 0)]))]
11076 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
11078 "&& reload_completed"
11079 [(set (match_dup 2) (match_dup 1))
11080 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
11082 operands[1] = shallow_copy_rtx (operands[1]);
11083 PUT_MODE (operands[1], QImode);
11084 operands[2] = gen_lowpart (QImode, operands[0]);
11087 (define_insn_and_split "*setcc_si_1_and"
11088 [(set (match_operand:SI 0 "register_operand" "=q")
11089 (match_operator:SI 1 "ix86_comparison_operator"
11090 [(reg FLAGS_REG) (const_int 0)]))
11091 (clobber (reg:CC FLAGS_REG))]
11092 "!TARGET_PARTIAL_REG_STALL
11093 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
11095 "&& reload_completed"
11096 [(set (match_dup 2) (match_dup 1))
11097 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
11098 (clobber (reg:CC FLAGS_REG))])]
11100 operands[1] = shallow_copy_rtx (operands[1]);
11101 PUT_MODE (operands[1], QImode);
11102 operands[2] = gen_lowpart (QImode, operands[0]);
11105 (define_insn_and_split "*setcc_si_1_movzbl"
11106 [(set (match_operand:SI 0 "register_operand" "=q")
11107 (match_operator:SI 1 "ix86_comparison_operator"
11108 [(reg FLAGS_REG) (const_int 0)]))]
11109 "!TARGET_PARTIAL_REG_STALL
11110 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
11112 "&& reload_completed"
11113 [(set (match_dup 2) (match_dup 1))
11114 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
11116 operands[1] = shallow_copy_rtx (operands[1]);
11117 PUT_MODE (operands[1], QImode);
11118 operands[2] = gen_lowpart (QImode, operands[0]);
11121 (define_insn "*setcc_qi"
11122 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11123 (match_operator:QI 1 "ix86_comparison_operator"
11124 [(reg FLAGS_REG) (const_int 0)]))]
11127 [(set_attr "type" "setcc")
11128 (set_attr "mode" "QI")])
11130 (define_insn "*setcc_qi_slp"
11131 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11132 (match_operator:QI 1 "ix86_comparison_operator"
11133 [(reg FLAGS_REG) (const_int 0)]))]
11136 [(set_attr "type" "setcc")
11137 (set_attr "mode" "QI")])
11139 ;; In general it is not safe to assume too much about CCmode registers,
11140 ;; so simplify-rtx stops when it sees a second one. Under certain
11141 ;; conditions this is safe on x86, so help combine not create
11148 [(set (match_operand:QI 0 "nonimmediate_operand")
11149 (ne:QI (match_operator 1 "ix86_comparison_operator"
11150 [(reg FLAGS_REG) (const_int 0)])
11153 [(set (match_dup 0) (match_dup 1))]
11155 operands[1] = shallow_copy_rtx (operands[1]);
11156 PUT_MODE (operands[1], QImode);
11160 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11161 (ne:QI (match_operator 1 "ix86_comparison_operator"
11162 [(reg FLAGS_REG) (const_int 0)])
11165 [(set (match_dup 0) (match_dup 1))]
11167 operands[1] = shallow_copy_rtx (operands[1]);
11168 PUT_MODE (operands[1], QImode);
11172 [(set (match_operand:QI 0 "nonimmediate_operand")
11173 (eq:QI (match_operator 1 "ix86_comparison_operator"
11174 [(reg FLAGS_REG) (const_int 0)])
11177 [(set (match_dup 0) (match_dup 1))]
11179 operands[1] = shallow_copy_rtx (operands[1]);
11180 PUT_MODE (operands[1], QImode);
11181 PUT_CODE (operands[1],
11182 ix86_reverse_condition (GET_CODE (operands[1]),
11183 GET_MODE (XEXP (operands[1], 0))));
11185 /* Make sure that (a) the CCmode we have for the flags is strong
11186 enough for the reversed compare or (b) we have a valid FP compare. */
11187 if (! ix86_comparison_operator (operands[1], VOIDmode))
11192 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11193 (eq:QI (match_operator 1 "ix86_comparison_operator"
11194 [(reg FLAGS_REG) (const_int 0)])
11197 [(set (match_dup 0) (match_dup 1))]
11199 operands[1] = shallow_copy_rtx (operands[1]);
11200 PUT_MODE (operands[1], QImode);
11201 PUT_CODE (operands[1],
11202 ix86_reverse_condition (GET_CODE (operands[1]),
11203 GET_MODE (XEXP (operands[1], 0))));
11205 /* Make sure that (a) the CCmode we have for the flags is strong
11206 enough for the reversed compare or (b) we have a valid FP compare. */
11207 if (! ix86_comparison_operator (operands[1], VOIDmode))
11211 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
11212 ;; subsequent logical operations are used to imitate conditional moves.
11213 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
11216 (define_insn "setcc_<mode>_sse"
11217 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
11218 (match_operator:MODEF 3 "sse_comparison_operator"
11219 [(match_operand:MODEF 1 "register_operand" "0,x")
11220 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
11221 "SSE_FLOAT_MODE_P (<MODE>mode)"
11223 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
11224 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
11225 [(set_attr "isa" "noavx,avx")
11226 (set_attr "type" "ssecmp")
11227 (set_attr "length_immediate" "1")
11228 (set_attr "prefix" "orig,vex")
11229 (set_attr "mode" "<MODE>")])
11231 ;; Basic conditional jump instructions.
11232 ;; We ignore the overflow flag for signed branch instructions.
11234 (define_insn "*jcc_1"
11236 (if_then_else (match_operator 1 "ix86_comparison_operator"
11237 [(reg FLAGS_REG) (const_int 0)])
11238 (label_ref (match_operand 0))
11242 [(set_attr "type" "ibr")
11243 (set_attr "modrm" "0")
11244 (set (attr "length")
11246 (and (ge (minus (match_dup 0) (pc))
11248 (lt (minus (match_dup 0) (pc))
11252 (set_attr "maybe_prefix_bnd" "1")])
11254 (define_insn "*jcc_2"
11256 (if_then_else (match_operator 1 "ix86_comparison_operator"
11257 [(reg FLAGS_REG) (const_int 0)])
11259 (label_ref (match_operand 0))))]
11262 [(set_attr "type" "ibr")
11263 (set_attr "modrm" "0")
11264 (set (attr "length")
11266 (and (ge (minus (match_dup 0) (pc))
11268 (lt (minus (match_dup 0) (pc))
11272 (set_attr "maybe_prefix_bnd" "1")])
11274 ;; In general it is not safe to assume too much about CCmode registers,
11275 ;; so simplify-rtx stops when it sees a second one. Under certain
11276 ;; conditions this is safe on x86, so help combine not create
11284 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11285 [(reg FLAGS_REG) (const_int 0)])
11287 (label_ref (match_operand 1))
11291 (if_then_else (match_dup 0)
11292 (label_ref (match_dup 1))
11295 operands[0] = shallow_copy_rtx (operands[0]);
11296 PUT_MODE (operands[0], VOIDmode);
11301 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11302 [(reg FLAGS_REG) (const_int 0)])
11304 (label_ref (match_operand 1))
11308 (if_then_else (match_dup 0)
11309 (label_ref (match_dup 1))
11312 operands[0] = shallow_copy_rtx (operands[0]);
11313 PUT_MODE (operands[0], VOIDmode);
11314 PUT_CODE (operands[0],
11315 ix86_reverse_condition (GET_CODE (operands[0]),
11316 GET_MODE (XEXP (operands[0], 0))));
11318 /* Make sure that (a) the CCmode we have for the flags is strong
11319 enough for the reversed compare or (b) we have a valid FP compare. */
11320 if (! ix86_comparison_operator (operands[0], VOIDmode))
11324 ;; Define combination compare-and-branch fp compare instructions to help
11327 (define_insn "*jcc<mode>_0_i387"
11329 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11330 [(match_operand:X87MODEF 1 "register_operand" "f")
11331 (match_operand:X87MODEF 2 "const0_operand")])
11332 (label_ref (match_operand 3))
11334 (clobber (reg:CCFP FPSR_REG))
11335 (clobber (reg:CCFP FLAGS_REG))
11336 (clobber (match_scratch:HI 4 "=a"))]
11337 "TARGET_80387 && !TARGET_CMOVE"
11340 (define_insn "*jcc<mode>_0_r_i387"
11342 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11343 [(match_operand:X87MODEF 1 "register_operand" "f")
11344 (match_operand:X87MODEF 2 "const0_operand")])
11346 (label_ref (match_operand 3))))
11347 (clobber (reg:CCFP FPSR_REG))
11348 (clobber (reg:CCFP FLAGS_REG))
11349 (clobber (match_scratch:HI 4 "=a"))]
11350 "TARGET_80387 && !TARGET_CMOVE"
11353 (define_insn "*jccxf_i387"
11355 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11356 [(match_operand:XF 1 "register_operand" "f")
11357 (match_operand:XF 2 "register_operand" "f")])
11358 (label_ref (match_operand 3))
11360 (clobber (reg:CCFP FPSR_REG))
11361 (clobber (reg:CCFP FLAGS_REG))
11362 (clobber (match_scratch:HI 4 "=a"))]
11363 "TARGET_80387 && !TARGET_CMOVE"
11366 (define_insn "*jccxf_r_i387"
11368 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11369 [(match_operand:XF 1 "register_operand" "f")
11370 (match_operand:XF 2 "register_operand" "f")])
11372 (label_ref (match_operand 3))))
11373 (clobber (reg:CCFP FPSR_REG))
11374 (clobber (reg:CCFP FLAGS_REG))
11375 (clobber (match_scratch:HI 4 "=a"))]
11376 "TARGET_80387 && !TARGET_CMOVE"
11379 (define_insn "*jcc<mode>_i387"
11381 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11382 [(match_operand:MODEF 1 "register_operand" "f")
11383 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11384 (label_ref (match_operand 3))
11386 (clobber (reg:CCFP FPSR_REG))
11387 (clobber (reg:CCFP FLAGS_REG))
11388 (clobber (match_scratch:HI 4 "=a"))]
11389 "TARGET_80387 && !TARGET_CMOVE"
11392 (define_insn "*jcc<mode>_r_i387"
11394 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11395 [(match_operand:MODEF 1 "register_operand" "f")
11396 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11398 (label_ref (match_operand 3))))
11399 (clobber (reg:CCFP FPSR_REG))
11400 (clobber (reg:CCFP FLAGS_REG))
11401 (clobber (match_scratch:HI 4 "=a"))]
11402 "TARGET_80387 && !TARGET_CMOVE"
11405 (define_insn "*jccu<mode>_i387"
11407 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11408 [(match_operand:X87MODEF 1 "register_operand" "f")
11409 (match_operand:X87MODEF 2 "register_operand" "f")])
11410 (label_ref (match_operand 3))
11412 (clobber (reg:CCFP FPSR_REG))
11413 (clobber (reg:CCFP FLAGS_REG))
11414 (clobber (match_scratch:HI 4 "=a"))]
11415 "TARGET_80387 && !TARGET_CMOVE"
11418 (define_insn "*jccu<mode>_r_i387"
11420 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11421 [(match_operand:X87MODEF 1 "register_operand" "f")
11422 (match_operand:X87MODEF 2 "register_operand" "f")])
11424 (label_ref (match_operand 3))))
11425 (clobber (reg:CCFP FPSR_REG))
11426 (clobber (reg:CCFP FLAGS_REG))
11427 (clobber (match_scratch:HI 4 "=a"))]
11428 "TARGET_80387 && !TARGET_CMOVE"
11433 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11434 [(match_operand:X87MODEF 1 "register_operand")
11435 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11437 (match_operand 4)))
11438 (clobber (reg:CCFP FPSR_REG))
11439 (clobber (reg:CCFP FLAGS_REG))]
11440 "TARGET_80387 && !TARGET_CMOVE
11441 && reload_completed"
11444 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11445 operands[3], operands[4], NULL_RTX);
11451 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11452 [(match_operand:X87MODEF 1 "register_operand")
11453 (match_operand:X87MODEF 2 "general_operand")])
11455 (match_operand 4)))
11456 (clobber (reg:CCFP FPSR_REG))
11457 (clobber (reg:CCFP FLAGS_REG))
11458 (clobber (match_scratch:HI 5))]
11459 "TARGET_80387 && !TARGET_CMOVE
11460 && reload_completed"
11463 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11464 operands[3], operands[4], operands[5]);
11468 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11469 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11470 ;; with a precedence over other operators and is always put in the first
11471 ;; place. Swap condition and operands to match ficom instruction.
11473 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11476 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11477 [(match_operator:X87MODEF 1 "float_operator"
11478 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11479 (match_operand:X87MODEF 3 "register_operand" "f")])
11480 (label_ref (match_operand 4))
11482 (clobber (reg:CCFP FPSR_REG))
11483 (clobber (reg:CCFP FLAGS_REG))
11484 (clobber (match_scratch:HI 5 "=a"))]
11485 "TARGET_80387 && !TARGET_CMOVE
11486 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11487 || optimize_function_for_size_p (cfun))"
11490 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11493 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11494 [(match_operator:X87MODEF 1 "float_operator"
11495 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11496 (match_operand:X87MODEF 3 "register_operand" "f")])
11498 (label_ref (match_operand 4))))
11499 (clobber (reg:CCFP FPSR_REG))
11500 (clobber (reg:CCFP FLAGS_REG))
11501 (clobber (match_scratch:HI 5 "=a"))]
11502 "TARGET_80387 && !TARGET_CMOVE
11503 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11504 || optimize_function_for_size_p (cfun))"
11510 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11511 [(match_operator:X87MODEF 1 "float_operator"
11512 [(match_operand:SWI24 2 "memory_operand")])
11513 (match_operand:X87MODEF 3 "register_operand")])
11515 (match_operand 5)))
11516 (clobber (reg:CCFP FPSR_REG))
11517 (clobber (reg:CCFP FLAGS_REG))
11518 (clobber (match_scratch:HI 6))]
11519 "TARGET_80387 && !TARGET_CMOVE
11520 && reload_completed"
11523 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11524 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11525 operands[4], operands[5], operands[6]);
11529 ;; Unconditional and other jump instructions
11531 (define_insn "jump"
11533 (label_ref (match_operand 0)))]
11536 [(set_attr "type" "ibr")
11537 (set_attr "modrm" "0")
11538 (set (attr "length")
11540 (and (ge (minus (match_dup 0) (pc))
11542 (lt (minus (match_dup 0) (pc))
11546 (set_attr "maybe_prefix_bnd" "1")])
11548 (define_expand "indirect_jump"
11549 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11553 operands[0] = convert_memory_address (word_mode, operands[0]);
11556 (define_insn "*indirect_jump"
11557 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11560 [(set_attr "type" "ibr")
11561 (set_attr "length_immediate" "0")
11562 (set_attr "maybe_prefix_bnd" "1")])
11564 (define_expand "tablejump"
11565 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11566 (use (label_ref (match_operand 1)))])]
11569 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11570 relative. Convert the relative address to an absolute address. */
11574 enum rtx_code code;
11576 /* We can't use @GOTOFF for text labels on VxWorks;
11577 see gotoff_operand. */
11578 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11582 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11584 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11588 op1 = pic_offset_table_rtx;
11593 op0 = pic_offset_table_rtx;
11597 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11602 operands[0] = convert_memory_address (word_mode, operands[0]);
11605 (define_insn "*tablejump_1"
11606 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11607 (use (label_ref (match_operand 1)))]
11610 [(set_attr "type" "ibr")
11611 (set_attr "length_immediate" "0")
11612 (set_attr "maybe_prefix_bnd" "1")])
11614 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11617 [(set (reg FLAGS_REG) (match_operand 0))
11618 (set (match_operand:QI 1 "register_operand")
11619 (match_operator:QI 2 "ix86_comparison_operator"
11620 [(reg FLAGS_REG) (const_int 0)]))
11621 (set (match_operand 3 "any_QIreg_operand")
11622 (zero_extend (match_dup 1)))]
11623 "(peep2_reg_dead_p (3, operands[1])
11624 || operands_match_p (operands[1], operands[3]))
11625 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11626 [(set (match_dup 4) (match_dup 0))
11627 (set (strict_low_part (match_dup 5))
11630 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11631 operands[5] = gen_lowpart (QImode, operands[3]);
11632 ix86_expand_clear (operands[3]);
11636 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11637 (match_operand 4)])
11638 (set (match_operand:QI 1 "register_operand")
11639 (match_operator:QI 2 "ix86_comparison_operator"
11640 [(reg FLAGS_REG) (const_int 0)]))
11641 (set (match_operand 3 "any_QIreg_operand")
11642 (zero_extend (match_dup 1)))]
11643 "(peep2_reg_dead_p (3, operands[1])
11644 || operands_match_p (operands[1], operands[3]))
11645 && ! reg_overlap_mentioned_p (operands[3], operands[0])
11646 && ! reg_set_p (operands[3], operands[4])"
11647 [(parallel [(set (match_dup 5) (match_dup 0))
11649 (set (strict_low_part (match_dup 6))
11652 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11653 operands[6] = gen_lowpart (QImode, operands[3]);
11654 ix86_expand_clear (operands[3]);
11657 ;; Similar, but match zero extend with andsi3.
11660 [(set (reg FLAGS_REG) (match_operand 0))
11661 (set (match_operand:QI 1 "register_operand")
11662 (match_operator:QI 2 "ix86_comparison_operator"
11663 [(reg FLAGS_REG) (const_int 0)]))
11664 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
11665 (and:SI (match_dup 3) (const_int 255)))
11666 (clobber (reg:CC FLAGS_REG))])]
11667 "REGNO (operands[1]) == REGNO (operands[3])
11668 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11669 [(set (match_dup 4) (match_dup 0))
11670 (set (strict_low_part (match_dup 5))
11673 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11674 operands[5] = gen_lowpart (QImode, operands[3]);
11675 ix86_expand_clear (operands[3]);
11679 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11680 (match_operand 4)])
11681 (set (match_operand:QI 1 "register_operand")
11682 (match_operator:QI 2 "ix86_comparison_operator"
11683 [(reg FLAGS_REG) (const_int 0)]))
11684 (parallel [(set (match_operand 3 "any_QIreg_operand")
11685 (zero_extend (match_dup 1)))
11686 (clobber (reg:CC FLAGS_REG))])]
11687 "(peep2_reg_dead_p (3, operands[1])
11688 || operands_match_p (operands[1], operands[3]))
11689 && ! reg_overlap_mentioned_p (operands[3], operands[0])
11690 && ! reg_set_p (operands[3], operands[4])"
11691 [(parallel [(set (match_dup 5) (match_dup 0))
11693 (set (strict_low_part (match_dup 6))
11696 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11697 operands[6] = gen_lowpart (QImode, operands[3]);
11698 ix86_expand_clear (operands[3]);
11701 ;; Call instructions.
11703 ;; The predicates normally associated with named expanders are not properly
11704 ;; checked for calls. This is a bug in the generic code, but it isn't that
11705 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11707 ;; P6 processors will jump to the address after the decrement when %esp
11708 ;; is used as a call operand, so they will execute return address as a code.
11709 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11711 ;; Register constraint for call instruction.
11712 (define_mode_attr c [(SI "l") (DI "r")])
11714 ;; Call subroutine returning no value.
11716 (define_expand "call"
11717 [(call (match_operand:QI 0)
11719 (use (match_operand 2))]
11722 ix86_expand_call (NULL, operands[0], operands[1],
11723 operands[2], NULL, false);
11727 (define_expand "sibcall"
11728 [(call (match_operand:QI 0)
11730 (use (match_operand 2))]
11733 ix86_expand_call (NULL, operands[0], operands[1],
11734 operands[2], NULL, true);
11738 (define_insn "*call"
11739 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11740 (match_operand 1))]
11741 "!SIBLING_CALL_P (insn)"
11742 "* return ix86_output_call_insn (insn, operands[0]);"
11743 [(set_attr "type" "call")])
11745 ;; This covers both call and sibcall since only GOT slot is allowed.
11746 (define_insn "*call_got_x32"
11747 [(call (mem:QI (zero_extend:DI
11748 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
11749 (match_operand 1))]
11752 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
11753 return ix86_output_call_insn (insn, fnaddr);
11755 [(set_attr "type" "call")])
11757 ;; Since sibcall never returns, we can only use call-clobbered register
11759 (define_insn "*sibcall_GOT_32"
11762 (match_operand:SI 0 "register_no_elim_operand" "U")
11763 (match_operand:SI 1 "GOT32_symbol_operand"))))
11764 (match_operand 2))]
11765 "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11767 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
11768 fnaddr = gen_const_mem (SImode, fnaddr);
11769 return ix86_output_call_insn (insn, fnaddr);
11771 [(set_attr "type" "call")])
11773 (define_insn "*sibcall"
11774 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11775 (match_operand 1))]
11776 "SIBLING_CALL_P (insn)"
11777 "* return ix86_output_call_insn (insn, operands[0]);"
11778 [(set_attr "type" "call")])
11780 (define_insn "*sibcall_memory"
11781 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11783 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11785 "* return ix86_output_call_insn (insn, operands[0]);"
11786 [(set_attr "type" "call")])
11789 [(set (match_operand:W 0 "register_operand")
11790 (match_operand:W 1 "memory_operand"))
11791 (call (mem:QI (match_dup 0))
11792 (match_operand 3))]
11793 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11794 && !reg_mentioned_p (operands[0],
11795 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
11796 [(parallel [(call (mem:QI (match_dup 1))
11798 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11801 [(set (match_operand:W 0 "register_operand")
11802 (match_operand:W 1 "memory_operand"))
11803 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11804 (call (mem:QI (match_dup 0))
11805 (match_operand 3))]
11806 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11807 && !reg_mentioned_p (operands[0],
11808 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
11809 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11810 (parallel [(call (mem:QI (match_dup 1))
11812 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11814 (define_expand "call_pop"
11815 [(parallel [(call (match_operand:QI 0)
11816 (match_operand:SI 1))
11817 (set (reg:SI SP_REG)
11818 (plus:SI (reg:SI SP_REG)
11819 (match_operand:SI 3)))])]
11822 ix86_expand_call (NULL, operands[0], operands[1],
11823 operands[2], operands[3], false);
11827 (define_insn "*call_pop"
11828 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
11830 (set (reg:SI SP_REG)
11831 (plus:SI (reg:SI SP_REG)
11832 (match_operand:SI 2 "immediate_operand" "i")))]
11833 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11834 "* return ix86_output_call_insn (insn, operands[0]);"
11835 [(set_attr "type" "call")])
11837 (define_insn "*sibcall_pop"
11838 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
11840 (set (reg:SI SP_REG)
11841 (plus:SI (reg:SI SP_REG)
11842 (match_operand:SI 2 "immediate_operand" "i")))]
11843 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11844 "* return ix86_output_call_insn (insn, operands[0]);"
11845 [(set_attr "type" "call")])
11847 (define_insn "*sibcall_pop_memory"
11848 [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
11850 (set (reg:SI SP_REG)
11851 (plus:SI (reg:SI SP_REG)
11852 (match_operand:SI 2 "immediate_operand" "i")))
11853 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11855 "* return ix86_output_call_insn (insn, operands[0]);"
11856 [(set_attr "type" "call")])
11859 [(set (match_operand:SI 0 "register_operand")
11860 (match_operand:SI 1 "memory_operand"))
11861 (parallel [(call (mem:QI (match_dup 0))
11863 (set (reg:SI SP_REG)
11864 (plus:SI (reg:SI SP_REG)
11865 (match_operand:SI 4 "immediate_operand")))])]
11866 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11867 && !reg_mentioned_p (operands[0],
11868 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
11869 [(parallel [(call (mem:QI (match_dup 1))
11871 (set (reg:SI SP_REG)
11872 (plus:SI (reg:SI SP_REG)
11874 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11877 [(set (match_operand:SI 0 "register_operand")
11878 (match_operand:SI 1 "memory_operand"))
11879 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11880 (parallel [(call (mem:QI (match_dup 0))
11882 (set (reg:SI SP_REG)
11883 (plus:SI (reg:SI SP_REG)
11884 (match_operand:SI 4 "immediate_operand")))])]
11885 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11886 && !reg_mentioned_p (operands[0],
11887 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
11888 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11889 (parallel [(call (mem:QI (match_dup 1))
11891 (set (reg:SI SP_REG)
11892 (plus:SI (reg:SI SP_REG)
11894 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11896 ;; Combining simple memory jump instruction
11899 [(set (match_operand:W 0 "register_operand")
11900 (match_operand:W 1 "memory_operand"))
11901 (set (pc) (match_dup 0))]
11902 "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
11903 [(set (pc) (match_dup 1))])
11905 ;; Call subroutine, returning value in operand 0
11907 (define_expand "call_value"
11908 [(set (match_operand 0)
11909 (call (match_operand:QI 1)
11910 (match_operand 2)))
11911 (use (match_operand 3))]
11914 ix86_expand_call (operands[0], operands[1], operands[2],
11915 operands[3], NULL, false);
11919 (define_expand "sibcall_value"
11920 [(set (match_operand 0)
11921 (call (match_operand:QI 1)
11922 (match_operand 2)))
11923 (use (match_operand 3))]
11926 ix86_expand_call (operands[0], operands[1], operands[2],
11927 operands[3], NULL, true);
11931 (define_insn "*call_value"
11932 [(set (match_operand 0)
11933 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
11934 (match_operand 2)))]
11935 "!SIBLING_CALL_P (insn)"
11936 "* return ix86_output_call_insn (insn, operands[1]);"
11937 [(set_attr "type" "callv")])
11939 ;; This covers both call and sibcall since only GOT slot is allowed.
11940 (define_insn "*call_value_got_x32"
11941 [(set (match_operand 0)
11944 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
11945 (match_operand 2)))]
11948 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
11949 return ix86_output_call_insn (insn, fnaddr);
11951 [(set_attr "type" "callv")])
11953 ;; Since sibcall never returns, we can only use call-clobbered register
11955 (define_insn "*sibcall_value_GOT_32"
11956 [(set (match_operand 0)
11959 (match_operand:SI 1 "register_no_elim_operand" "U")
11960 (match_operand:SI 2 "GOT32_symbol_operand"))))
11961 (match_operand 3)))]
11962 "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11964 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
11965 fnaddr = gen_const_mem (SImode, fnaddr);
11966 return ix86_output_call_insn (insn, fnaddr);
11968 [(set_attr "type" "callv")])
11970 (define_insn "*sibcall_value"
11971 [(set (match_operand 0)
11972 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
11973 (match_operand 2)))]
11974 "SIBLING_CALL_P (insn)"
11975 "* return ix86_output_call_insn (insn, operands[1]);"
11976 [(set_attr "type" "callv")])
11978 (define_insn "*sibcall_value_memory"
11979 [(set (match_operand 0)
11980 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
11981 (match_operand 2)))
11982 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11984 "* return ix86_output_call_insn (insn, operands[1]);"
11985 [(set_attr "type" "callv")])
11988 [(set (match_operand:W 0 "register_operand")
11989 (match_operand:W 1 "memory_operand"))
11990 (set (match_operand 2)
11991 (call (mem:QI (match_dup 0))
11992 (match_operand 3)))]
11993 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11994 && !reg_mentioned_p (operands[0],
11995 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
11996 [(parallel [(set (match_dup 2)
11997 (call (mem:QI (match_dup 1))
11999 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12002 [(set (match_operand:W 0 "register_operand")
12003 (match_operand:W 1 "memory_operand"))
12004 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12005 (set (match_operand 2)
12006 (call (mem:QI (match_dup 0))
12007 (match_operand 3)))]
12008 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
12009 && !reg_mentioned_p (operands[0],
12010 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12011 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12012 (parallel [(set (match_dup 2)
12013 (call (mem:QI (match_dup 1))
12015 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12017 (define_expand "call_value_pop"
12018 [(parallel [(set (match_operand 0)
12019 (call (match_operand:QI 1)
12020 (match_operand:SI 2)))
12021 (set (reg:SI SP_REG)
12022 (plus:SI (reg:SI SP_REG)
12023 (match_operand:SI 4)))])]
12026 ix86_expand_call (operands[0], operands[1], operands[2],
12027 operands[3], operands[4], false);
12031 (define_insn "*call_value_pop"
12032 [(set (match_operand 0)
12033 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
12034 (match_operand 2)))
12035 (set (reg:SI SP_REG)
12036 (plus:SI (reg:SI SP_REG)
12037 (match_operand:SI 3 "immediate_operand" "i")))]
12038 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12039 "* return ix86_output_call_insn (insn, operands[1]);"
12040 [(set_attr "type" "callv")])
12042 (define_insn "*sibcall_value_pop"
12043 [(set (match_operand 0)
12044 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
12045 (match_operand 2)))
12046 (set (reg:SI SP_REG)
12047 (plus:SI (reg:SI SP_REG)
12048 (match_operand:SI 3 "immediate_operand" "i")))]
12049 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12050 "* return ix86_output_call_insn (insn, operands[1]);"
12051 [(set_attr "type" "callv")])
12053 (define_insn "*sibcall_value_pop_memory"
12054 [(set (match_operand 0)
12055 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
12056 (match_operand 2)))
12057 (set (reg:SI SP_REG)
12058 (plus:SI (reg:SI SP_REG)
12059 (match_operand:SI 3 "immediate_operand" "i")))
12060 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12062 "* return ix86_output_call_insn (insn, operands[1]);"
12063 [(set_attr "type" "callv")])
12066 [(set (match_operand:SI 0 "register_operand")
12067 (match_operand:SI 1 "memory_operand"))
12068 (parallel [(set (match_operand 2)
12069 (call (mem:QI (match_dup 0))
12070 (match_operand 3)))
12071 (set (reg:SI SP_REG)
12072 (plus:SI (reg:SI SP_REG)
12073 (match_operand:SI 4 "immediate_operand")))])]
12074 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12075 && !reg_mentioned_p (operands[0],
12076 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12077 [(parallel [(set (match_dup 2)
12078 (call (mem:QI (match_dup 1))
12080 (set (reg:SI SP_REG)
12081 (plus:SI (reg:SI SP_REG)
12083 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12086 [(set (match_operand:SI 0 "register_operand")
12087 (match_operand:SI 1 "memory_operand"))
12088 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12089 (parallel [(set (match_operand 2)
12090 (call (mem:QI (match_dup 0))
12091 (match_operand 3)))
12092 (set (reg:SI SP_REG)
12093 (plus:SI (reg:SI SP_REG)
12094 (match_operand:SI 4 "immediate_operand")))])]
12095 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12096 && !reg_mentioned_p (operands[0],
12097 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12098 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12099 (parallel [(set (match_dup 2)
12100 (call (mem:QI (match_dup 1))
12102 (set (reg:SI SP_REG)
12103 (plus:SI (reg:SI SP_REG)
12105 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12107 ;; Call subroutine returning any type.
12109 (define_expand "untyped_call"
12110 [(parallel [(call (match_operand 0)
12113 (match_operand 2)])]
12118 /* In order to give reg-stack an easier job in validating two
12119 coprocessor registers as containing a possible return value,
12120 simply pretend the untyped call returns a complex long double
12123 We can't use SSE_REGPARM_MAX here since callee is unprototyped
12124 and should have the default ABI. */
12126 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12127 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12128 operands[0], const0_rtx,
12129 GEN_INT ((TARGET_64BIT
12130 ? (ix86_abi == SYSV_ABI
12131 ? X86_64_SSE_REGPARM_MAX
12132 : X86_64_MS_SSE_REGPARM_MAX)
12133 : X86_32_SSE_REGPARM_MAX)
12137 for (i = 0; i < XVECLEN (operands[2], 0); i++)
12139 rtx set = XVECEXP (operands[2], 0, i);
12140 emit_move_insn (SET_DEST (set), SET_SRC (set));
12143 /* The optimizer does not know that the call sets the function value
12144 registers we stored in the result block. We avoid problems by
12145 claiming that all hard registers are used and clobbered at this
12147 emit_insn (gen_blockage ());
12152 ;; Prologue and epilogue instructions
12154 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12155 ;; all of memory. This blocks insns from being moved across this point.
12157 (define_insn "blockage"
12158 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12161 [(set_attr "length" "0")])
12163 ;; Do not schedule instructions accessing memory across this point.
12165 (define_expand "memory_blockage"
12166 [(set (match_dup 0)
12167 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12170 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12171 MEM_VOLATILE_P (operands[0]) = 1;
12174 (define_insn "*memory_blockage"
12175 [(set (match_operand:BLK 0)
12176 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12179 [(set_attr "length" "0")])
12181 ;; As USE insns aren't meaningful after reload, this is used instead
12182 ;; to prevent deleting instructions setting registers for PIC code
12183 (define_insn "prologue_use"
12184 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12187 [(set_attr "length" "0")])
12189 ;; Insn emitted into the body of a function to return from a function.
12190 ;; This is only done if the function's epilogue is known to be simple.
12191 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12193 (define_expand "return"
12195 "ix86_can_use_return_insn_p ()"
12197 if (crtl->args.pops_args)
12199 rtx popc = GEN_INT (crtl->args.pops_args);
12200 emit_jump_insn (gen_simple_return_pop_internal (popc));
12205 ;; We need to disable this for TARGET_SEH, as otherwise
12206 ;; shrink-wrapped prologue gets enabled too. This might exceed
12207 ;; the maximum size of prologue in unwind information.
12208 ;; Also disallow shrink-wrapping if using stack slot to pass the
12209 ;; static chain pointer - the first instruction has to be pushl %esi
12210 ;; and it can't be moved around, as we use alternate entry points
12213 (define_expand "simple_return"
12215 "!TARGET_SEH && !ix86_static_chain_on_stack"
12217 if (crtl->args.pops_args)
12219 rtx popc = GEN_INT (crtl->args.pops_args);
12220 emit_jump_insn (gen_simple_return_pop_internal (popc));
12225 (define_insn "simple_return_internal"
12229 [(set_attr "length" "1")
12230 (set_attr "atom_unit" "jeu")
12231 (set_attr "length_immediate" "0")
12232 (set_attr "modrm" "0")
12233 (set_attr "maybe_prefix_bnd" "1")])
12235 (define_insn "interrupt_return"
12237 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
12240 return TARGET_64BIT ? "iretq" : "iret";
12243 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12244 ;; instruction Athlon and K8 have.
12246 (define_insn "simple_return_internal_long"
12248 (unspec [(const_int 0)] UNSPEC_REP)]
12251 if (ix86_bnd_prefixed_insn_p (insn))
12254 return "rep%; ret";
12256 [(set_attr "length" "2")
12257 (set_attr "atom_unit" "jeu")
12258 (set_attr "length_immediate" "0")
12259 (set_attr "prefix_rep" "1")
12260 (set_attr "modrm" "0")])
12262 (define_insn "simple_return_pop_internal"
12264 (use (match_operand:SI 0 "const_int_operand"))]
12267 [(set_attr "length" "3")
12268 (set_attr "atom_unit" "jeu")
12269 (set_attr "length_immediate" "2")
12270 (set_attr "modrm" "0")
12271 (set_attr "maybe_prefix_bnd" "1")])
12273 (define_insn "simple_return_indirect_internal"
12275 (use (match_operand:SI 0 "register_operand" "r"))]
12278 [(set_attr "type" "ibr")
12279 (set_attr "length_immediate" "0")
12280 (set_attr "maybe_prefix_bnd" "1")])
12286 [(set_attr "length" "1")
12287 (set_attr "length_immediate" "0")
12288 (set_attr "modrm" "0")])
12290 ;; Generate nops. Operand 0 is the number of nops, up to 8.
12291 (define_insn "nops"
12292 [(unspec_volatile [(match_operand 0 "const_int_operand")]
12296 int num = INTVAL (operands[0]);
12298 gcc_assert (IN_RANGE (num, 1, 8));
12301 fputs ("\tnop\n", asm_out_file);
12305 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12306 (set_attr "length_immediate" "0")
12307 (set_attr "modrm" "0")])
12309 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12310 ;; branch prediction penalty for the third jump in a 16-byte
12314 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12317 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12318 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12320 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12321 The align insn is used to avoid 3 jump instructions in the row to improve
12322 branch prediction and the benefits hardly outweigh the cost of extra 8
12323 nops on the average inserted by full alignment pseudo operation. */
12327 [(set_attr "length" "16")])
12329 (define_expand "prologue"
12332 "ix86_expand_prologue (); DONE;")
12334 (define_expand "set_got"
12336 [(set (match_operand:SI 0 "register_operand")
12337 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12338 (clobber (reg:CC FLAGS_REG))])]
12341 if (flag_pic && !TARGET_VXWORKS_RTP)
12342 ix86_pc_thunk_call_expanded = true;
12345 (define_insn "*set_got"
12346 [(set (match_operand:SI 0 "register_operand" "=r")
12347 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12348 (clobber (reg:CC FLAGS_REG))]
12350 "* return output_set_got (operands[0], NULL_RTX);"
12351 [(set_attr "type" "multi")
12352 (set_attr "length" "12")])
12354 (define_expand "set_got_labelled"
12356 [(set (match_operand:SI 0 "register_operand")
12357 (unspec:SI [(label_ref (match_operand 1))]
12359 (clobber (reg:CC FLAGS_REG))])]
12362 if (flag_pic && !TARGET_VXWORKS_RTP)
12363 ix86_pc_thunk_call_expanded = true;
12366 (define_insn "*set_got_labelled"
12367 [(set (match_operand:SI 0 "register_operand" "=r")
12368 (unspec:SI [(label_ref (match_operand 1))]
12370 (clobber (reg:CC FLAGS_REG))]
12372 "* return output_set_got (operands[0], operands[1]);"
12373 [(set_attr "type" "multi")
12374 (set_attr "length" "12")])
12376 (define_insn "set_got_rex64"
12377 [(set (match_operand:DI 0 "register_operand" "=r")
12378 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12380 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12381 [(set_attr "type" "lea")
12382 (set_attr "length_address" "4")
12383 (set_attr "modrm_class" "unknown")
12384 (set_attr "mode" "DI")])
12386 (define_insn "set_rip_rex64"
12387 [(set (match_operand:DI 0 "register_operand" "=r")
12388 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12390 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12391 [(set_attr "type" "lea")
12392 (set_attr "length_address" "4")
12393 (set_attr "mode" "DI")])
12395 (define_insn "set_got_offset_rex64"
12396 [(set (match_operand:DI 0 "register_operand" "=r")
12398 [(label_ref (match_operand 1))]
12399 UNSPEC_SET_GOT_OFFSET))]
12401 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12402 [(set_attr "type" "imov")
12403 (set_attr "length_immediate" "0")
12404 (set_attr "length_address" "8")
12405 (set_attr "mode" "DI")])
12407 (define_expand "epilogue"
12410 "ix86_expand_epilogue (1); DONE;")
12412 (define_expand "sibcall_epilogue"
12415 "ix86_expand_epilogue (0); DONE;")
12417 (define_expand "eh_return"
12418 [(use (match_operand 0 "register_operand"))]
12421 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12423 /* Tricky bit: we write the address of the handler to which we will
12424 be returning into someone else's stack frame, one word below the
12425 stack address we wish to restore. */
12426 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12427 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12428 tmp = gen_rtx_MEM (Pmode, tmp);
12429 emit_move_insn (tmp, ra);
12431 emit_jump_insn (gen_eh_return_internal ());
12436 (define_insn_and_split "eh_return_internal"
12440 "epilogue_completed"
12442 "ix86_expand_epilogue (2); DONE;")
12444 (define_insn "leave"
12445 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12446 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12447 (clobber (mem:BLK (scratch)))]
12450 [(set_attr "type" "leave")])
12452 (define_insn "leave_rex64"
12453 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12454 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12455 (clobber (mem:BLK (scratch)))]
12458 [(set_attr "type" "leave")])
12460 ;; Handle -fsplit-stack.
12462 (define_expand "split_stack_prologue"
12466 ix86_expand_split_stack_prologue ();
12470 ;; In order to support the call/return predictor, we use a return
12471 ;; instruction which the middle-end doesn't see.
12472 (define_insn "split_stack_return"
12473 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12474 UNSPECV_SPLIT_STACK_RETURN)]
12477 if (operands[0] == const0_rtx)
12482 [(set_attr "atom_unit" "jeu")
12483 (set_attr "modrm" "0")
12484 (set (attr "length")
12485 (if_then_else (match_operand:SI 0 "const0_operand")
12488 (set (attr "length_immediate")
12489 (if_then_else (match_operand:SI 0 "const0_operand")
12493 ;; If there are operand 0 bytes available on the stack, jump to
12496 (define_expand "split_stack_space_check"
12497 [(set (pc) (if_then_else
12498 (ltu (minus (reg SP_REG)
12499 (match_operand 0 "register_operand"))
12500 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12501 (label_ref (match_operand 1))
12505 rtx reg, size, limit;
12507 reg = gen_reg_rtx (Pmode);
12508 size = force_reg (Pmode, operands[0]);
12509 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12510 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12511 UNSPEC_STACK_CHECK);
12512 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12513 ix86_expand_branch (GEU, reg, limit, operands[1]);
12518 ;; Bit manipulation instructions.
12520 (define_expand "ffs<mode>2"
12521 [(set (match_dup 2) (const_int -1))
12522 (parallel [(set (match_dup 3) (match_dup 4))
12523 (set (match_operand:SWI48 0 "register_operand")
12525 (match_operand:SWI48 1 "nonimmediate_operand")))])
12526 (set (match_dup 0) (if_then_else:SWI48
12527 (eq (match_dup 3) (const_int 0))
12530 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12531 (clobber (reg:CC FLAGS_REG))])]
12534 machine_mode flags_mode;
12536 if (<MODE>mode == SImode && !TARGET_CMOVE)
12538 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12542 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12544 operands[2] = gen_reg_rtx (<MODE>mode);
12545 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12546 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12549 (define_insn_and_split "ffssi2_no_cmove"
12550 [(set (match_operand:SI 0 "register_operand" "=r")
12551 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12552 (clobber (match_scratch:SI 2 "=&q"))
12553 (clobber (reg:CC FLAGS_REG))]
12556 "&& reload_completed"
12557 [(parallel [(set (match_dup 4) (match_dup 5))
12558 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12559 (set (strict_low_part (match_dup 3))
12560 (eq:QI (match_dup 4) (const_int 0)))
12561 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12562 (clobber (reg:CC FLAGS_REG))])
12563 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12564 (clobber (reg:CC FLAGS_REG))])
12565 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12566 (clobber (reg:CC FLAGS_REG))])]
12568 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12570 operands[3] = gen_lowpart (QImode, operands[2]);
12571 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12572 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12574 ix86_expand_clear (operands[2]);
12577 (define_insn_and_split "*tzcnt<mode>_1"
12578 [(set (reg:CCC FLAGS_REG)
12579 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12581 (set (match_operand:SWI48 0 "register_operand" "=r")
12582 (ctz:SWI48 (match_dup 1)))]
12584 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12585 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
12586 && optimize_function_for_speed_p (cfun)
12587 && !reg_mentioned_p (operands[0], operands[1])"
12589 [(set (reg:CCC FLAGS_REG)
12590 (compare:CCC (match_dup 1) (const_int 0)))
12592 (ctz:SWI48 (match_dup 1)))
12593 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
12594 "ix86_expand_clear (operands[0]);"
12595 [(set_attr "type" "alu1")
12596 (set_attr "prefix_0f" "1")
12597 (set_attr "prefix_rep" "1")
12598 (set_attr "btver2_decode" "double")
12599 (set_attr "mode" "<MODE>")])
12601 ; False dependency happens when destination is only updated by tzcnt,
12602 ; lzcnt or popcnt. There is no false dependency when destination is
12603 ; also used in source.
12604 (define_insn "*tzcnt<mode>_1_falsedep"
12605 [(set (reg:CCC FLAGS_REG)
12606 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12608 (set (match_operand:SWI48 0 "register_operand" "=r")
12609 (ctz:SWI48 (match_dup 1)))
12610 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12611 UNSPEC_INSN_FALSE_DEP)]
12613 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12614 [(set_attr "type" "alu1")
12615 (set_attr "prefix_0f" "1")
12616 (set_attr "prefix_rep" "1")
12617 (set_attr "btver2_decode" "double")
12618 (set_attr "mode" "<MODE>")])
12620 (define_insn "*bsf<mode>_1"
12621 [(set (reg:CCZ FLAGS_REG)
12622 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12624 (set (match_operand:SWI48 0 "register_operand" "=r")
12625 (ctz:SWI48 (match_dup 1)))]
12627 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12628 [(set_attr "type" "alu1")
12629 (set_attr "prefix_0f" "1")
12630 (set_attr "btver2_decode" "double")
12631 (set_attr "znver1_decode" "vector")
12632 (set_attr "mode" "<MODE>")])
12634 (define_insn_and_split "*ctzhi2"
12635 [(set (match_operand:SI 0 "register_operand")
12637 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
12638 (clobber (reg:CC FLAGS_REG))]
12640 && can_create_pseudo_p ()"
12645 rtx tmp = gen_reg_rtx (HImode);
12647 emit_insn (gen_tzcnt_hi (tmp, operands[1]));
12648 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
12652 (define_insn_and_split "ctz<mode>2"
12653 [(set (match_operand:SWI48 0 "register_operand" "=r")
12655 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12656 (clobber (reg:CC FLAGS_REG))]
12660 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12661 else if (optimize_function_for_size_p (cfun))
12663 else if (TARGET_GENERIC)
12664 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12665 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12667 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12669 "(TARGET_BMI || TARGET_GENERIC)
12670 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
12671 && optimize_function_for_speed_p (cfun)
12672 && !reg_mentioned_p (operands[0], operands[1])"
12674 [(set (match_dup 0)
12675 (ctz:SWI48 (match_dup 1)))
12676 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12677 (clobber (reg:CC FLAGS_REG))])]
12678 "ix86_expand_clear (operands[0]);"
12679 [(set_attr "type" "alu1")
12680 (set_attr "prefix_0f" "1")
12681 (set (attr "prefix_rep")
12683 (ior (match_test "TARGET_BMI")
12684 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12685 (match_test "TARGET_GENERIC")))
12687 (const_string "0")))
12688 (set_attr "mode" "<MODE>")])
12690 ; False dependency happens when destination is only updated by tzcnt,
12691 ; lzcnt or popcnt. There is no false dependency when destination is
12692 ; also used in source.
12693 (define_insn "*ctz<mode>2_falsedep"
12694 [(set (match_operand:SWI48 0 "register_operand" "=r")
12696 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12697 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12698 UNSPEC_INSN_FALSE_DEP)
12699 (clobber (reg:CC FLAGS_REG))]
12703 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12704 else if (TARGET_GENERIC)
12705 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12706 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12708 gcc_unreachable ();
12710 [(set_attr "type" "alu1")
12711 (set_attr "prefix_0f" "1")
12712 (set_attr "prefix_rep" "1")
12713 (set_attr "mode" "<MODE>")])
12715 (define_insn "bsr_rex64"
12716 [(set (match_operand:DI 0 "register_operand" "=r")
12717 (minus:DI (const_int 63)
12718 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12719 (clobber (reg:CC FLAGS_REG))]
12721 "bsr{q}\t{%1, %0|%0, %1}"
12722 [(set_attr "type" "alu1")
12723 (set_attr "prefix_0f" "1")
12724 (set_attr "znver1_decode" "vector")
12725 (set_attr "mode" "DI")])
12728 [(set (match_operand:SI 0 "register_operand" "=r")
12729 (minus:SI (const_int 31)
12730 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12731 (clobber (reg:CC FLAGS_REG))]
12733 "bsr{l}\t{%1, %0|%0, %1}"
12734 [(set_attr "type" "alu1")
12735 (set_attr "prefix_0f" "1")
12736 (set_attr "znver1_decode" "vector")
12737 (set_attr "mode" "SI")])
12739 (define_insn "*bsrhi"
12740 [(set (match_operand:HI 0 "register_operand" "=r")
12741 (minus:HI (const_int 15)
12742 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12743 (clobber (reg:CC FLAGS_REG))]
12745 "bsr{w}\t{%1, %0|%0, %1}"
12746 [(set_attr "type" "alu1")
12747 (set_attr "prefix_0f" "1")
12748 (set_attr "znver1_decode" "vector")
12749 (set_attr "mode" "HI")])
12751 (define_expand "clz<mode>2"
12753 [(set (match_operand:SWI48 0 "register_operand")
12756 (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
12757 (clobber (reg:CC FLAGS_REG))])
12759 [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
12760 (clobber (reg:CC FLAGS_REG))])]
12765 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12768 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12771 (define_insn_and_split "*clzhi2"
12772 [(set (match_operand:SI 0 "register_operand")
12774 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
12775 (clobber (reg:CC FLAGS_REG))]
12777 && can_create_pseudo_p ()"
12782 rtx tmp = gen_reg_rtx (HImode);
12784 emit_insn (gen_lzcnt_hi (tmp, operands[1]));
12785 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
12789 (define_insn_and_split "clz<mode>2_lzcnt"
12790 [(set (match_operand:SWI48 0 "register_operand" "=r")
12792 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12793 (clobber (reg:CC FLAGS_REG))]
12795 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12796 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
12797 && optimize_function_for_speed_p (cfun)
12798 && !reg_mentioned_p (operands[0], operands[1])"
12800 [(set (match_dup 0)
12801 (clz:SWI48 (match_dup 1)))
12802 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12803 (clobber (reg:CC FLAGS_REG))])]
12804 "ix86_expand_clear (operands[0]);"
12805 [(set_attr "prefix_rep" "1")
12806 (set_attr "type" "bitmanip")
12807 (set_attr "mode" "<MODE>")])
12809 ; False dependency happens when destination is only updated by tzcnt,
12810 ; lzcnt or popcnt. There is no false dependency when destination is
12811 ; also used in source.
12812 (define_insn "*clz<mode>2_lzcnt_falsedep"
12813 [(set (match_operand:SWI48 0 "register_operand" "=r")
12815 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12816 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12817 UNSPEC_INSN_FALSE_DEP)
12818 (clobber (reg:CC FLAGS_REG))]
12820 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12821 [(set_attr "prefix_rep" "1")
12822 (set_attr "type" "bitmanip")
12823 (set_attr "mode" "<MODE>")])
12825 (define_int_iterator LT_ZCNT
12826 [(UNSPEC_TZCNT "TARGET_BMI")
12827 (UNSPEC_LZCNT "TARGET_LZCNT")])
12829 (define_int_attr lt_zcnt
12830 [(UNSPEC_TZCNT "tzcnt")
12831 (UNSPEC_LZCNT "lzcnt")])
12833 (define_int_attr lt_zcnt_type
12834 [(UNSPEC_TZCNT "alu1")
12835 (UNSPEC_LZCNT "bitmanip")])
12837 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
12838 ;; provides operand size as output when source operand is zero.
12840 (define_insn_and_split "<lt_zcnt>_<mode>"
12841 [(set (match_operand:SWI48 0 "register_operand" "=r")
12843 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
12844 (clobber (reg:CC FLAGS_REG))]
12846 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
12847 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
12848 && optimize_function_for_speed_p (cfun)
12849 && !reg_mentioned_p (operands[0], operands[1])"
12851 [(set (match_dup 0)
12852 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
12853 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12854 (clobber (reg:CC FLAGS_REG))])]
12855 "ix86_expand_clear (operands[0]);"
12856 [(set_attr "type" "<lt_zcnt_type>")
12857 (set_attr "prefix_0f" "1")
12858 (set_attr "prefix_rep" "1")
12859 (set_attr "mode" "<MODE>")])
12861 ; False dependency happens when destination is only updated by tzcnt,
12862 ; lzcnt or popcnt. There is no false dependency when destination is
12863 ; also used in source.
12864 (define_insn "*<lt_zcnt>_<mode>_falsedep"
12865 [(set (match_operand:SWI48 0 "register_operand" "=r")
12867 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
12868 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12869 UNSPEC_INSN_FALSE_DEP)
12870 (clobber (reg:CC FLAGS_REG))]
12872 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
12873 [(set_attr "type" "<lt_zcnt_type>")
12874 (set_attr "prefix_0f" "1")
12875 (set_attr "prefix_rep" "1")
12876 (set_attr "mode" "<MODE>")])
12878 (define_insn "<lt_zcnt>_hi"
12879 [(set (match_operand:HI 0 "register_operand" "=r")
12881 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
12882 (clobber (reg:CC FLAGS_REG))]
12884 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
12885 [(set_attr "type" "<lt_zcnt_type>")
12886 (set_attr "prefix_0f" "1")
12887 (set_attr "prefix_rep" "1")
12888 (set_attr "mode" "HI")])
12890 ;; BMI instructions.
12892 (define_insn "bmi_bextr_<mode>"
12893 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12894 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12895 (match_operand:SWI48 2 "register_operand" "r,r")]
12897 (clobber (reg:CC FLAGS_REG))]
12899 "bextr\t{%2, %1, %0|%0, %1, %2}"
12900 [(set_attr "type" "bitmanip")
12901 (set_attr "btver2_decode" "direct, double")
12902 (set_attr "mode" "<MODE>")])
12904 (define_insn "*bmi_bextr_<mode>_ccz"
12905 [(set (reg:CCZ FLAGS_REG)
12907 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12908 (match_operand:SWI48 2 "register_operand" "r,r")]
12911 (clobber (match_scratch:SWI48 0 "=r,r"))]
12913 "bextr\t{%2, %1, %0|%0, %1, %2}"
12914 [(set_attr "type" "bitmanip")
12915 (set_attr "btver2_decode" "direct, double")
12916 (set_attr "mode" "<MODE>")])
12918 (define_insn "*bmi_blsi_<mode>"
12919 [(set (match_operand:SWI48 0 "register_operand" "=r")
12922 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12924 (clobber (reg:CC FLAGS_REG))]
12926 "blsi\t{%1, %0|%0, %1}"
12927 [(set_attr "type" "bitmanip")
12928 (set_attr "btver2_decode" "double")
12929 (set_attr "mode" "<MODE>")])
12931 (define_insn "*bmi_blsmsk_<mode>"
12932 [(set (match_operand:SWI48 0 "register_operand" "=r")
12935 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12938 (clobber (reg:CC FLAGS_REG))]
12940 "blsmsk\t{%1, %0|%0, %1}"
12941 [(set_attr "type" "bitmanip")
12942 (set_attr "btver2_decode" "double")
12943 (set_attr "mode" "<MODE>")])
12945 (define_insn "*bmi_blsr_<mode>"
12946 [(set (match_operand:SWI48 0 "register_operand" "=r")
12949 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12952 (clobber (reg:CC FLAGS_REG))]
12954 "blsr\t{%1, %0|%0, %1}"
12955 [(set_attr "type" "bitmanip")
12956 (set_attr "btver2_decode" "double")
12957 (set_attr "mode" "<MODE>")])
12959 ;; BMI2 instructions.
12960 (define_expand "bmi2_bzhi_<mode>3"
12962 [(set (match_operand:SWI48 0 "register_operand")
12963 (zero_extract:SWI48
12964 (match_operand:SWI48 1 "nonimmediate_operand")
12966 (and:SWI48 (match_operand:SWI48 2 "register_operand")
12970 (clobber (reg:CC FLAGS_REG))])]
12972 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
12974 (define_insn "*bmi2_bzhi_<mode>3"
12975 [(set (match_operand:SWI48 0 "register_operand" "=r")
12976 (zero_extract:SWI48
12977 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12979 (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
12981 (match_operand:SWI48 3 "const_int_operand" "n"))
12983 (clobber (reg:CC FLAGS_REG))]
12984 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12985 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12986 [(set_attr "type" "bitmanip")
12987 (set_attr "prefix" "vex")
12988 (set_attr "mode" "<MODE>")])
12990 (define_mode_attr k [(SI "k") (DI "q")])
12992 (define_insn "*bmi2_bzhi_<mode>3_1"
12993 [(set (match_operand:SWI48 0 "register_operand" "=r")
12994 (zero_extract:SWI48
12995 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12997 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
12998 (match_operand:SWI48 3 "const_int_operand" "n"))
13000 (clobber (reg:CC FLAGS_REG))]
13001 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13002 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13003 [(set_attr "type" "bitmanip")
13004 (set_attr "prefix" "vex")
13005 (set_attr "mode" "<MODE>")])
13007 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
13008 [(set (reg:CCZ FLAGS_REG)
13010 (zero_extract:SWI48
13011 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13013 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13014 (match_operand:SWI48 3 "const_int_operand" "n"))
13017 (clobber (match_scratch:SWI48 0 "=r"))]
13018 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13019 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13020 [(set_attr "type" "bitmanip")
13021 (set_attr "prefix" "vex")
13022 (set_attr "mode" "<MODE>")])
13024 (define_insn "bmi2_pdep_<mode>3"
13025 [(set (match_operand:SWI48 0 "register_operand" "=r")
13026 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13027 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13030 "pdep\t{%2, %1, %0|%0, %1, %2}"
13031 [(set_attr "type" "bitmanip")
13032 (set_attr "prefix" "vex")
13033 (set_attr "mode" "<MODE>")])
13035 (define_insn "bmi2_pext_<mode>3"
13036 [(set (match_operand:SWI48 0 "register_operand" "=r")
13037 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13038 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13041 "pext\t{%2, %1, %0|%0, %1, %2}"
13042 [(set_attr "type" "bitmanip")
13043 (set_attr "prefix" "vex")
13044 (set_attr "mode" "<MODE>")])
13046 ;; TBM instructions.
13047 (define_insn "tbm_bextri_<mode>"
13048 [(set (match_operand:SWI48 0 "register_operand" "=r")
13049 (zero_extract:SWI48
13050 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13051 (match_operand 2 "const_0_to_255_operand" "N")
13052 (match_operand 3 "const_0_to_255_operand" "N")))
13053 (clobber (reg:CC FLAGS_REG))]
13056 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
13057 return "bextr\t{%2, %1, %0|%0, %1, %2}";
13059 [(set_attr "type" "bitmanip")
13060 (set_attr "mode" "<MODE>")])
13062 (define_insn "*tbm_blcfill_<mode>"
13063 [(set (match_operand:SWI48 0 "register_operand" "=r")
13066 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13069 (clobber (reg:CC FLAGS_REG))]
13071 "blcfill\t{%1, %0|%0, %1}"
13072 [(set_attr "type" "bitmanip")
13073 (set_attr "mode" "<MODE>")])
13075 (define_insn "*tbm_blci_<mode>"
13076 [(set (match_operand:SWI48 0 "register_operand" "=r")
13080 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13083 (clobber (reg:CC FLAGS_REG))]
13085 "blci\t{%1, %0|%0, %1}"
13086 [(set_attr "type" "bitmanip")
13087 (set_attr "mode" "<MODE>")])
13089 (define_insn "*tbm_blcic_<mode>"
13090 [(set (match_operand:SWI48 0 "register_operand" "=r")
13093 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13097 (clobber (reg:CC FLAGS_REG))]
13099 "blcic\t{%1, %0|%0, %1}"
13100 [(set_attr "type" "bitmanip")
13101 (set_attr "mode" "<MODE>")])
13103 (define_insn "*tbm_blcmsk_<mode>"
13104 [(set (match_operand:SWI48 0 "register_operand" "=r")
13107 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13110 (clobber (reg:CC FLAGS_REG))]
13112 "blcmsk\t{%1, %0|%0, %1}"
13113 [(set_attr "type" "bitmanip")
13114 (set_attr "mode" "<MODE>")])
13116 (define_insn "*tbm_blcs_<mode>"
13117 [(set (match_operand:SWI48 0 "register_operand" "=r")
13120 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13123 (clobber (reg:CC FLAGS_REG))]
13125 "blcs\t{%1, %0|%0, %1}"
13126 [(set_attr "type" "bitmanip")
13127 (set_attr "mode" "<MODE>")])
13129 (define_insn "*tbm_blsfill_<mode>"
13130 [(set (match_operand:SWI48 0 "register_operand" "=r")
13133 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13136 (clobber (reg:CC FLAGS_REG))]
13138 "blsfill\t{%1, %0|%0, %1}"
13139 [(set_attr "type" "bitmanip")
13140 (set_attr "mode" "<MODE>")])
13142 (define_insn "*tbm_blsic_<mode>"
13143 [(set (match_operand:SWI48 0 "register_operand" "=r")
13146 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13150 (clobber (reg:CC FLAGS_REG))]
13152 "blsic\t{%1, %0|%0, %1}"
13153 [(set_attr "type" "bitmanip")
13154 (set_attr "mode" "<MODE>")])
13156 (define_insn "*tbm_t1mskc_<mode>"
13157 [(set (match_operand:SWI48 0 "register_operand" "=r")
13160 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13164 (clobber (reg:CC FLAGS_REG))]
13166 "t1mskc\t{%1, %0|%0, %1}"
13167 [(set_attr "type" "bitmanip")
13168 (set_attr "mode" "<MODE>")])
13170 (define_insn "*tbm_tzmsk_<mode>"
13171 [(set (match_operand:SWI48 0 "register_operand" "=r")
13174 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13178 (clobber (reg:CC FLAGS_REG))]
13180 "tzmsk\t{%1, %0|%0, %1}"
13181 [(set_attr "type" "bitmanip")
13182 (set_attr "mode" "<MODE>")])
13184 (define_insn_and_split "popcount<mode>2"
13185 [(set (match_operand:SWI48 0 "register_operand" "=r")
13187 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13188 (clobber (reg:CC FLAGS_REG))]
13192 return "popcnt\t{%1, %0|%0, %1}";
13194 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13197 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13198 && optimize_function_for_speed_p (cfun)
13199 && !reg_mentioned_p (operands[0], operands[1])"
13201 [(set (match_dup 0)
13202 (popcount:SWI48 (match_dup 1)))
13203 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13204 (clobber (reg:CC FLAGS_REG))])]
13205 "ix86_expand_clear (operands[0]);"
13206 [(set_attr "prefix_rep" "1")
13207 (set_attr "type" "bitmanip")
13208 (set_attr "mode" "<MODE>")])
13210 ; False dependency happens when destination is only updated by tzcnt,
13211 ; lzcnt or popcnt. There is no false dependency when destination is
13212 ; also used in source.
13213 (define_insn "*popcount<mode>2_falsedep"
13214 [(set (match_operand:SWI48 0 "register_operand" "=r")
13216 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13217 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13218 UNSPEC_INSN_FALSE_DEP)
13219 (clobber (reg:CC FLAGS_REG))]
13223 return "popcnt\t{%1, %0|%0, %1}";
13225 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13228 [(set_attr "prefix_rep" "1")
13229 (set_attr "type" "bitmanip")
13230 (set_attr "mode" "<MODE>")])
13232 (define_insn_and_split "*popcounthi2_1"
13233 [(set (match_operand:SI 0 "register_operand")
13235 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
13236 (clobber (reg:CC FLAGS_REG))]
13238 && can_create_pseudo_p ()"
13243 rtx tmp = gen_reg_rtx (HImode);
13245 emit_insn (gen_popcounthi2 (tmp, operands[1]));
13246 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
13250 (define_insn "popcounthi2"
13251 [(set (match_operand:HI 0 "register_operand" "=r")
13253 (match_operand:HI 1 "nonimmediate_operand" "rm")))
13254 (clobber (reg:CC FLAGS_REG))]
13258 return "popcnt\t{%1, %0|%0, %1}";
13260 return "popcnt{w}\t{%1, %0|%0, %1}";
13263 [(set_attr "prefix_rep" "1")
13264 (set_attr "type" "bitmanip")
13265 (set_attr "mode" "HI")])
13267 (define_expand "bswapdi2"
13268 [(set (match_operand:DI 0 "register_operand")
13269 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
13273 operands[1] = force_reg (DImode, operands[1]);
13276 (define_expand "bswapsi2"
13277 [(set (match_operand:SI 0 "register_operand")
13278 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
13283 else if (TARGET_BSWAP)
13284 operands[1] = force_reg (SImode, operands[1]);
13287 rtx x = operands[0];
13289 emit_move_insn (x, operands[1]);
13290 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13291 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
13292 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13297 (define_insn "*bswap<mode>2_movbe"
13298 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
13299 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
13301 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13304 movbe\t{%1, %0|%0, %1}
13305 movbe\t{%1, %0|%0, %1}"
13306 [(set_attr "type" "bitmanip,imov,imov")
13307 (set_attr "modrm" "0,1,1")
13308 (set_attr "prefix_0f" "*,1,1")
13309 (set_attr "prefix_extra" "*,1,1")
13310 (set_attr "mode" "<MODE>")])
13312 (define_insn "*bswap<mode>2"
13313 [(set (match_operand:SWI48 0 "register_operand" "=r")
13314 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
13317 [(set_attr "type" "bitmanip")
13318 (set_attr "modrm" "0")
13319 (set_attr "mode" "<MODE>")])
13321 (define_insn "*bswaphi_lowpart_1"
13322 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
13323 (bswap:HI (match_dup 0)))
13324 (clobber (reg:CC FLAGS_REG))]
13325 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
13327 xchg{b}\t{%h0, %b0|%b0, %h0}
13328 rol{w}\t{$8, %0|%0, 8}"
13329 [(set_attr "length" "2,4")
13330 (set_attr "mode" "QI,HI")])
13332 (define_insn "bswaphi_lowpart"
13333 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
13334 (bswap:HI (match_dup 0)))
13335 (clobber (reg:CC FLAGS_REG))]
13337 "rol{w}\t{$8, %0|%0, 8}"
13338 [(set_attr "length" "4")
13339 (set_attr "mode" "HI")])
13341 (define_expand "paritydi2"
13342 [(set (match_operand:DI 0 "register_operand")
13343 (parity:DI (match_operand:DI 1 "register_operand")))]
13346 rtx scratch = gen_reg_rtx (QImode);
13348 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
13349 NULL_RTX, operands[1]));
13351 ix86_expand_setcc (scratch, ORDERED,
13352 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
13355 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
13358 rtx tmp = gen_reg_rtx (SImode);
13360 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
13361 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
13366 (define_expand "paritysi2"
13367 [(set (match_operand:SI 0 "register_operand")
13368 (parity:SI (match_operand:SI 1 "register_operand")))]
13371 rtx scratch = gen_reg_rtx (QImode);
13373 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
13375 ix86_expand_setcc (scratch, ORDERED,
13376 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
13378 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
13382 (define_insn_and_split "paritydi2_cmp"
13383 [(set (reg:CC FLAGS_REG)
13384 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
13386 (clobber (match_scratch:DI 0 "=r"))
13387 (clobber (match_scratch:SI 1 "=&r"))
13388 (clobber (match_scratch:HI 2 "=Q"))]
13391 "&& reload_completed"
13393 [(set (match_dup 1)
13394 (xor:SI (match_dup 1) (match_dup 4)))
13395 (clobber (reg:CC FLAGS_REG))])
13397 [(set (reg:CC FLAGS_REG)
13398 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13399 (clobber (match_dup 1))
13400 (clobber (match_dup 2))])]
13402 operands[4] = gen_lowpart (SImode, operands[3]);
13406 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
13407 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
13410 operands[1] = gen_highpart (SImode, operands[3]);
13413 (define_insn_and_split "paritysi2_cmp"
13414 [(set (reg:CC FLAGS_REG)
13415 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
13417 (clobber (match_scratch:SI 0 "=r"))
13418 (clobber (match_scratch:HI 1 "=&Q"))]
13421 "&& reload_completed"
13423 [(set (match_dup 1)
13424 (xor:HI (match_dup 1) (match_dup 3)))
13425 (clobber (reg:CC FLAGS_REG))])
13427 [(set (reg:CC FLAGS_REG)
13428 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13429 (clobber (match_dup 1))])]
13431 operands[3] = gen_lowpart (HImode, operands[2]);
13433 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
13434 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
13437 (define_insn "*parityhi2_cmp"
13438 [(set (reg:CC FLAGS_REG)
13439 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
13441 (clobber (match_scratch:HI 0 "=Q"))]
13443 "xor{b}\t{%h0, %b0|%b0, %h0}"
13444 [(set_attr "length" "2")
13445 (set_attr "mode" "HI")])
13448 ;; Thread-local storage patterns for ELF.
13450 ;; Note that these code sequences must appear exactly as shown
13451 ;; in order to allow linker relaxation.
13453 (define_insn "*tls_global_dynamic_32_gnu"
13454 [(set (match_operand:SI 0 "register_operand" "=a")
13456 [(match_operand:SI 1 "register_operand" "Yb")
13457 (match_operand 2 "tls_symbolic_operand")
13458 (match_operand 3 "constant_call_address_operand" "Bz")
13461 (clobber (match_scratch:SI 4 "=d"))
13462 (clobber (match_scratch:SI 5 "=c"))
13463 (clobber (reg:CC FLAGS_REG))]
13464 "!TARGET_64BIT && TARGET_GNU_TLS"
13466 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13468 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
13471 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
13472 if (TARGET_SUN_TLS)
13473 #ifdef HAVE_AS_IX86_TLSGDPLT
13474 return "call\t%a2@tlsgdplt";
13476 return "call\t%p3@plt";
13478 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13479 return "call\t%P3";
13480 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
13482 [(set_attr "type" "multi")
13483 (set_attr "length" "12")])
13485 (define_expand "tls_global_dynamic_32"
13487 [(set (match_operand:SI 0 "register_operand")
13488 (unspec:SI [(match_operand:SI 2 "register_operand")
13489 (match_operand 1 "tls_symbolic_operand")
13490 (match_operand 3 "constant_call_address_operand")
13493 (clobber (match_scratch:SI 4))
13494 (clobber (match_scratch:SI 5))
13495 (clobber (reg:CC FLAGS_REG))])]
13497 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13499 (define_insn "*tls_global_dynamic_64_<mode>"
13500 [(set (match_operand:P 0 "register_operand" "=a")
13502 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
13503 (match_operand 3)))
13504 (unspec:P [(match_operand 1 "tls_symbolic_operand")
13510 fputs (ASM_BYTE "0x66\n", asm_out_file);
13512 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13513 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13514 fputs (ASM_SHORT "0x6666\n", asm_out_file);
13516 fputs (ASM_BYTE "0x66\n", asm_out_file);
13517 fputs ("\trex64\n", asm_out_file);
13518 if (TARGET_SUN_TLS)
13519 return "call\t%p2@plt";
13520 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13521 return "call\t%P2";
13522 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
13524 [(set_attr "type" "multi")
13525 (set (attr "length")
13526 (symbol_ref "TARGET_X32 ? 15 : 16"))])
13528 (define_insn "*tls_global_dynamic_64_largepic"
13529 [(set (match_operand:DI 0 "register_operand" "=a")
13531 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
13532 (match_operand:DI 3 "immediate_operand" "i")))
13533 (match_operand 4)))
13534 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13537 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13538 && GET_CODE (operands[3]) == CONST
13539 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13540 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13543 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13544 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13545 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13546 return "call\t{*%%rax|rax}";
13548 [(set_attr "type" "multi")
13549 (set_attr "length" "22")])
13551 (define_expand "tls_global_dynamic_64_<mode>"
13553 [(set (match_operand:P 0 "register_operand")
13555 (mem:QI (match_operand 2))
13557 (unspec:P [(match_operand 1 "tls_symbolic_operand")
13561 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13563 (define_insn "*tls_local_dynamic_base_32_gnu"
13564 [(set (match_operand:SI 0 "register_operand" "=a")
13566 [(match_operand:SI 1 "register_operand" "Yb")
13567 (match_operand 2 "constant_call_address_operand" "Bz")
13569 UNSPEC_TLS_LD_BASE))
13570 (clobber (match_scratch:SI 3 "=d"))
13571 (clobber (match_scratch:SI 4 "=c"))
13572 (clobber (reg:CC FLAGS_REG))]
13573 "!TARGET_64BIT && TARGET_GNU_TLS"
13576 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13577 if (TARGET_SUN_TLS)
13579 if (HAVE_AS_IX86_TLSLDMPLT)
13580 return "call\t%&@tlsldmplt";
13582 return "call\t%p2@plt";
13584 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13585 return "call\t%P2";
13586 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
13588 [(set_attr "type" "multi")
13589 (set_attr "length" "11")])
13591 (define_expand "tls_local_dynamic_base_32"
13593 [(set (match_operand:SI 0 "register_operand")
13595 [(match_operand:SI 1 "register_operand")
13596 (match_operand 2 "constant_call_address_operand")
13598 UNSPEC_TLS_LD_BASE))
13599 (clobber (match_scratch:SI 3))
13600 (clobber (match_scratch:SI 4))
13601 (clobber (reg:CC FLAGS_REG))])]
13603 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13605 (define_insn "*tls_local_dynamic_base_64_<mode>"
13606 [(set (match_operand:P 0 "register_operand" "=a")
13608 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13609 (match_operand 2)))
13610 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
13614 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13615 if (TARGET_SUN_TLS)
13616 return "call\t%p1@plt";
13617 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13618 return "call\t%P1";
13619 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
13621 [(set_attr "type" "multi")
13622 (set_attr "length" "12")])
13624 (define_insn "*tls_local_dynamic_base_64_largepic"
13625 [(set (match_operand:DI 0 "register_operand" "=a")
13627 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13628 (match_operand:DI 2 "immediate_operand" "i")))
13629 (match_operand 3)))
13630 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
13631 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13632 && GET_CODE (operands[2]) == CONST
13633 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13634 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13637 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13638 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13639 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13640 return "call\t{*%%rax|rax}";
13642 [(set_attr "type" "multi")
13643 (set_attr "length" "22")])
13645 (define_expand "tls_local_dynamic_base_64_<mode>"
13647 [(set (match_operand:P 0 "register_operand")
13649 (mem:QI (match_operand 1))
13651 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
13653 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13655 ;; Local dynamic of a single variable is a lose. Show combine how
13656 ;; to convert that back to global dynamic.
13658 (define_insn_and_split "*tls_local_dynamic_32_once"
13659 [(set (match_operand:SI 0 "register_operand" "=a")
13661 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13662 (match_operand 2 "constant_call_address_operand" "Bz")
13664 UNSPEC_TLS_LD_BASE)
13665 (const:SI (unspec:SI
13666 [(match_operand 3 "tls_symbolic_operand")]
13668 (clobber (match_scratch:SI 4 "=d"))
13669 (clobber (match_scratch:SI 5 "=c"))
13670 (clobber (reg:CC FLAGS_REG))]
13675 [(set (match_dup 0)
13676 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13679 (clobber (match_dup 4))
13680 (clobber (match_dup 5))
13681 (clobber (reg:CC FLAGS_REG))])])
13683 ;; Segment register for the thread base ptr load
13684 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13686 ;; Load and add the thread base pointer from %<tp_seg>:0.
13687 (define_insn "*load_tp_x32"
13688 [(set (match_operand:SI 0 "register_operand" "=r")
13689 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13691 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13692 [(set_attr "type" "imov")
13693 (set_attr "modrm" "0")
13694 (set_attr "length" "7")
13695 (set_attr "memory" "load")
13696 (set_attr "imm_disp" "false")])
13698 (define_insn "*load_tp_x32_zext"
13699 [(set (match_operand:DI 0 "register_operand" "=r")
13700 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13702 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13703 [(set_attr "type" "imov")
13704 (set_attr "modrm" "0")
13705 (set_attr "length" "7")
13706 (set_attr "memory" "load")
13707 (set_attr "imm_disp" "false")])
13709 (define_insn "*load_tp_<mode>"
13710 [(set (match_operand:P 0 "register_operand" "=r")
13711 (unspec:P [(const_int 0)] UNSPEC_TP))]
13713 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13714 [(set_attr "type" "imov")
13715 (set_attr "modrm" "0")
13716 (set_attr "length" "7")
13717 (set_attr "memory" "load")
13718 (set_attr "imm_disp" "false")])
13720 (define_insn "*add_tp_x32"
13721 [(set (match_operand:SI 0 "register_operand" "=r")
13722 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13723 (match_operand:SI 1 "register_operand" "0")))
13724 (clobber (reg:CC FLAGS_REG))]
13726 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13727 [(set_attr "type" "alu")
13728 (set_attr "modrm" "0")
13729 (set_attr "length" "7")
13730 (set_attr "memory" "load")
13731 (set_attr "imm_disp" "false")])
13733 (define_insn "*add_tp_x32_zext"
13734 [(set (match_operand:DI 0 "register_operand" "=r")
13736 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13737 (match_operand:SI 1 "register_operand" "0"))))
13738 (clobber (reg:CC FLAGS_REG))]
13740 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13741 [(set_attr "type" "alu")
13742 (set_attr "modrm" "0")
13743 (set_attr "length" "7")
13744 (set_attr "memory" "load")
13745 (set_attr "imm_disp" "false")])
13747 (define_insn "*add_tp_<mode>"
13748 [(set (match_operand:P 0 "register_operand" "=r")
13749 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13750 (match_operand:P 1 "register_operand" "0")))
13751 (clobber (reg:CC FLAGS_REG))]
13753 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13754 [(set_attr "type" "alu")
13755 (set_attr "modrm" "0")
13756 (set_attr "length" "7")
13757 (set_attr "memory" "load")
13758 (set_attr "imm_disp" "false")])
13760 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13761 ;; %rax as destination of the initial executable code sequence.
13762 (define_insn "tls_initial_exec_64_sun"
13763 [(set (match_operand:DI 0 "register_operand" "=a")
13765 [(match_operand 1 "tls_symbolic_operand")]
13766 UNSPEC_TLS_IE_SUN))
13767 (clobber (reg:CC FLAGS_REG))]
13768 "TARGET_64BIT && TARGET_SUN_TLS"
13771 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13772 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13774 [(set_attr "type" "multi")])
13776 ;; GNU2 TLS patterns can be split.
13778 (define_expand "tls_dynamic_gnu2_32"
13779 [(set (match_dup 3)
13780 (plus:SI (match_operand:SI 2 "register_operand")
13782 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13785 [(set (match_operand:SI 0 "register_operand")
13786 (unspec:SI [(match_dup 1) (match_dup 3)
13787 (match_dup 2) (reg:SI SP_REG)]
13789 (clobber (reg:CC FLAGS_REG))])]
13790 "!TARGET_64BIT && TARGET_GNU2_TLS"
13792 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13793 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13796 (define_insn "*tls_dynamic_gnu2_lea_32"
13797 [(set (match_operand:SI 0 "register_operand" "=r")
13798 (plus:SI (match_operand:SI 1 "register_operand" "b")
13800 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13801 UNSPEC_TLSDESC))))]
13802 "!TARGET_64BIT && TARGET_GNU2_TLS"
13803 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13804 [(set_attr "type" "lea")
13805 (set_attr "mode" "SI")
13806 (set_attr "length" "6")
13807 (set_attr "length_address" "4")])
13809 (define_insn "*tls_dynamic_gnu2_call_32"
13810 [(set (match_operand:SI 0 "register_operand" "=a")
13811 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13812 (match_operand:SI 2 "register_operand" "0")
13813 ;; we have to make sure %ebx still points to the GOT
13814 (match_operand:SI 3 "register_operand" "b")
13817 (clobber (reg:CC FLAGS_REG))]
13818 "!TARGET_64BIT && TARGET_GNU2_TLS"
13819 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13820 [(set_attr "type" "call")
13821 (set_attr "length" "2")
13822 (set_attr "length_address" "0")])
13824 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13825 [(set (match_operand:SI 0 "register_operand" "=&a")
13827 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13828 (match_operand:SI 4)
13829 (match_operand:SI 2 "register_operand" "b")
13832 (const:SI (unspec:SI
13833 [(match_operand 1 "tls_symbolic_operand")]
13835 (clobber (reg:CC FLAGS_REG))]
13836 "!TARGET_64BIT && TARGET_GNU2_TLS"
13839 [(set (match_dup 0) (match_dup 5))]
13841 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13842 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13845 (define_expand "tls_dynamic_gnu2_64"
13846 [(set (match_dup 2)
13847 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13850 [(set (match_operand:DI 0 "register_operand")
13851 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13853 (clobber (reg:CC FLAGS_REG))])]
13854 "TARGET_64BIT && TARGET_GNU2_TLS"
13856 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13857 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13860 (define_insn "*tls_dynamic_gnu2_lea_64"
13861 [(set (match_operand:DI 0 "register_operand" "=r")
13862 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13864 "TARGET_64BIT && TARGET_GNU2_TLS"
13865 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13866 [(set_attr "type" "lea")
13867 (set_attr "mode" "DI")
13868 (set_attr "length" "7")
13869 (set_attr "length_address" "4")])
13871 (define_insn "*tls_dynamic_gnu2_call_64"
13872 [(set (match_operand:DI 0 "register_operand" "=a")
13873 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13874 (match_operand:DI 2 "register_operand" "0")
13877 (clobber (reg:CC FLAGS_REG))]
13878 "TARGET_64BIT && TARGET_GNU2_TLS"
13879 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13880 [(set_attr "type" "call")
13881 (set_attr "length" "2")
13882 (set_attr "length_address" "0")])
13884 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13885 [(set (match_operand:DI 0 "register_operand" "=&a")
13887 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13888 (match_operand:DI 3)
13891 (const:DI (unspec:DI
13892 [(match_operand 1 "tls_symbolic_operand")]
13894 (clobber (reg:CC FLAGS_REG))]
13895 "TARGET_64BIT && TARGET_GNU2_TLS"
13898 [(set (match_dup 0) (match_dup 4))]
13900 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13901 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13904 ;; These patterns match the binary 387 instructions for addM3, subM3,
13905 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13906 ;; SFmode. The first is the normal insn, the second the same insn but
13907 ;; with one operand a conversion, and the third the same insn but with
13908 ;; the other operand a conversion. The conversion may be SFmode or
13909 ;; SImode if the target mode DFmode, but only SImode if the target mode
13912 ;; Gcc is slightly more smart about handling normal two address instructions
13913 ;; so use special patterns for add and mull.
13915 (define_insn "*fop_<mode>_comm"
13916 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
13917 (match_operator:MODEF 3 "binary_fp_operator"
13918 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
13919 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
13920 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13921 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
13922 && COMMUTATIVE_ARITH_P (operands[3])
13923 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13924 "* return output_387_binary_op (insn, operands);"
13925 [(set (attr "type")
13926 (if_then_else (eq_attr "alternative" "1,2")
13927 (if_then_else (match_operand:MODEF 3 "mult_operator")
13928 (const_string "ssemul")
13929 (const_string "sseadd"))
13930 (if_then_else (match_operand:MODEF 3 "mult_operator")
13931 (const_string "fmul")
13932 (const_string "fop"))))
13933 (set_attr "isa" "*,noavx,avx")
13934 (set_attr "prefix" "orig,orig,vex")
13935 (set_attr "mode" "<MODE>")
13936 (set (attr "enabled")
13938 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
13940 (eq_attr "alternative" "0")
13941 (symbol_ref "TARGET_MIX_SSE_I387
13942 && X87_ENABLE_ARITH (<MODE>mode)")
13943 (const_string "*"))
13945 (eq_attr "alternative" "0")
13946 (symbol_ref "true")
13947 (symbol_ref "false"))))])
13949 (define_insn "*rcpsf2_sse"
13950 [(set (match_operand:SF 0 "register_operand" "=x")
13951 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13954 "%vrcpss\t{%1, %d0|%d0, %1}"
13955 [(set_attr "type" "sse")
13956 (set_attr "atom_sse_attr" "rcp")
13957 (set_attr "btver2_sse_attr" "rcp")
13958 (set_attr "prefix" "maybe_vex")
13959 (set_attr "mode" "SF")])
13961 (define_insn "*fop_<mode>_1"
13962 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
13963 (match_operator:MODEF 3 "binary_fp_operator"
13964 [(match_operand:MODEF 1
13965 "x87nonimm_ssenomem_operand" "0,fm,0,v")
13966 (match_operand:MODEF 2
13967 "nonimmediate_operand" "fm,0,xm,vm")]))]
13968 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13969 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
13970 && !COMMUTATIVE_ARITH_P (operands[3])
13971 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13972 "* return output_387_binary_op (insn, operands);"
13973 [(set (attr "type")
13974 (if_then_else (eq_attr "alternative" "2,3")
13975 (if_then_else (match_operand:MODEF 3 "div_operator")
13976 (const_string "ssediv")
13977 (const_string "sseadd"))
13978 (if_then_else (match_operand:MODEF 3 "div_operator")
13979 (const_string "fdiv")
13980 (const_string "fop"))))
13981 (set_attr "isa" "*,*,noavx,avx")
13982 (set_attr "prefix" "orig,orig,orig,vex")
13983 (set_attr "mode" "<MODE>")
13984 (set (attr "enabled")
13986 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
13988 (eq_attr "alternative" "0,1")
13989 (symbol_ref "TARGET_MIX_SSE_I387
13990 && X87_ENABLE_ARITH (<MODE>mode)")
13991 (const_string "*"))
13993 (eq_attr "alternative" "0,1")
13994 (symbol_ref "true")
13995 (symbol_ref "false"))))])
13997 ;; ??? Add SSE splitters for these!
13998 (define_insn "*fop_<MODEF:mode>_2_i387"
13999 [(set (match_operand:MODEF 0 "register_operand" "=f")
14000 (match_operator:MODEF 3 "binary_fp_operator"
14002 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14003 (match_operand:MODEF 2 "register_operand" "0")]))]
14004 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14005 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14006 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14007 || optimize_function_for_size_p (cfun))"
14008 "* return output_387_binary_op (insn, operands);"
14009 [(set (attr "type")
14010 (cond [(match_operand:MODEF 3 "mult_operator")
14011 (const_string "fmul")
14012 (match_operand:MODEF 3 "div_operator")
14013 (const_string "fdiv")
14015 (const_string "fop")))
14016 (set_attr "fp_int_src" "true")
14017 (set_attr "mode" "<SWI24:MODE>")])
14019 (define_insn "*fop_<MODEF:mode>_3_i387"
14020 [(set (match_operand:MODEF 0 "register_operand" "=f")
14021 (match_operator:MODEF 3 "binary_fp_operator"
14022 [(match_operand:MODEF 1 "register_operand" "0")
14024 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14025 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14026 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14027 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14028 || optimize_function_for_size_p (cfun))"
14029 "* return output_387_binary_op (insn, operands);"
14030 [(set (attr "type")
14031 (cond [(match_operand:MODEF 3 "mult_operator")
14032 (const_string "fmul")
14033 (match_operand:MODEF 3 "div_operator")
14034 (const_string "fdiv")
14036 (const_string "fop")))
14037 (set_attr "fp_int_src" "true")
14038 (set_attr "mode" "<MODE>")])
14040 (define_insn "*fop_df_4_i387"
14041 [(set (match_operand:DF 0 "register_operand" "=f,f")
14042 (match_operator:DF 3 "binary_fp_operator"
14044 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14045 (match_operand:DF 2 "register_operand" "0,f")]))]
14046 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14047 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14048 "* return output_387_binary_op (insn, operands);"
14049 [(set (attr "type")
14050 (cond [(match_operand:DF 3 "mult_operator")
14051 (const_string "fmul")
14052 (match_operand:DF 3 "div_operator")
14053 (const_string "fdiv")
14055 (const_string "fop")))
14056 (set_attr "mode" "SF")])
14058 (define_insn "*fop_df_5_i387"
14059 [(set (match_operand:DF 0 "register_operand" "=f,f")
14060 (match_operator:DF 3 "binary_fp_operator"
14061 [(match_operand:DF 1 "register_operand" "0,f")
14063 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14064 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14065 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14066 "* return output_387_binary_op (insn, operands);"
14067 [(set (attr "type")
14068 (cond [(match_operand:DF 3 "mult_operator")
14069 (const_string "fmul")
14070 (match_operand:DF 3 "div_operator")
14071 (const_string "fdiv")
14073 (const_string "fop")))
14074 (set_attr "mode" "SF")])
14076 (define_insn "*fop_df_6_i387"
14077 [(set (match_operand:DF 0 "register_operand" "=f,f")
14078 (match_operator:DF 3 "binary_fp_operator"
14080 (match_operand:SF 1 "register_operand" "0,f"))
14082 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14083 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14084 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14085 "* return output_387_binary_op (insn, operands);"
14086 [(set (attr "type")
14087 (cond [(match_operand:DF 3 "mult_operator")
14088 (const_string "fmul")
14089 (match_operand:DF 3 "div_operator")
14090 (const_string "fdiv")
14092 (const_string "fop")))
14093 (set_attr "mode" "SF")])
14095 (define_insn "*fop_xf_comm_i387"
14096 [(set (match_operand:XF 0 "register_operand" "=f")
14097 (match_operator:XF 3 "binary_fp_operator"
14098 [(match_operand:XF 1 "register_operand" "%0")
14099 (match_operand:XF 2 "register_operand" "f")]))]
14101 && COMMUTATIVE_ARITH_P (operands[3])"
14102 "* return output_387_binary_op (insn, operands);"
14103 [(set (attr "type")
14104 (if_then_else (match_operand:XF 3 "mult_operator")
14105 (const_string "fmul")
14106 (const_string "fop")))
14107 (set_attr "mode" "XF")])
14109 (define_insn "*fop_xf_1_i387"
14110 [(set (match_operand:XF 0 "register_operand" "=f,f")
14111 (match_operator:XF 3 "binary_fp_operator"
14112 [(match_operand:XF 1 "register_operand" "0,f")
14113 (match_operand:XF 2 "register_operand" "f,0")]))]
14115 && !COMMUTATIVE_ARITH_P (operands[3])"
14116 "* return output_387_binary_op (insn, operands);"
14117 [(set (attr "type")
14118 (if_then_else (match_operand:XF 3 "div_operator")
14119 (const_string "fdiv")
14120 (const_string "fop")))
14121 (set_attr "mode" "XF")])
14123 (define_insn "*fop_xf_2_i387"
14124 [(set (match_operand:XF 0 "register_operand" "=f")
14125 (match_operator:XF 3 "binary_fp_operator"
14127 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14128 (match_operand:XF 2 "register_operand" "0")]))]
14130 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14131 "* return output_387_binary_op (insn, operands);"
14132 [(set (attr "type")
14133 (cond [(match_operand:XF 3 "mult_operator")
14134 (const_string "fmul")
14135 (match_operand:XF 3 "div_operator")
14136 (const_string "fdiv")
14138 (const_string "fop")))
14139 (set_attr "fp_int_src" "true")
14140 (set_attr "mode" "<MODE>")])
14142 (define_insn "*fop_xf_3_i387"
14143 [(set (match_operand:XF 0 "register_operand" "=f")
14144 (match_operator:XF 3 "binary_fp_operator"
14145 [(match_operand:XF 1 "register_operand" "0")
14147 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14149 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14150 "* return output_387_binary_op (insn, operands);"
14151 [(set (attr "type")
14152 (cond [(match_operand:XF 3 "mult_operator")
14153 (const_string "fmul")
14154 (match_operand:XF 3 "div_operator")
14155 (const_string "fdiv")
14157 (const_string "fop")))
14158 (set_attr "fp_int_src" "true")
14159 (set_attr "mode" "<MODE>")])
14161 (define_insn "*fop_xf_4_i387"
14162 [(set (match_operand:XF 0 "register_operand" "=f,f")
14163 (match_operator:XF 3 "binary_fp_operator"
14165 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
14166 (match_operand:XF 2 "register_operand" "0,f")]))]
14168 "* return output_387_binary_op (insn, operands);"
14169 [(set (attr "type")
14170 (cond [(match_operand:XF 3 "mult_operator")
14171 (const_string "fmul")
14172 (match_operand:XF 3 "div_operator")
14173 (const_string "fdiv")
14175 (const_string "fop")))
14176 (set_attr "mode" "<MODE>")])
14178 (define_insn "*fop_xf_5_i387"
14179 [(set (match_operand:XF 0 "register_operand" "=f,f")
14180 (match_operator:XF 3 "binary_fp_operator"
14181 [(match_operand:XF 1 "register_operand" "0,f")
14183 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14185 "* return output_387_binary_op (insn, operands);"
14186 [(set (attr "type")
14187 (cond [(match_operand:XF 3 "mult_operator")
14188 (const_string "fmul")
14189 (match_operand:XF 3 "div_operator")
14190 (const_string "fdiv")
14192 (const_string "fop")))
14193 (set_attr "mode" "<MODE>")])
14195 (define_insn "*fop_xf_6_i387"
14196 [(set (match_operand:XF 0 "register_operand" "=f,f")
14197 (match_operator:XF 3 "binary_fp_operator"
14199 (match_operand:MODEF 1 "register_operand" "0,f"))
14201 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14203 "* return output_387_binary_op (insn, operands);"
14204 [(set (attr "type")
14205 (cond [(match_operand:XF 3 "mult_operator")
14206 (const_string "fmul")
14207 (match_operand:XF 3 "div_operator")
14208 (const_string "fdiv")
14210 (const_string "fop")))
14211 (set_attr "mode" "<MODE>")])
14213 ;; FPU special functions.
14215 ;; This pattern implements a no-op XFmode truncation for
14216 ;; all fancy i386 XFmode math functions.
14218 (define_insn "truncxf<mode>2_i387_noop_unspec"
14219 [(set (match_operand:MODEF 0 "register_operand" "=f")
14220 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
14221 UNSPEC_TRUNC_NOOP))]
14222 "TARGET_USE_FANCY_MATH_387"
14223 "* return output_387_reg_move (insn, operands);"
14224 [(set_attr "type" "fmov")
14225 (set_attr "mode" "<MODE>")])
14227 (define_insn "sqrtxf2"
14228 [(set (match_operand:XF 0 "register_operand" "=f")
14229 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14230 "TARGET_USE_FANCY_MATH_387"
14232 [(set_attr "type" "fpspc")
14233 (set_attr "mode" "XF")
14234 (set_attr "athlon_decode" "direct")
14235 (set_attr "amdfam10_decode" "direct")
14236 (set_attr "bdver1_decode" "direct")])
14238 (define_insn "sqrt_extend<mode>xf2_i387"
14239 [(set (match_operand:XF 0 "register_operand" "=f")
14242 (match_operand:MODEF 1 "register_operand" "0"))))]
14243 "TARGET_USE_FANCY_MATH_387"
14245 [(set_attr "type" "fpspc")
14246 (set_attr "mode" "XF")
14247 (set_attr "athlon_decode" "direct")
14248 (set_attr "amdfam10_decode" "direct")
14249 (set_attr "bdver1_decode" "direct")])
14251 (define_insn "*rsqrtsf2_sse"
14252 [(set (match_operand:SF 0 "register_operand" "=x")
14253 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14256 "%vrsqrtss\t{%1, %d0|%d0, %1}"
14257 [(set_attr "type" "sse")
14258 (set_attr "atom_sse_attr" "rcp")
14259 (set_attr "btver2_sse_attr" "rcp")
14260 (set_attr "prefix" "maybe_vex")
14261 (set_attr "mode" "SF")])
14263 (define_expand "rsqrtsf2"
14264 [(set (match_operand:SF 0 "register_operand")
14265 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
14269 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
14273 (define_insn "*sqrt<mode>2_sse"
14274 [(set (match_operand:MODEF 0 "register_operand" "=v")
14276 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
14277 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14278 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
14279 [(set_attr "type" "sse")
14280 (set_attr "atom_sse_attr" "sqrt")
14281 (set_attr "btver2_sse_attr" "sqrt")
14282 (set_attr "prefix" "maybe_vex")
14283 (set_attr "mode" "<MODE>")
14284 (set_attr "athlon_decode" "*")
14285 (set_attr "amdfam10_decode" "*")
14286 (set_attr "bdver1_decode" "*")])
14288 (define_expand "sqrt<mode>2"
14289 [(set (match_operand:MODEF 0 "register_operand")
14291 (match_operand:MODEF 1 "nonimmediate_operand")))]
14292 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
14293 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14295 if (<MODE>mode == SFmode
14297 && TARGET_RECIP_SQRT
14298 && !optimize_function_for_size_p (cfun)
14299 && flag_finite_math_only && !flag_trapping_math
14300 && flag_unsafe_math_optimizations)
14302 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
14306 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
14308 rtx op0 = gen_reg_rtx (XFmode);
14309 rtx op1 = force_reg (<MODE>mode, operands[1]);
14311 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
14312 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
14317 (define_insn "fpremxf4_i387"
14318 [(set (match_operand:XF 0 "register_operand" "=f")
14319 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14320 (match_operand:XF 3 "register_operand" "1")]
14322 (set (match_operand:XF 1 "register_operand" "=u")
14323 (unspec:XF [(match_dup 2) (match_dup 3)]
14325 (set (reg:CCFP FPSR_REG)
14326 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14328 "TARGET_USE_FANCY_MATH_387
14329 && flag_finite_math_only"
14331 [(set_attr "type" "fpspc")
14332 (set_attr "znver1_decode" "vector")
14333 (set_attr "mode" "XF")])
14335 (define_expand "fmodxf3"
14336 [(use (match_operand:XF 0 "register_operand"))
14337 (use (match_operand:XF 1 "general_operand"))
14338 (use (match_operand:XF 2 "general_operand"))]
14339 "TARGET_USE_FANCY_MATH_387
14340 && flag_finite_math_only"
14342 rtx_code_label *label = gen_label_rtx ();
14344 rtx op1 = gen_reg_rtx (XFmode);
14345 rtx op2 = gen_reg_rtx (XFmode);
14347 emit_move_insn (op2, operands[2]);
14348 emit_move_insn (op1, operands[1]);
14350 emit_label (label);
14351 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14352 ix86_emit_fp_unordered_jump (label);
14353 LABEL_NUSES (label) = 1;
14355 emit_move_insn (operands[0], op1);
14359 (define_expand "fmod<mode>3"
14360 [(use (match_operand:MODEF 0 "register_operand"))
14361 (use (match_operand:MODEF 1 "general_operand"))
14362 (use (match_operand:MODEF 2 "general_operand"))]
14363 "TARGET_USE_FANCY_MATH_387
14364 && flag_finite_math_only"
14366 rtx (*gen_truncxf) (rtx, rtx);
14368 rtx_code_label *label = gen_label_rtx ();
14370 rtx op1 = gen_reg_rtx (XFmode);
14371 rtx op2 = gen_reg_rtx (XFmode);
14373 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14374 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14376 emit_label (label);
14377 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14378 ix86_emit_fp_unordered_jump (label);
14379 LABEL_NUSES (label) = 1;
14381 /* Truncate the result properly for strict SSE math. */
14382 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14383 && !TARGET_MIX_SSE_I387)
14384 gen_truncxf = gen_truncxf<mode>2;
14386 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14388 emit_insn (gen_truncxf (operands[0], op1));
14392 (define_insn "fprem1xf4_i387"
14393 [(set (match_operand:XF 0 "register_operand" "=f")
14394 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14395 (match_operand:XF 3 "register_operand" "1")]
14397 (set (match_operand:XF 1 "register_operand" "=u")
14398 (unspec:XF [(match_dup 2) (match_dup 3)]
14400 (set (reg:CCFP FPSR_REG)
14401 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14403 "TARGET_USE_FANCY_MATH_387
14404 && flag_finite_math_only"
14406 [(set_attr "type" "fpspc")
14407 (set_attr "znver1_decode" "vector")
14408 (set_attr "mode" "XF")])
14410 (define_expand "remainderxf3"
14411 [(use (match_operand:XF 0 "register_operand"))
14412 (use (match_operand:XF 1 "general_operand"))
14413 (use (match_operand:XF 2 "general_operand"))]
14414 "TARGET_USE_FANCY_MATH_387
14415 && flag_finite_math_only"
14417 rtx_code_label *label = gen_label_rtx ();
14419 rtx op1 = gen_reg_rtx (XFmode);
14420 rtx op2 = gen_reg_rtx (XFmode);
14422 emit_move_insn (op2, operands[2]);
14423 emit_move_insn (op1, operands[1]);
14425 emit_label (label);
14426 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14427 ix86_emit_fp_unordered_jump (label);
14428 LABEL_NUSES (label) = 1;
14430 emit_move_insn (operands[0], op1);
14434 (define_expand "remainder<mode>3"
14435 [(use (match_operand:MODEF 0 "register_operand"))
14436 (use (match_operand:MODEF 1 "general_operand"))
14437 (use (match_operand:MODEF 2 "general_operand"))]
14438 "TARGET_USE_FANCY_MATH_387
14439 && flag_finite_math_only"
14441 rtx (*gen_truncxf) (rtx, rtx);
14443 rtx_code_label *label = gen_label_rtx ();
14445 rtx op1 = gen_reg_rtx (XFmode);
14446 rtx op2 = gen_reg_rtx (XFmode);
14448 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14449 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14451 emit_label (label);
14453 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14454 ix86_emit_fp_unordered_jump (label);
14455 LABEL_NUSES (label) = 1;
14457 /* Truncate the result properly for strict SSE math. */
14458 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14459 && !TARGET_MIX_SSE_I387)
14460 gen_truncxf = gen_truncxf<mode>2;
14462 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14464 emit_insn (gen_truncxf (operands[0], op1));
14468 (define_int_iterator SINCOS
14472 (define_int_attr sincos
14473 [(UNSPEC_SIN "sin")
14474 (UNSPEC_COS "cos")])
14476 (define_insn "*<sincos>xf2_i387"
14477 [(set (match_operand:XF 0 "register_operand" "=f")
14478 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14480 "TARGET_USE_FANCY_MATH_387
14481 && flag_unsafe_math_optimizations"
14483 [(set_attr "type" "fpspc")
14484 (set_attr "znver1_decode" "vector")
14485 (set_attr "mode" "XF")])
14487 (define_insn "*<sincos>_extend<mode>xf2_i387"
14488 [(set (match_operand:XF 0 "register_operand" "=f")
14489 (unspec:XF [(float_extend:XF
14490 (match_operand:MODEF 1 "register_operand" "0"))]
14492 "TARGET_USE_FANCY_MATH_387
14493 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14494 || TARGET_MIX_SSE_I387)
14495 && flag_unsafe_math_optimizations"
14497 [(set_attr "type" "fpspc")
14498 (set_attr "znver1_decode" "vector")
14499 (set_attr "mode" "XF")])
14501 ;; When sincos pattern is defined, sin and cos builtin functions will be
14502 ;; expanded to sincos pattern with one of its outputs left unused.
14503 ;; CSE pass will figure out if two sincos patterns can be combined,
14504 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14505 ;; depending on the unused output.
14507 (define_insn "sincosxf3"
14508 [(set (match_operand:XF 0 "register_operand" "=f")
14509 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14510 UNSPEC_SINCOS_COS))
14511 (set (match_operand:XF 1 "register_operand" "=u")
14512 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14513 "TARGET_USE_FANCY_MATH_387
14514 && flag_unsafe_math_optimizations"
14516 [(set_attr "type" "fpspc")
14517 (set_attr "znver1_decode" "vector")
14518 (set_attr "mode" "XF")])
14521 [(set (match_operand:XF 0 "register_operand")
14522 (unspec:XF [(match_operand:XF 2 "register_operand")]
14523 UNSPEC_SINCOS_COS))
14524 (set (match_operand:XF 1 "register_operand")
14525 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14526 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14527 && can_create_pseudo_p ()"
14528 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14531 [(set (match_operand:XF 0 "register_operand")
14532 (unspec:XF [(match_operand:XF 2 "register_operand")]
14533 UNSPEC_SINCOS_COS))
14534 (set (match_operand:XF 1 "register_operand")
14535 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14536 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14537 && can_create_pseudo_p ()"
14538 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14540 (define_insn "sincos_extend<mode>xf3_i387"
14541 [(set (match_operand:XF 0 "register_operand" "=f")
14542 (unspec:XF [(float_extend:XF
14543 (match_operand:MODEF 2 "register_operand" "0"))]
14544 UNSPEC_SINCOS_COS))
14545 (set (match_operand:XF 1 "register_operand" "=u")
14546 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14547 "TARGET_USE_FANCY_MATH_387
14548 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14549 || TARGET_MIX_SSE_I387)
14550 && flag_unsafe_math_optimizations"
14552 [(set_attr "type" "fpspc")
14553 (set_attr "znver1_decode" "vector")
14554 (set_attr "mode" "XF")])
14557 [(set (match_operand:XF 0 "register_operand")
14558 (unspec:XF [(float_extend:XF
14559 (match_operand:MODEF 2 "register_operand"))]
14560 UNSPEC_SINCOS_COS))
14561 (set (match_operand:XF 1 "register_operand")
14562 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14563 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14564 && can_create_pseudo_p ()"
14565 [(set (match_dup 1)
14566 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14569 [(set (match_operand:XF 0 "register_operand")
14570 (unspec:XF [(float_extend:XF
14571 (match_operand:MODEF 2 "register_operand"))]
14572 UNSPEC_SINCOS_COS))
14573 (set (match_operand:XF 1 "register_operand")
14574 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14575 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14576 && can_create_pseudo_p ()"
14577 [(set (match_dup 0)
14578 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14580 (define_expand "sincos<mode>3"
14581 [(use (match_operand:MODEF 0 "register_operand"))
14582 (use (match_operand:MODEF 1 "register_operand"))
14583 (use (match_operand:MODEF 2 "register_operand"))]
14584 "TARGET_USE_FANCY_MATH_387
14585 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14586 || TARGET_MIX_SSE_I387)
14587 && flag_unsafe_math_optimizations"
14589 rtx op0 = gen_reg_rtx (XFmode);
14590 rtx op1 = gen_reg_rtx (XFmode);
14592 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14593 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14594 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14598 (define_insn "fptanxf4_i387"
14599 [(set (match_operand:XF 0 "register_operand" "=f")
14600 (match_operand:XF 3 "const_double_operand" "F"))
14601 (set (match_operand:XF 1 "register_operand" "=u")
14602 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14604 "TARGET_USE_FANCY_MATH_387
14605 && flag_unsafe_math_optimizations
14606 && standard_80387_constant_p (operands[3]) == 2"
14608 [(set_attr "type" "fpspc")
14609 (set_attr "znver1_decode" "vector")
14610 (set_attr "mode" "XF")])
14612 (define_insn "fptan_extend<mode>xf4_i387"
14613 [(set (match_operand:MODEF 0 "register_operand" "=f")
14614 (match_operand:MODEF 3 "const_double_operand" "F"))
14615 (set (match_operand:XF 1 "register_operand" "=u")
14616 (unspec:XF [(float_extend:XF
14617 (match_operand:MODEF 2 "register_operand" "0"))]
14619 "TARGET_USE_FANCY_MATH_387
14620 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14621 || TARGET_MIX_SSE_I387)
14622 && flag_unsafe_math_optimizations
14623 && standard_80387_constant_p (operands[3]) == 2"
14625 [(set_attr "type" "fpspc")
14626 (set_attr "znver1_decode" "vector")
14627 (set_attr "mode" "XF")])
14629 (define_expand "tanxf2"
14630 [(use (match_operand:XF 0 "register_operand"))
14631 (use (match_operand:XF 1 "register_operand"))]
14632 "TARGET_USE_FANCY_MATH_387
14633 && flag_unsafe_math_optimizations"
14635 rtx one = gen_reg_rtx (XFmode);
14636 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14638 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14642 (define_expand "tan<mode>2"
14643 [(use (match_operand:MODEF 0 "register_operand"))
14644 (use (match_operand:MODEF 1 "register_operand"))]
14645 "TARGET_USE_FANCY_MATH_387
14646 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14647 || TARGET_MIX_SSE_I387)
14648 && flag_unsafe_math_optimizations"
14650 rtx op0 = gen_reg_rtx (XFmode);
14652 rtx one = gen_reg_rtx (<MODE>mode);
14653 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14655 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14656 operands[1], op2));
14657 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14661 (define_insn "*fpatanxf3_i387"
14662 [(set (match_operand:XF 0 "register_operand" "=f")
14663 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14664 (match_operand:XF 2 "register_operand" "u")]
14666 (clobber (match_scratch:XF 3 "=2"))]
14667 "TARGET_USE_FANCY_MATH_387
14668 && flag_unsafe_math_optimizations"
14670 [(set_attr "type" "fpspc")
14671 (set_attr "znver1_decode" "vector")
14672 (set_attr "mode" "XF")])
14674 (define_insn "fpatan_extend<mode>xf3_i387"
14675 [(set (match_operand:XF 0 "register_operand" "=f")
14676 (unspec:XF [(float_extend:XF
14677 (match_operand:MODEF 1 "register_operand" "0"))
14679 (match_operand:MODEF 2 "register_operand" "u"))]
14681 (clobber (match_scratch:XF 3 "=2"))]
14682 "TARGET_USE_FANCY_MATH_387
14683 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14684 || TARGET_MIX_SSE_I387)
14685 && flag_unsafe_math_optimizations"
14687 [(set_attr "type" "fpspc")
14688 (set_attr "znver1_decode" "vector")
14689 (set_attr "mode" "XF")])
14691 (define_expand "atan2xf3"
14692 [(parallel [(set (match_operand:XF 0 "register_operand")
14693 (unspec:XF [(match_operand:XF 2 "register_operand")
14694 (match_operand:XF 1 "register_operand")]
14696 (clobber (match_scratch:XF 3))])]
14697 "TARGET_USE_FANCY_MATH_387
14698 && flag_unsafe_math_optimizations")
14700 (define_expand "atan2<mode>3"
14701 [(use (match_operand:MODEF 0 "register_operand"))
14702 (use (match_operand:MODEF 1 "register_operand"))
14703 (use (match_operand:MODEF 2 "register_operand"))]
14704 "TARGET_USE_FANCY_MATH_387
14705 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14706 || TARGET_MIX_SSE_I387)
14707 && flag_unsafe_math_optimizations"
14709 rtx op0 = gen_reg_rtx (XFmode);
14711 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14712 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14716 (define_expand "atanxf2"
14717 [(parallel [(set (match_operand:XF 0 "register_operand")
14718 (unspec:XF [(match_dup 2)
14719 (match_operand:XF 1 "register_operand")]
14721 (clobber (match_scratch:XF 3))])]
14722 "TARGET_USE_FANCY_MATH_387
14723 && flag_unsafe_math_optimizations"
14725 operands[2] = gen_reg_rtx (XFmode);
14726 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14729 (define_expand "atan<mode>2"
14730 [(use (match_operand:MODEF 0 "register_operand"))
14731 (use (match_operand:MODEF 1 "register_operand"))]
14732 "TARGET_USE_FANCY_MATH_387
14733 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14734 || TARGET_MIX_SSE_I387)
14735 && flag_unsafe_math_optimizations"
14737 rtx op0 = gen_reg_rtx (XFmode);
14739 rtx op2 = gen_reg_rtx (<MODE>mode);
14740 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14742 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14743 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14747 (define_expand "asinxf2"
14748 [(set (match_dup 2)
14749 (mult:XF (match_operand:XF 1 "register_operand")
14751 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14752 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14753 (parallel [(set (match_operand:XF 0 "register_operand")
14754 (unspec:XF [(match_dup 5) (match_dup 1)]
14756 (clobber (match_scratch:XF 6))])]
14757 "TARGET_USE_FANCY_MATH_387
14758 && flag_unsafe_math_optimizations"
14762 for (i = 2; i < 6; i++)
14763 operands[i] = gen_reg_rtx (XFmode);
14765 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14768 (define_expand "asin<mode>2"
14769 [(use (match_operand:MODEF 0 "register_operand"))
14770 (use (match_operand:MODEF 1 "general_operand"))]
14771 "TARGET_USE_FANCY_MATH_387
14772 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14773 || TARGET_MIX_SSE_I387)
14774 && flag_unsafe_math_optimizations"
14776 rtx op0 = gen_reg_rtx (XFmode);
14777 rtx op1 = gen_reg_rtx (XFmode);
14779 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14780 emit_insn (gen_asinxf2 (op0, op1));
14781 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14785 (define_expand "acosxf2"
14786 [(set (match_dup 2)
14787 (mult:XF (match_operand:XF 1 "register_operand")
14789 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14790 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14791 (parallel [(set (match_operand:XF 0 "register_operand")
14792 (unspec:XF [(match_dup 1) (match_dup 5)]
14794 (clobber (match_scratch:XF 6))])]
14795 "TARGET_USE_FANCY_MATH_387
14796 && flag_unsafe_math_optimizations"
14800 for (i = 2; i < 6; i++)
14801 operands[i] = gen_reg_rtx (XFmode);
14803 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14806 (define_expand "acos<mode>2"
14807 [(use (match_operand:MODEF 0 "register_operand"))
14808 (use (match_operand:MODEF 1 "general_operand"))]
14809 "TARGET_USE_FANCY_MATH_387
14810 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14811 || TARGET_MIX_SSE_I387)
14812 && flag_unsafe_math_optimizations"
14814 rtx op0 = gen_reg_rtx (XFmode);
14815 rtx op1 = gen_reg_rtx (XFmode);
14817 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14818 emit_insn (gen_acosxf2 (op0, op1));
14819 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14823 (define_insn "fyl2xxf3_i387"
14824 [(set (match_operand:XF 0 "register_operand" "=f")
14825 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14826 (match_operand:XF 2 "register_operand" "u")]
14828 (clobber (match_scratch:XF 3 "=2"))]
14829 "TARGET_USE_FANCY_MATH_387
14830 && flag_unsafe_math_optimizations"
14832 [(set_attr "type" "fpspc")
14833 (set_attr "znver1_decode" "vector")
14834 (set_attr "mode" "XF")])
14836 (define_insn "fyl2x_extend<mode>xf3_i387"
14837 [(set (match_operand:XF 0 "register_operand" "=f")
14838 (unspec:XF [(float_extend:XF
14839 (match_operand:MODEF 1 "register_operand" "0"))
14840 (match_operand:XF 2 "register_operand" "u")]
14842 (clobber (match_scratch:XF 3 "=2"))]
14843 "TARGET_USE_FANCY_MATH_387
14844 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14845 || TARGET_MIX_SSE_I387)
14846 && flag_unsafe_math_optimizations"
14848 [(set_attr "type" "fpspc")
14849 (set_attr "znver1_decode" "vector")
14850 (set_attr "mode" "XF")])
14852 (define_expand "logxf2"
14853 [(parallel [(set (match_operand:XF 0 "register_operand")
14854 (unspec:XF [(match_operand:XF 1 "register_operand")
14855 (match_dup 2)] UNSPEC_FYL2X))
14856 (clobber (match_scratch:XF 3))])]
14857 "TARGET_USE_FANCY_MATH_387
14858 && flag_unsafe_math_optimizations"
14860 operands[2] = gen_reg_rtx (XFmode);
14861 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14864 (define_expand "log<mode>2"
14865 [(use (match_operand:MODEF 0 "register_operand"))
14866 (use (match_operand:MODEF 1 "register_operand"))]
14867 "TARGET_USE_FANCY_MATH_387
14868 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14869 || TARGET_MIX_SSE_I387)
14870 && flag_unsafe_math_optimizations"
14872 rtx op0 = gen_reg_rtx (XFmode);
14874 rtx op2 = gen_reg_rtx (XFmode);
14875 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14877 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14878 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14882 (define_expand "log10xf2"
14883 [(parallel [(set (match_operand:XF 0 "register_operand")
14884 (unspec:XF [(match_operand:XF 1 "register_operand")
14885 (match_dup 2)] UNSPEC_FYL2X))
14886 (clobber (match_scratch:XF 3))])]
14887 "TARGET_USE_FANCY_MATH_387
14888 && flag_unsafe_math_optimizations"
14890 operands[2] = gen_reg_rtx (XFmode);
14891 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14894 (define_expand "log10<mode>2"
14895 [(use (match_operand:MODEF 0 "register_operand"))
14896 (use (match_operand:MODEF 1 "register_operand"))]
14897 "TARGET_USE_FANCY_MATH_387
14898 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14899 || TARGET_MIX_SSE_I387)
14900 && flag_unsafe_math_optimizations"
14902 rtx op0 = gen_reg_rtx (XFmode);
14904 rtx op2 = gen_reg_rtx (XFmode);
14905 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14907 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14908 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14912 (define_expand "log2xf2"
14913 [(parallel [(set (match_operand:XF 0 "register_operand")
14914 (unspec:XF [(match_operand:XF 1 "register_operand")
14915 (match_dup 2)] UNSPEC_FYL2X))
14916 (clobber (match_scratch:XF 3))])]
14917 "TARGET_USE_FANCY_MATH_387
14918 && flag_unsafe_math_optimizations"
14920 operands[2] = gen_reg_rtx (XFmode);
14921 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14924 (define_expand "log2<mode>2"
14925 [(use (match_operand:MODEF 0 "register_operand"))
14926 (use (match_operand:MODEF 1 "register_operand"))]
14927 "TARGET_USE_FANCY_MATH_387
14928 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14929 || TARGET_MIX_SSE_I387)
14930 && flag_unsafe_math_optimizations"
14932 rtx op0 = gen_reg_rtx (XFmode);
14934 rtx op2 = gen_reg_rtx (XFmode);
14935 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14937 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14938 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14942 (define_insn "fyl2xp1xf3_i387"
14943 [(set (match_operand:XF 0 "register_operand" "=f")
14944 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14945 (match_operand:XF 2 "register_operand" "u")]
14947 (clobber (match_scratch:XF 3 "=2"))]
14948 "TARGET_USE_FANCY_MATH_387
14949 && flag_unsafe_math_optimizations"
14951 [(set_attr "type" "fpspc")
14952 (set_attr "znver1_decode" "vector")
14953 (set_attr "mode" "XF")])
14955 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14956 [(set (match_operand:XF 0 "register_operand" "=f")
14957 (unspec:XF [(float_extend:XF
14958 (match_operand:MODEF 1 "register_operand" "0"))
14959 (match_operand:XF 2 "register_operand" "u")]
14961 (clobber (match_scratch:XF 3 "=2"))]
14962 "TARGET_USE_FANCY_MATH_387
14963 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14964 || TARGET_MIX_SSE_I387)
14965 && flag_unsafe_math_optimizations"
14967 [(set_attr "type" "fpspc")
14968 (set_attr "znver1_decode" "vector")
14969 (set_attr "mode" "XF")])
14971 (define_expand "log1pxf2"
14972 [(use (match_operand:XF 0 "register_operand"))
14973 (use (match_operand:XF 1 "register_operand"))]
14974 "TARGET_USE_FANCY_MATH_387
14975 && flag_unsafe_math_optimizations"
14977 ix86_emit_i387_log1p (operands[0], operands[1]);
14981 (define_expand "log1p<mode>2"
14982 [(use (match_operand:MODEF 0 "register_operand"))
14983 (use (match_operand:MODEF 1 "register_operand"))]
14984 "TARGET_USE_FANCY_MATH_387
14985 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14986 || TARGET_MIX_SSE_I387)
14987 && flag_unsafe_math_optimizations"
14991 op0 = gen_reg_rtx (XFmode);
14993 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14995 ix86_emit_i387_log1p (op0, operands[1]);
14996 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15000 (define_insn "fxtractxf3_i387"
15001 [(set (match_operand:XF 0 "register_operand" "=f")
15002 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15003 UNSPEC_XTRACT_FRACT))
15004 (set (match_operand:XF 1 "register_operand" "=u")
15005 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15006 "TARGET_USE_FANCY_MATH_387
15007 && flag_unsafe_math_optimizations"
15009 [(set_attr "type" "fpspc")
15010 (set_attr "znver1_decode" "vector")
15011 (set_attr "mode" "XF")])
15013 (define_insn "fxtract_extend<mode>xf3_i387"
15014 [(set (match_operand:XF 0 "register_operand" "=f")
15015 (unspec:XF [(float_extend:XF
15016 (match_operand:MODEF 2 "register_operand" "0"))]
15017 UNSPEC_XTRACT_FRACT))
15018 (set (match_operand:XF 1 "register_operand" "=u")
15019 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
15020 "TARGET_USE_FANCY_MATH_387
15021 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15022 || TARGET_MIX_SSE_I387)
15023 && flag_unsafe_math_optimizations"
15025 [(set_attr "type" "fpspc")
15026 (set_attr "znver1_decode" "vector")
15027 (set_attr "mode" "XF")])
15029 (define_expand "logbxf2"
15030 [(parallel [(set (match_dup 2)
15031 (unspec:XF [(match_operand:XF 1 "register_operand")]
15032 UNSPEC_XTRACT_FRACT))
15033 (set (match_operand:XF 0 "register_operand")
15034 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15035 "TARGET_USE_FANCY_MATH_387
15036 && flag_unsafe_math_optimizations"
15037 "operands[2] = gen_reg_rtx (XFmode);")
15039 (define_expand "logb<mode>2"
15040 [(use (match_operand:MODEF 0 "register_operand"))
15041 (use (match_operand:MODEF 1 "register_operand"))]
15042 "TARGET_USE_FANCY_MATH_387
15043 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15044 || TARGET_MIX_SSE_I387)
15045 && flag_unsafe_math_optimizations"
15047 rtx op0 = gen_reg_rtx (XFmode);
15048 rtx op1 = gen_reg_rtx (XFmode);
15050 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15051 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
15055 (define_expand "ilogbxf2"
15056 [(use (match_operand:SI 0 "register_operand"))
15057 (use (match_operand:XF 1 "register_operand"))]
15058 "TARGET_USE_FANCY_MATH_387
15059 && flag_unsafe_math_optimizations"
15063 if (optimize_insn_for_size_p ())
15066 op0 = gen_reg_rtx (XFmode);
15067 op1 = gen_reg_rtx (XFmode);
15069 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
15070 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15074 (define_expand "ilogb<mode>2"
15075 [(use (match_operand:SI 0 "register_operand"))
15076 (use (match_operand:MODEF 1 "register_operand"))]
15077 "TARGET_USE_FANCY_MATH_387
15078 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15079 || TARGET_MIX_SSE_I387)
15080 && flag_unsafe_math_optimizations"
15084 if (optimize_insn_for_size_p ())
15087 op0 = gen_reg_rtx (XFmode);
15088 op1 = gen_reg_rtx (XFmode);
15090 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15091 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15095 (define_insn "*f2xm1xf2_i387"
15096 [(set (match_operand:XF 0 "register_operand" "=f")
15097 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15099 "TARGET_USE_FANCY_MATH_387
15100 && flag_unsafe_math_optimizations"
15102 [(set_attr "type" "fpspc")
15103 (set_attr "znver1_decode" "vector")
15104 (set_attr "mode" "XF")])
15106 (define_insn "fscalexf4_i387"
15107 [(set (match_operand:XF 0 "register_operand" "=f")
15108 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15109 (match_operand:XF 3 "register_operand" "1")]
15110 UNSPEC_FSCALE_FRACT))
15111 (set (match_operand:XF 1 "register_operand" "=u")
15112 (unspec:XF [(match_dup 2) (match_dup 3)]
15113 UNSPEC_FSCALE_EXP))]
15114 "TARGET_USE_FANCY_MATH_387
15115 && flag_unsafe_math_optimizations"
15117 [(set_attr "type" "fpspc")
15118 (set_attr "znver1_decode" "vector")
15119 (set_attr "mode" "XF")])
15121 (define_expand "expNcorexf3"
15122 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15123 (match_operand:XF 2 "register_operand")))
15124 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15125 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15126 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15127 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15128 (parallel [(set (match_operand:XF 0 "register_operand")
15129 (unspec:XF [(match_dup 8) (match_dup 4)]
15130 UNSPEC_FSCALE_FRACT))
15132 (unspec:XF [(match_dup 8) (match_dup 4)]
15133 UNSPEC_FSCALE_EXP))])]
15134 "TARGET_USE_FANCY_MATH_387
15135 && flag_unsafe_math_optimizations"
15139 for (i = 3; i < 10; i++)
15140 operands[i] = gen_reg_rtx (XFmode);
15142 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15145 (define_expand "expxf2"
15146 [(use (match_operand:XF 0 "register_operand"))
15147 (use (match_operand:XF 1 "register_operand"))]
15148 "TARGET_USE_FANCY_MATH_387
15149 && flag_unsafe_math_optimizations"
15153 op2 = gen_reg_rtx (XFmode);
15154 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
15156 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15160 (define_expand "exp<mode>2"
15161 [(use (match_operand:MODEF 0 "register_operand"))
15162 (use (match_operand:MODEF 1 "general_operand"))]
15163 "TARGET_USE_FANCY_MATH_387
15164 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15165 || TARGET_MIX_SSE_I387)
15166 && flag_unsafe_math_optimizations"
15170 op0 = gen_reg_rtx (XFmode);
15171 op1 = gen_reg_rtx (XFmode);
15173 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15174 emit_insn (gen_expxf2 (op0, op1));
15175 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15179 (define_expand "exp10xf2"
15180 [(use (match_operand:XF 0 "register_operand"))
15181 (use (match_operand:XF 1 "register_operand"))]
15182 "TARGET_USE_FANCY_MATH_387
15183 && flag_unsafe_math_optimizations"
15187 op2 = gen_reg_rtx (XFmode);
15188 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
15190 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15194 (define_expand "exp10<mode>2"
15195 [(use (match_operand:MODEF 0 "register_operand"))
15196 (use (match_operand:MODEF 1 "general_operand"))]
15197 "TARGET_USE_FANCY_MATH_387
15198 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15199 || TARGET_MIX_SSE_I387)
15200 && flag_unsafe_math_optimizations"
15204 op0 = gen_reg_rtx (XFmode);
15205 op1 = gen_reg_rtx (XFmode);
15207 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15208 emit_insn (gen_exp10xf2 (op0, op1));
15209 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15213 (define_expand "exp2xf2"
15214 [(use (match_operand:XF 0 "register_operand"))
15215 (use (match_operand:XF 1 "register_operand"))]
15216 "TARGET_USE_FANCY_MATH_387
15217 && flag_unsafe_math_optimizations"
15221 op2 = gen_reg_rtx (XFmode);
15222 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15224 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15228 (define_expand "exp2<mode>2"
15229 [(use (match_operand:MODEF 0 "register_operand"))
15230 (use (match_operand:MODEF 1 "general_operand"))]
15231 "TARGET_USE_FANCY_MATH_387
15232 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15233 || TARGET_MIX_SSE_I387)
15234 && flag_unsafe_math_optimizations"
15238 op0 = gen_reg_rtx (XFmode);
15239 op1 = gen_reg_rtx (XFmode);
15241 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15242 emit_insn (gen_exp2xf2 (op0, op1));
15243 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15247 (define_expand "expm1xf2"
15248 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15250 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15251 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15252 (set (match_dup 9) (float_extend:XF (match_dup 13)))
15253 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15254 (parallel [(set (match_dup 7)
15255 (unspec:XF [(match_dup 6) (match_dup 4)]
15256 UNSPEC_FSCALE_FRACT))
15258 (unspec:XF [(match_dup 6) (match_dup 4)]
15259 UNSPEC_FSCALE_EXP))])
15260 (parallel [(set (match_dup 10)
15261 (unspec:XF [(match_dup 9) (match_dup 8)]
15262 UNSPEC_FSCALE_FRACT))
15263 (set (match_dup 11)
15264 (unspec:XF [(match_dup 9) (match_dup 8)]
15265 UNSPEC_FSCALE_EXP))])
15266 (set (match_dup 12) (minus:XF (match_dup 10)
15267 (float_extend:XF (match_dup 13))))
15268 (set (match_operand:XF 0 "register_operand")
15269 (plus:XF (match_dup 12) (match_dup 7)))]
15270 "TARGET_USE_FANCY_MATH_387
15271 && flag_unsafe_math_optimizations"
15275 for (i = 2; i < 13; i++)
15276 operands[i] = gen_reg_rtx (XFmode);
15279 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
15281 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
15284 (define_expand "expm1<mode>2"
15285 [(use (match_operand:MODEF 0 "register_operand"))
15286 (use (match_operand:MODEF 1 "general_operand"))]
15287 "TARGET_USE_FANCY_MATH_387
15288 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15289 || TARGET_MIX_SSE_I387)
15290 && flag_unsafe_math_optimizations"
15294 op0 = gen_reg_rtx (XFmode);
15295 op1 = gen_reg_rtx (XFmode);
15297 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15298 emit_insn (gen_expm1xf2 (op0, op1));
15299 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15303 (define_expand "ldexpxf3"
15304 [(match_operand:XF 0 "register_operand")
15305 (match_operand:XF 1 "register_operand")
15306 (match_operand:SI 2 "register_operand")]
15307 "TARGET_USE_FANCY_MATH_387
15308 && flag_unsafe_math_optimizations"
15312 tmp1 = gen_reg_rtx (XFmode);
15313 tmp2 = gen_reg_rtx (XFmode);
15315 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
15316 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
15317 operands[1], tmp1));
15321 (define_expand "ldexp<mode>3"
15322 [(use (match_operand:MODEF 0 "register_operand"))
15323 (use (match_operand:MODEF 1 "general_operand"))
15324 (use (match_operand:SI 2 "register_operand"))]
15325 "TARGET_USE_FANCY_MATH_387
15326 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15327 || TARGET_MIX_SSE_I387)
15328 && flag_unsafe_math_optimizations"
15332 op0 = gen_reg_rtx (XFmode);
15333 op1 = gen_reg_rtx (XFmode);
15335 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15336 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15337 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15341 (define_expand "scalbxf3"
15342 [(parallel [(set (match_operand:XF 0 " register_operand")
15343 (unspec:XF [(match_operand:XF 1 "register_operand")
15344 (match_operand:XF 2 "register_operand")]
15345 UNSPEC_FSCALE_FRACT))
15347 (unspec:XF [(match_dup 1) (match_dup 2)]
15348 UNSPEC_FSCALE_EXP))])]
15349 "TARGET_USE_FANCY_MATH_387
15350 && flag_unsafe_math_optimizations"
15352 operands[3] = gen_reg_rtx (XFmode);
15355 (define_expand "scalb<mode>3"
15356 [(use (match_operand:MODEF 0 "register_operand"))
15357 (use (match_operand:MODEF 1 "general_operand"))
15358 (use (match_operand:MODEF 2 "general_operand"))]
15359 "TARGET_USE_FANCY_MATH_387
15360 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15361 || TARGET_MIX_SSE_I387)
15362 && flag_unsafe_math_optimizations"
15366 op0 = gen_reg_rtx (XFmode);
15367 op1 = gen_reg_rtx (XFmode);
15368 op2 = gen_reg_rtx (XFmode);
15370 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15371 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15372 emit_insn (gen_scalbxf3 (op0, op1, op2));
15373 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15377 (define_expand "significandxf2"
15378 [(parallel [(set (match_operand:XF 0 "register_operand")
15379 (unspec:XF [(match_operand:XF 1 "register_operand")]
15380 UNSPEC_XTRACT_FRACT))
15382 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15383 "TARGET_USE_FANCY_MATH_387
15384 && flag_unsafe_math_optimizations"
15385 "operands[2] = gen_reg_rtx (XFmode);")
15387 (define_expand "significand<mode>2"
15388 [(use (match_operand:MODEF 0 "register_operand"))
15389 (use (match_operand:MODEF 1 "register_operand"))]
15390 "TARGET_USE_FANCY_MATH_387
15391 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15392 || TARGET_MIX_SSE_I387)
15393 && flag_unsafe_math_optimizations"
15395 rtx op0 = gen_reg_rtx (XFmode);
15396 rtx op1 = gen_reg_rtx (XFmode);
15398 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15399 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15404 (define_insn "sse4_1_round<mode>2"
15405 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
15406 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x,v")
15407 (match_operand:SI 2 "const_0_to_15_operand" "n,n")]
15411 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
15412 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15413 [(set_attr "type" "ssecvt")
15414 (set_attr "prefix_extra" "1,*")
15415 (set_attr "length_immediate" "*,1")
15416 (set_attr "prefix" "maybe_vex,evex")
15417 (set_attr "isa" "noavx512f,avx512f")
15418 (set_attr "mode" "<MODE>")])
15420 (define_insn "rintxf2"
15421 [(set (match_operand:XF 0 "register_operand" "=f")
15422 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15424 "TARGET_USE_FANCY_MATH_387"
15426 [(set_attr "type" "fpspc")
15427 (set_attr "znver1_decode" "vector")
15428 (set_attr "mode" "XF")])
15430 (define_insn "rint<mode>2_frndint"
15431 [(set (match_operand:MODEF 0 "register_operand" "=f")
15432 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "0")]
15434 "TARGET_USE_FANCY_MATH_387"
15436 [(set_attr "type" "fpspc")
15437 (set_attr "znver1_decode" "vector")
15438 (set_attr "mode" "<MODE>")])
15440 (define_expand "rint<mode>2"
15441 [(use (match_operand:MODEF 0 "register_operand"))
15442 (use (match_operand:MODEF 1 "register_operand"))]
15443 "(TARGET_USE_FANCY_MATH_387
15444 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15445 || TARGET_MIX_SSE_I387))
15446 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15448 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15451 emit_insn (gen_sse4_1_round<mode>2
15452 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
15454 ix86_expand_rint (operands[0], operands[1]);
15457 emit_insn (gen_rint<mode>2_frndint (operands[0], operands[1]));
15461 (define_expand "round<mode>2"
15462 [(match_operand:X87MODEF 0 "register_operand")
15463 (match_operand:X87MODEF 1 "nonimmediate_operand")]
15464 "(TARGET_USE_FANCY_MATH_387
15465 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15466 || TARGET_MIX_SSE_I387)
15467 && flag_unsafe_math_optimizations)
15468 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15469 && !flag_trapping_math && !flag_rounding_math)"
15471 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15472 && !flag_trapping_math && !flag_rounding_math)
15476 operands[1] = force_reg (<MODE>mode, operands[1]);
15477 ix86_expand_round_sse4 (operands[0], operands[1]);
15479 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15480 ix86_expand_round (operands[0], operands[1]);
15482 ix86_expand_rounddf_32 (operands[0], operands[1]);
15486 operands[1] = force_reg (<MODE>mode, operands[1]);
15487 ix86_emit_i387_round (operands[0], operands[1]);
15492 (define_insn_and_split "*fistdi2_1"
15493 [(set (match_operand:DI 0 "nonimmediate_operand")
15494 (unspec:DI [(match_operand:XF 1 "register_operand")]
15496 "TARGET_USE_FANCY_MATH_387
15497 && can_create_pseudo_p ()"
15502 if (memory_operand (operands[0], VOIDmode))
15503 emit_insn (gen_fistdi2 (operands[0], operands[1]));
15506 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15507 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15512 [(set_attr "type" "fpspc")
15513 (set_attr "mode" "DI")])
15515 (define_insn "fistdi2"
15516 [(set (match_operand:DI 0 "memory_operand" "=m")
15517 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15519 (clobber (match_scratch:XF 2 "=&1f"))]
15520 "TARGET_USE_FANCY_MATH_387"
15521 "* return output_fix_trunc (insn, operands, false);"
15522 [(set_attr "type" "fpspc")
15523 (set_attr "mode" "DI")])
15525 (define_insn "fistdi2_with_temp"
15526 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15527 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15529 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15530 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15531 "TARGET_USE_FANCY_MATH_387"
15533 [(set_attr "type" "fpspc")
15534 (set_attr "mode" "DI")])
15537 [(set (match_operand:DI 0 "register_operand")
15538 (unspec:DI [(match_operand:XF 1 "register_operand")]
15540 (clobber (match_operand:DI 2 "memory_operand"))
15541 (clobber (match_scratch 3))]
15543 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15544 (clobber (match_dup 3))])
15545 (set (match_dup 0) (match_dup 2))])
15548 [(set (match_operand:DI 0 "memory_operand")
15549 (unspec:DI [(match_operand:XF 1 "register_operand")]
15551 (clobber (match_operand:DI 2 "memory_operand"))
15552 (clobber (match_scratch 3))]
15554 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15555 (clobber (match_dup 3))])])
15557 (define_insn_and_split "*fist<mode>2_1"
15558 [(set (match_operand:SWI24 0 "register_operand")
15559 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15561 "TARGET_USE_FANCY_MATH_387
15562 && can_create_pseudo_p ()"
15567 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15568 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15572 [(set_attr "type" "fpspc")
15573 (set_attr "mode" "<MODE>")])
15575 (define_insn "fist<mode>2"
15576 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15577 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15579 "TARGET_USE_FANCY_MATH_387"
15580 "* return output_fix_trunc (insn, operands, false);"
15581 [(set_attr "type" "fpspc")
15582 (set_attr "mode" "<MODE>")])
15584 (define_insn "fist<mode>2_with_temp"
15585 [(set (match_operand:SWI24 0 "register_operand" "=r")
15586 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15588 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15589 "TARGET_USE_FANCY_MATH_387"
15591 [(set_attr "type" "fpspc")
15592 (set_attr "mode" "<MODE>")])
15595 [(set (match_operand:SWI24 0 "register_operand")
15596 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15598 (clobber (match_operand:SWI24 2 "memory_operand"))]
15600 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15601 (set (match_dup 0) (match_dup 2))])
15604 [(set (match_operand:SWI24 0 "memory_operand")
15605 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15607 (clobber (match_operand:SWI24 2 "memory_operand"))]
15609 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15611 (define_expand "lrintxf<mode>2"
15612 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15613 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15615 "TARGET_USE_FANCY_MATH_387")
15617 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15618 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15619 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15620 UNSPEC_FIX_NOTRUNC))]
15621 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15623 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15624 [(match_operand:SWI248x 0 "nonimmediate_operand")
15625 (match_operand:X87MODEF 1 "register_operand")]
15626 "(TARGET_USE_FANCY_MATH_387
15627 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15628 || TARGET_MIX_SSE_I387)
15629 && flag_unsafe_math_optimizations)
15630 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15631 && <SWI248x:MODE>mode != HImode
15632 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15633 && !flag_trapping_math && !flag_rounding_math)"
15635 if (optimize_insn_for_size_p ())
15638 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15639 && <SWI248x:MODE>mode != HImode
15640 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15641 && !flag_trapping_math && !flag_rounding_math)
15642 ix86_expand_lround (operands[0], operands[1]);
15644 ix86_emit_i387_round (operands[0], operands[1]);
15648 (define_int_iterator FRNDINT_ROUNDING
15649 [UNSPEC_FRNDINT_FLOOR
15650 UNSPEC_FRNDINT_CEIL
15651 UNSPEC_FRNDINT_TRUNC])
15653 (define_int_iterator FIST_ROUNDING
15657 ;; Base name for define_insn
15658 (define_int_attr rounding_insn
15659 [(UNSPEC_FRNDINT_FLOOR "floor")
15660 (UNSPEC_FRNDINT_CEIL "ceil")
15661 (UNSPEC_FRNDINT_TRUNC "btrunc")
15662 (UNSPEC_FIST_FLOOR "floor")
15663 (UNSPEC_FIST_CEIL "ceil")])
15665 (define_int_attr rounding
15666 [(UNSPEC_FRNDINT_FLOOR "floor")
15667 (UNSPEC_FRNDINT_CEIL "ceil")
15668 (UNSPEC_FRNDINT_TRUNC "trunc")
15669 (UNSPEC_FIST_FLOOR "floor")
15670 (UNSPEC_FIST_CEIL "ceil")])
15672 (define_int_attr ROUNDING
15673 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15674 (UNSPEC_FRNDINT_CEIL "CEIL")
15675 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15676 (UNSPEC_FIST_FLOOR "FLOOR")
15677 (UNSPEC_FIST_CEIL "CEIL")])
15679 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15680 (define_insn_and_split "frndint<mode>2_<rounding>"
15681 [(set (match_operand:X87MODEF 0 "register_operand")
15682 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand")]
15684 (clobber (reg:CC FLAGS_REG))]
15685 "TARGET_USE_FANCY_MATH_387
15686 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
15687 && can_create_pseudo_p ()"
15692 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15694 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15695 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15697 emit_insn (gen_frndint<mode>2_<rounding>_i387 (operands[0], operands[1],
15698 operands[2], operands[3]));
15701 [(set_attr "type" "frndint")
15702 (set_attr "i387_cw" "<rounding>")
15703 (set_attr "mode" "<MODE>")])
15705 (define_insn "frndint<mode>2_<rounding>_i387"
15706 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
15707 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand" "0")]
15709 (use (match_operand:HI 2 "memory_operand" "m"))
15710 (use (match_operand:HI 3 "memory_operand" "m"))]
15711 "TARGET_USE_FANCY_MATH_387
15712 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
15713 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15714 [(set_attr "type" "frndint")
15715 (set_attr "i387_cw" "<rounding>")
15716 (set_attr "mode" "<MODE>")])
15718 (define_expand "<rounding_insn>xf2"
15719 [(parallel [(set (match_operand:XF 0 "register_operand")
15720 (unspec:XF [(match_operand:XF 1 "register_operand")]
15722 (clobber (reg:CC FLAGS_REG))])]
15723 "TARGET_USE_FANCY_MATH_387
15724 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
15726 (define_expand "<rounding_insn><mode>2"
15727 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15728 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15730 (clobber (reg:CC FLAGS_REG))])]
15731 "(TARGET_USE_FANCY_MATH_387
15732 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15733 || TARGET_MIX_SSE_I387)
15734 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
15735 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15736 && (TARGET_ROUND || !flag_trapping_math || flag_fp_int_builtin_inexact))"
15738 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15739 && (TARGET_ROUND || !flag_trapping_math || flag_fp_int_builtin_inexact))
15742 emit_insn (gen_sse4_1_round<mode>2
15743 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>
15745 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15747 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15748 ix86_expand_floorceil (operands[0], operands[1], true);
15749 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15750 ix86_expand_floorceil (operands[0], operands[1], false);
15751 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15752 ix86_expand_trunc (operands[0], operands[1]);
15754 gcc_unreachable ();
15758 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15759 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15760 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15761 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15762 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15763 ix86_expand_truncdf_32 (operands[0], operands[1]);
15765 gcc_unreachable ();
15769 emit_insn (gen_frndint<mode>2_<rounding> (operands[0], operands[1]));
15773 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15774 (define_insn_and_split "frndintxf2_mask_pm"
15775 [(set (match_operand:XF 0 "register_operand")
15776 (unspec:XF [(match_operand:XF 1 "register_operand")]
15777 UNSPEC_FRNDINT_MASK_PM))
15778 (clobber (reg:CC FLAGS_REG))]
15779 "TARGET_USE_FANCY_MATH_387
15780 && flag_unsafe_math_optimizations
15781 && can_create_pseudo_p ()"
15786 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15788 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15789 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15791 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15792 operands[2], operands[3]));
15795 [(set_attr "type" "frndint")
15796 (set_attr "i387_cw" "mask_pm")
15797 (set_attr "mode" "XF")])
15799 (define_insn "frndintxf2_mask_pm_i387"
15800 [(set (match_operand:XF 0 "register_operand" "=f")
15801 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15802 UNSPEC_FRNDINT_MASK_PM))
15803 (use (match_operand:HI 2 "memory_operand" "m"))
15804 (use (match_operand:HI 3 "memory_operand" "m"))]
15805 "TARGET_USE_FANCY_MATH_387
15806 && flag_unsafe_math_optimizations"
15807 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15808 [(set_attr "type" "frndint")
15809 (set_attr "i387_cw" "mask_pm")
15810 (set_attr "mode" "XF")])
15812 (define_expand "nearbyintxf2"
15813 [(parallel [(set (match_operand:XF 0 "register_operand")
15814 (unspec:XF [(match_operand:XF 1 "register_operand")]
15815 UNSPEC_FRNDINT_MASK_PM))
15816 (clobber (reg:CC FLAGS_REG))])]
15817 "TARGET_USE_FANCY_MATH_387
15818 && flag_unsafe_math_optimizations")
15820 (define_expand "nearbyint<mode>2"
15821 [(use (match_operand:MODEF 0 "register_operand"))
15822 (use (match_operand:MODEF 1 "register_operand"))]
15823 "TARGET_USE_FANCY_MATH_387
15824 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15825 || TARGET_MIX_SSE_I387)
15826 && flag_unsafe_math_optimizations"
15828 rtx op0 = gen_reg_rtx (XFmode);
15829 rtx op1 = gen_reg_rtx (XFmode);
15831 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15832 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15834 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15838 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15839 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15840 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15841 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15843 (clobber (reg:CC FLAGS_REG))]
15844 "TARGET_USE_FANCY_MATH_387
15845 && flag_unsafe_math_optimizations
15846 && can_create_pseudo_p ()"
15851 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15853 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15854 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15855 if (memory_operand (operands[0], VOIDmode))
15856 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15857 operands[2], operands[3]));
15860 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15861 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15862 (operands[0], operands[1], operands[2],
15863 operands[3], operands[4]));
15867 [(set_attr "type" "fistp")
15868 (set_attr "i387_cw" "<rounding>")
15869 (set_attr "mode" "<MODE>")])
15871 (define_insn "fistdi2_<rounding>"
15872 [(set (match_operand:DI 0 "memory_operand" "=m")
15873 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15875 (use (match_operand:HI 2 "memory_operand" "m"))
15876 (use (match_operand:HI 3 "memory_operand" "m"))
15877 (clobber (match_scratch:XF 4 "=&1f"))]
15878 "TARGET_USE_FANCY_MATH_387
15879 && flag_unsafe_math_optimizations"
15880 "* return output_fix_trunc (insn, operands, false);"
15881 [(set_attr "type" "fistp")
15882 (set_attr "i387_cw" "<rounding>")
15883 (set_attr "mode" "DI")])
15885 (define_insn "fistdi2_<rounding>_with_temp"
15886 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15887 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15889 (use (match_operand:HI 2 "memory_operand" "m,m"))
15890 (use (match_operand:HI 3 "memory_operand" "m,m"))
15891 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15892 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15893 "TARGET_USE_FANCY_MATH_387
15894 && flag_unsafe_math_optimizations"
15896 [(set_attr "type" "fistp")
15897 (set_attr "i387_cw" "<rounding>")
15898 (set_attr "mode" "DI")])
15901 [(set (match_operand:DI 0 "register_operand")
15902 (unspec:DI [(match_operand:XF 1 "register_operand")]
15904 (use (match_operand:HI 2 "memory_operand"))
15905 (use (match_operand:HI 3 "memory_operand"))
15906 (clobber (match_operand:DI 4 "memory_operand"))
15907 (clobber (match_scratch 5))]
15909 [(parallel [(set (match_dup 4)
15910 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15911 (use (match_dup 2))
15912 (use (match_dup 3))
15913 (clobber (match_dup 5))])
15914 (set (match_dup 0) (match_dup 4))])
15917 [(set (match_operand:DI 0 "memory_operand")
15918 (unspec:DI [(match_operand:XF 1 "register_operand")]
15920 (use (match_operand:HI 2 "memory_operand"))
15921 (use (match_operand:HI 3 "memory_operand"))
15922 (clobber (match_operand:DI 4 "memory_operand"))
15923 (clobber (match_scratch 5))]
15925 [(parallel [(set (match_dup 0)
15926 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15927 (use (match_dup 2))
15928 (use (match_dup 3))
15929 (clobber (match_dup 5))])])
15931 (define_insn "fist<mode>2_<rounding>"
15932 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15933 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15935 (use (match_operand:HI 2 "memory_operand" "m"))
15936 (use (match_operand:HI 3 "memory_operand" "m"))]
15937 "TARGET_USE_FANCY_MATH_387
15938 && flag_unsafe_math_optimizations"
15939 "* return output_fix_trunc (insn, operands, false);"
15940 [(set_attr "type" "fistp")
15941 (set_attr "i387_cw" "<rounding>")
15942 (set_attr "mode" "<MODE>")])
15944 (define_insn "fist<mode>2_<rounding>_with_temp"
15945 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15946 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15948 (use (match_operand:HI 2 "memory_operand" "m,m"))
15949 (use (match_operand:HI 3 "memory_operand" "m,m"))
15950 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15951 "TARGET_USE_FANCY_MATH_387
15952 && flag_unsafe_math_optimizations"
15954 [(set_attr "type" "fistp")
15955 (set_attr "i387_cw" "<rounding>")
15956 (set_attr "mode" "<MODE>")])
15959 [(set (match_operand:SWI24 0 "register_operand")
15960 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15962 (use (match_operand:HI 2 "memory_operand"))
15963 (use (match_operand:HI 3 "memory_operand"))
15964 (clobber (match_operand:SWI24 4 "memory_operand"))]
15966 [(parallel [(set (match_dup 4)
15967 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15968 (use (match_dup 2))
15969 (use (match_dup 3))])
15970 (set (match_dup 0) (match_dup 4))])
15973 [(set (match_operand:SWI24 0 "memory_operand")
15974 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15976 (use (match_operand:HI 2 "memory_operand"))
15977 (use (match_operand:HI 3 "memory_operand"))
15978 (clobber (match_operand:SWI24 4 "memory_operand"))]
15980 [(parallel [(set (match_dup 0)
15981 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15982 (use (match_dup 2))
15983 (use (match_dup 3))])])
15985 (define_expand "l<rounding_insn>xf<mode>2"
15986 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15987 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15989 (clobber (reg:CC FLAGS_REG))])]
15990 "TARGET_USE_FANCY_MATH_387
15991 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15992 && flag_unsafe_math_optimizations")
15994 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15995 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15996 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15998 (clobber (reg:CC FLAGS_REG))])]
15999 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16000 && !flag_trapping_math"
16002 if (TARGET_64BIT && optimize_insn_for_size_p ())
16005 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16006 ix86_expand_lfloorceil (operands[0], operands[1], true);
16007 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16008 ix86_expand_lfloorceil (operands[0], operands[1], false);
16010 gcc_unreachable ();
16015 (define_insn "fxam<mode>2_i387"
16016 [(set (match_operand:HI 0 "register_operand" "=a")
16018 [(match_operand:X87MODEF 1 "register_operand" "f")]
16020 "TARGET_USE_FANCY_MATH_387"
16021 "fxam\n\tfnstsw\t%0"
16022 [(set_attr "type" "multi")
16023 (set_attr "length" "4")
16024 (set_attr "unit" "i387")
16025 (set_attr "mode" "<MODE>")])
16027 (define_insn_and_split "fxam<mode>2_i387_with_temp"
16028 [(set (match_operand:HI 0 "register_operand")
16030 [(match_operand:MODEF 1 "memory_operand")]
16032 "TARGET_USE_FANCY_MATH_387
16033 && can_create_pseudo_p ()"
16036 [(set (match_dup 2)(match_dup 1))
16038 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
16040 operands[2] = gen_reg_rtx (<MODE>mode);
16042 MEM_VOLATILE_P (operands[1]) = 1;
16044 [(set_attr "type" "multi")
16045 (set_attr "unit" "i387")
16046 (set_attr "mode" "<MODE>")])
16048 (define_expand "isinfxf2"
16049 [(use (match_operand:SI 0 "register_operand"))
16050 (use (match_operand:XF 1 "register_operand"))]
16051 "TARGET_USE_FANCY_MATH_387
16052 && ix86_libc_has_function (function_c99_misc)"
16054 rtx mask = GEN_INT (0x45);
16055 rtx val = GEN_INT (0x05);
16057 rtx scratch = gen_reg_rtx (HImode);
16058 rtx res = gen_reg_rtx (QImode);
16060 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16062 emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
16063 emit_insn (gen_cmpqi_ext_3 (scratch, val));
16064 ix86_expand_setcc (res, EQ,
16065 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
16066 emit_insn (gen_zero_extendqisi2 (operands[0], res));
16070 (define_expand "isinf<mode>2"
16071 [(use (match_operand:SI 0 "register_operand"))
16072 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
16073 "TARGET_USE_FANCY_MATH_387
16074 && ix86_libc_has_function (function_c99_misc)
16075 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16077 rtx mask = GEN_INT (0x45);
16078 rtx val = GEN_INT (0x05);
16080 rtx scratch = gen_reg_rtx (HImode);
16081 rtx res = gen_reg_rtx (QImode);
16083 /* Remove excess precision by forcing value through memory. */
16084 if (memory_operand (operands[1], VOIDmode))
16085 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
16088 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16090 emit_move_insn (temp, operands[1]);
16091 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
16094 emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
16095 emit_insn (gen_cmpqi_ext_3 (scratch, val));
16096 ix86_expand_setcc (res, EQ,
16097 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
16098 emit_insn (gen_zero_extendqisi2 (operands[0], res));
16102 (define_expand "signbittf2"
16103 [(use (match_operand:SI 0 "register_operand"))
16104 (use (match_operand:TF 1 "register_operand"))]
16109 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
16110 rtx scratch = gen_reg_rtx (QImode);
16112 emit_insn (gen_ptesttf2 (operands[1], mask));
16113 ix86_expand_setcc (scratch, NE,
16114 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
16116 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
16120 emit_insn (gen_sse_movmskps (operands[0],
16121 gen_lowpart (V4SFmode, operands[1])));
16122 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
16127 (define_expand "signbitxf2"
16128 [(use (match_operand:SI 0 "register_operand"))
16129 (use (match_operand:XF 1 "register_operand"))]
16130 "TARGET_USE_FANCY_MATH_387"
16132 rtx scratch = gen_reg_rtx (HImode);
16134 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16135 emit_insn (gen_andsi3 (operands[0],
16136 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16140 (define_insn "movmsk_df"
16141 [(set (match_operand:SI 0 "register_operand" "=r")
16143 [(match_operand:DF 1 "register_operand" "x")]
16145 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
16146 "%vmovmskpd\t{%1, %0|%0, %1}"
16147 [(set_attr "type" "ssemov")
16148 (set_attr "prefix" "maybe_vex")
16149 (set_attr "mode" "DF")])
16151 ;; Use movmskpd in SSE mode to avoid store forwarding stall
16152 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
16153 (define_expand "signbitdf2"
16154 [(use (match_operand:SI 0 "register_operand"))
16155 (use (match_operand:DF 1 "register_operand"))]
16156 "TARGET_USE_FANCY_MATH_387
16157 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
16159 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
16161 emit_insn (gen_movmsk_df (operands[0], operands[1]));
16162 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
16166 rtx scratch = gen_reg_rtx (HImode);
16168 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
16169 emit_insn (gen_andsi3 (operands[0],
16170 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16175 (define_expand "signbitsf2"
16176 [(use (match_operand:SI 0 "register_operand"))
16177 (use (match_operand:SF 1 "register_operand"))]
16178 "TARGET_USE_FANCY_MATH_387
16179 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
16181 rtx scratch = gen_reg_rtx (HImode);
16183 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
16184 emit_insn (gen_andsi3 (operands[0],
16185 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16189 ;; Block operation instructions
16192 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16195 [(set_attr "length" "1")
16196 (set_attr "length_immediate" "0")
16197 (set_attr "modrm" "0")])
16199 (define_expand "movmem<mode>"
16200 [(use (match_operand:BLK 0 "memory_operand"))
16201 (use (match_operand:BLK 1 "memory_operand"))
16202 (use (match_operand:SWI48 2 "nonmemory_operand"))
16203 (use (match_operand:SWI48 3 "const_int_operand"))
16204 (use (match_operand:SI 4 "const_int_operand"))
16205 (use (match_operand:SI 5 "const_int_operand"))
16206 (use (match_operand:SI 6 ""))
16207 (use (match_operand:SI 7 ""))
16208 (use (match_operand:SI 8 ""))]
16211 if (ix86_expand_set_or_movmem (operands[0], operands[1],
16212 operands[2], NULL, operands[3],
16213 operands[4], operands[5],
16214 operands[6], operands[7],
16215 operands[8], false))
16221 ;; Most CPUs don't like single string operations
16222 ;; Handle this case here to simplify previous expander.
16224 (define_expand "strmov"
16225 [(set (match_dup 4) (match_operand 3 "memory_operand"))
16226 (set (match_operand 1 "memory_operand") (match_dup 4))
16227 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
16228 (clobber (reg:CC FLAGS_REG))])
16229 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
16230 (clobber (reg:CC FLAGS_REG))])]
16233 /* Can't use this for non-default address spaces. */
16234 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
16237 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16239 /* If .md ever supports :P for Pmode, these can be directly
16240 in the pattern above. */
16241 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16242 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16244 /* Can't use this if the user has appropriated esi or edi. */
16245 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16246 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16248 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16249 operands[2], operands[3],
16250 operands[5], operands[6]));
16254 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16257 (define_expand "strmov_singleop"
16258 [(parallel [(set (match_operand 1 "memory_operand")
16259 (match_operand 3 "memory_operand"))
16260 (set (match_operand 0 "register_operand")
16262 (set (match_operand 2 "register_operand")
16263 (match_operand 5))])]
16267 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16270 (define_insn "*strmovdi_rex_1"
16271 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16272 (mem:DI (match_operand:P 3 "register_operand" "1")))
16273 (set (match_operand:P 0 "register_operand" "=D")
16274 (plus:P (match_dup 2)
16276 (set (match_operand:P 1 "register_operand" "=S")
16277 (plus:P (match_dup 3)
16280 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16281 && ix86_check_no_addr_space (insn)"
16283 [(set_attr "type" "str")
16284 (set_attr "memory" "both")
16285 (set_attr "mode" "DI")])
16287 (define_insn "*strmovsi_1"
16288 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16289 (mem:SI (match_operand:P 3 "register_operand" "1")))
16290 (set (match_operand:P 0 "register_operand" "=D")
16291 (plus:P (match_dup 2)
16293 (set (match_operand:P 1 "register_operand" "=S")
16294 (plus:P (match_dup 3)
16296 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16297 && ix86_check_no_addr_space (insn)"
16299 [(set_attr "type" "str")
16300 (set_attr "memory" "both")
16301 (set_attr "mode" "SI")])
16303 (define_insn "*strmovhi_1"
16304 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16305 (mem:HI (match_operand:P 3 "register_operand" "1")))
16306 (set (match_operand:P 0 "register_operand" "=D")
16307 (plus:P (match_dup 2)
16309 (set (match_operand:P 1 "register_operand" "=S")
16310 (plus:P (match_dup 3)
16312 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16313 && ix86_check_no_addr_space (insn)"
16315 [(set_attr "type" "str")
16316 (set_attr "memory" "both")
16317 (set_attr "mode" "HI")])
16319 (define_insn "*strmovqi_1"
16320 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16321 (mem:QI (match_operand:P 3 "register_operand" "1")))
16322 (set (match_operand:P 0 "register_operand" "=D")
16323 (plus:P (match_dup 2)
16325 (set (match_operand:P 1 "register_operand" "=S")
16326 (plus:P (match_dup 3)
16328 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16329 && ix86_check_no_addr_space (insn)"
16331 [(set_attr "type" "str")
16332 (set_attr "memory" "both")
16333 (set (attr "prefix_rex")
16335 (match_test "<P:MODE>mode == DImode")
16337 (const_string "*")))
16338 (set_attr "mode" "QI")])
16340 (define_expand "rep_mov"
16341 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16342 (set (match_operand 0 "register_operand")
16344 (set (match_operand 2 "register_operand")
16346 (set (match_operand 1 "memory_operand")
16347 (match_operand 3 "memory_operand"))
16348 (use (match_dup 4))])]
16352 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16355 (define_insn "*rep_movdi_rex64"
16356 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16357 (set (match_operand:P 0 "register_operand" "=D")
16358 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16360 (match_operand:P 3 "register_operand" "0")))
16361 (set (match_operand:P 1 "register_operand" "=S")
16362 (plus:P (ashift:P (match_dup 5) (const_int 3))
16363 (match_operand:P 4 "register_operand" "1")))
16364 (set (mem:BLK (match_dup 3))
16365 (mem:BLK (match_dup 4)))
16366 (use (match_dup 5))]
16368 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16369 && ix86_check_no_addr_space (insn)"
16371 [(set_attr "type" "str")
16372 (set_attr "prefix_rep" "1")
16373 (set_attr "memory" "both")
16374 (set_attr "mode" "DI")])
16376 (define_insn "*rep_movsi"
16377 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16378 (set (match_operand:P 0 "register_operand" "=D")
16379 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16381 (match_operand:P 3 "register_operand" "0")))
16382 (set (match_operand:P 1 "register_operand" "=S")
16383 (plus:P (ashift:P (match_dup 5) (const_int 2))
16384 (match_operand:P 4 "register_operand" "1")))
16385 (set (mem:BLK (match_dup 3))
16386 (mem:BLK (match_dup 4)))
16387 (use (match_dup 5))]
16388 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16389 && ix86_check_no_addr_space (insn)"
16390 "%^rep{%;} movs{l|d}"
16391 [(set_attr "type" "str")
16392 (set_attr "prefix_rep" "1")
16393 (set_attr "memory" "both")
16394 (set_attr "mode" "SI")])
16396 (define_insn "*rep_movqi"
16397 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16398 (set (match_operand:P 0 "register_operand" "=D")
16399 (plus:P (match_operand:P 3 "register_operand" "0")
16400 (match_operand:P 5 "register_operand" "2")))
16401 (set (match_operand:P 1 "register_operand" "=S")
16402 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16403 (set (mem:BLK (match_dup 3))
16404 (mem:BLK (match_dup 4)))
16405 (use (match_dup 5))]
16406 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16407 && ix86_check_no_addr_space (insn)"
16409 [(set_attr "type" "str")
16410 (set_attr "prefix_rep" "1")
16411 (set_attr "memory" "both")
16412 (set_attr "mode" "QI")])
16414 (define_expand "setmem<mode>"
16415 [(use (match_operand:BLK 0 "memory_operand"))
16416 (use (match_operand:SWI48 1 "nonmemory_operand"))
16417 (use (match_operand:QI 2 "nonmemory_operand"))
16418 (use (match_operand 3 "const_int_operand"))
16419 (use (match_operand:SI 4 "const_int_operand"))
16420 (use (match_operand:SI 5 "const_int_operand"))
16421 (use (match_operand:SI 6 ""))
16422 (use (match_operand:SI 7 ""))
16423 (use (match_operand:SI 8 ""))]
16426 if (ix86_expand_set_or_movmem (operands[0], NULL,
16427 operands[1], operands[2],
16428 operands[3], operands[4],
16429 operands[5], operands[6],
16430 operands[7], operands[8], true))
16436 ;; Most CPUs don't like single string operations
16437 ;; Handle this case here to simplify previous expander.
16439 (define_expand "strset"
16440 [(set (match_operand 1 "memory_operand")
16441 (match_operand 2 "register_operand"))
16442 (parallel [(set (match_operand 0 "register_operand")
16444 (clobber (reg:CC FLAGS_REG))])]
16447 /* Can't use this for non-default address spaces. */
16448 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
16451 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16452 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16454 /* If .md ever supports :P for Pmode, this can be directly
16455 in the pattern above. */
16456 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16457 GEN_INT (GET_MODE_SIZE (GET_MODE
16459 /* Can't use this if the user has appropriated eax or edi. */
16460 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16461 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16463 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16469 (define_expand "strset_singleop"
16470 [(parallel [(set (match_operand 1 "memory_operand")
16471 (match_operand 2 "register_operand"))
16472 (set (match_operand 0 "register_operand")
16474 (unspec [(const_int 0)] UNSPEC_STOS)])]
16478 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16481 (define_insn "*strsetdi_rex_1"
16482 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16483 (match_operand:DI 2 "register_operand" "a"))
16484 (set (match_operand:P 0 "register_operand" "=D")
16485 (plus:P (match_dup 1)
16487 (unspec [(const_int 0)] UNSPEC_STOS)]
16489 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16490 && ix86_check_no_addr_space (insn)"
16492 [(set_attr "type" "str")
16493 (set_attr "memory" "store")
16494 (set_attr "mode" "DI")])
16496 (define_insn "*strsetsi_1"
16497 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16498 (match_operand:SI 2 "register_operand" "a"))
16499 (set (match_operand:P 0 "register_operand" "=D")
16500 (plus:P (match_dup 1)
16502 (unspec [(const_int 0)] UNSPEC_STOS)]
16503 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16504 && ix86_check_no_addr_space (insn)"
16506 [(set_attr "type" "str")
16507 (set_attr "memory" "store")
16508 (set_attr "mode" "SI")])
16510 (define_insn "*strsethi_1"
16511 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16512 (match_operand:HI 2 "register_operand" "a"))
16513 (set (match_operand:P 0 "register_operand" "=D")
16514 (plus:P (match_dup 1)
16516 (unspec [(const_int 0)] UNSPEC_STOS)]
16517 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16518 && ix86_check_no_addr_space (insn)"
16520 [(set_attr "type" "str")
16521 (set_attr "memory" "store")
16522 (set_attr "mode" "HI")])
16524 (define_insn "*strsetqi_1"
16525 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16526 (match_operand:QI 2 "register_operand" "a"))
16527 (set (match_operand:P 0 "register_operand" "=D")
16528 (plus:P (match_dup 1)
16530 (unspec [(const_int 0)] UNSPEC_STOS)]
16531 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16532 && ix86_check_no_addr_space (insn)"
16534 [(set_attr "type" "str")
16535 (set_attr "memory" "store")
16536 (set (attr "prefix_rex")
16538 (match_test "<P:MODE>mode == DImode")
16540 (const_string "*")))
16541 (set_attr "mode" "QI")])
16543 (define_expand "rep_stos"
16544 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16545 (set (match_operand 0 "register_operand")
16547 (set (match_operand 2 "memory_operand") (const_int 0))
16548 (use (match_operand 3 "register_operand"))
16549 (use (match_dup 1))])]
16553 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16556 (define_insn "*rep_stosdi_rex64"
16557 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16558 (set (match_operand:P 0 "register_operand" "=D")
16559 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16561 (match_operand:P 3 "register_operand" "0")))
16562 (set (mem:BLK (match_dup 3))
16564 (use (match_operand:DI 2 "register_operand" "a"))
16565 (use (match_dup 4))]
16567 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16568 && ix86_check_no_addr_space (insn)"
16570 [(set_attr "type" "str")
16571 (set_attr "prefix_rep" "1")
16572 (set_attr "memory" "store")
16573 (set_attr "mode" "DI")])
16575 (define_insn "*rep_stossi"
16576 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16577 (set (match_operand:P 0 "register_operand" "=D")
16578 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16580 (match_operand:P 3 "register_operand" "0")))
16581 (set (mem:BLK (match_dup 3))
16583 (use (match_operand:SI 2 "register_operand" "a"))
16584 (use (match_dup 4))]
16585 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16586 && ix86_check_no_addr_space (insn)"
16587 "%^rep{%;} stos{l|d}"
16588 [(set_attr "type" "str")
16589 (set_attr "prefix_rep" "1")
16590 (set_attr "memory" "store")
16591 (set_attr "mode" "SI")])
16593 (define_insn "*rep_stosqi"
16594 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16595 (set (match_operand:P 0 "register_operand" "=D")
16596 (plus:P (match_operand:P 3 "register_operand" "0")
16597 (match_operand:P 4 "register_operand" "1")))
16598 (set (mem:BLK (match_dup 3))
16600 (use (match_operand:QI 2 "register_operand" "a"))
16601 (use (match_dup 4))]
16602 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16603 && ix86_check_no_addr_space (insn)"
16605 [(set_attr "type" "str")
16606 (set_attr "prefix_rep" "1")
16607 (set_attr "memory" "store")
16608 (set (attr "prefix_rex")
16610 (match_test "<P:MODE>mode == DImode")
16612 (const_string "*")))
16613 (set_attr "mode" "QI")])
16615 (define_expand "cmpstrnsi"
16616 [(set (match_operand:SI 0 "register_operand")
16617 (compare:SI (match_operand:BLK 1 "general_operand")
16618 (match_operand:BLK 2 "general_operand")))
16619 (use (match_operand 3 "general_operand"))
16620 (use (match_operand 4 "immediate_operand"))]
16623 rtx addr1, addr2, out, outlow, count, countreg, align;
16625 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16628 /* Can't use this if the user has appropriated ecx, esi or edi. */
16629 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16632 /* One of the strings must be a constant. If so, expand_builtin_strncmp()
16633 will have rewritten the length arg to be the minimum of the const string
16634 length and the actual length arg. If both strings are the same and
16635 shorter than the length arg, repz cmpsb will not stop at the 0 byte and
16636 will incorrectly base the results on chars past the 0 byte. */
16637 tree t1 = MEM_EXPR (operands[1]);
16638 tree t2 = MEM_EXPR (operands[2]);
16639 if (!((t1 && TREE_CODE (t1) == MEM_REF
16640 && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR
16641 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST)
16642 || (t2 && TREE_CODE (t2) == MEM_REF
16643 && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR
16644 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST)))
16649 out = gen_reg_rtx (SImode);
16651 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16652 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16653 if (addr1 != XEXP (operands[1], 0))
16654 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16655 if (addr2 != XEXP (operands[2], 0))
16656 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16658 count = operands[3];
16659 countreg = ix86_zero_extend_to_Pmode (count);
16661 /* %%% Iff we are testing strict equality, we can use known alignment
16662 to good advantage. This may be possible with combine, particularly
16663 once cc0 is dead. */
16664 align = operands[4];
16666 if (CONST_INT_P (count))
16668 if (INTVAL (count) == 0)
16670 emit_move_insn (operands[0], const0_rtx);
16673 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16674 operands[1], operands[2]));
16678 rtx (*gen_cmp) (rtx, rtx);
16680 gen_cmp = (TARGET_64BIT
16681 ? gen_cmpdi_1 : gen_cmpsi_1);
16683 emit_insn (gen_cmp (countreg, countreg));
16684 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16685 operands[1], operands[2]));
16688 outlow = gen_lowpart (QImode, out);
16689 emit_insn (gen_cmpintqi (outlow));
16690 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16692 if (operands[0] != out)
16693 emit_move_insn (operands[0], out);
16698 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16700 (define_expand "cmpintqi"
16701 [(set (match_dup 1)
16702 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16704 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16705 (parallel [(set (match_operand:QI 0 "register_operand")
16706 (minus:QI (match_dup 1)
16708 (clobber (reg:CC FLAGS_REG))])]
16711 operands[1] = gen_reg_rtx (QImode);
16712 operands[2] = gen_reg_rtx (QImode);
16715 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16716 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16718 (define_expand "cmpstrnqi_nz_1"
16719 [(parallel [(set (reg:CC FLAGS_REG)
16720 (compare:CC (match_operand 4 "memory_operand")
16721 (match_operand 5 "memory_operand")))
16722 (use (match_operand 2 "register_operand"))
16723 (use (match_operand:SI 3 "immediate_operand"))
16724 (clobber (match_operand 0 "register_operand"))
16725 (clobber (match_operand 1 "register_operand"))
16726 (clobber (match_dup 2))])]
16730 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16733 (define_insn "*cmpstrnqi_nz_1"
16734 [(set (reg:CC FLAGS_REG)
16735 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16736 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16737 (use (match_operand:P 6 "register_operand" "2"))
16738 (use (match_operand:SI 3 "immediate_operand" "i"))
16739 (clobber (match_operand:P 0 "register_operand" "=S"))
16740 (clobber (match_operand:P 1 "register_operand" "=D"))
16741 (clobber (match_operand:P 2 "register_operand" "=c"))]
16742 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16743 && ix86_check_no_addr_space (insn)"
16745 [(set_attr "type" "str")
16746 (set_attr "mode" "QI")
16747 (set (attr "prefix_rex")
16749 (match_test "<P:MODE>mode == DImode")
16751 (const_string "*")))
16752 (set_attr "prefix_rep" "1")])
16754 ;; The same, but the count is not known to not be zero.
16756 (define_expand "cmpstrnqi_1"
16757 [(parallel [(set (reg:CC FLAGS_REG)
16758 (if_then_else:CC (ne (match_operand 2 "register_operand")
16760 (compare:CC (match_operand 4 "memory_operand")
16761 (match_operand 5 "memory_operand"))
16763 (use (match_operand:SI 3 "immediate_operand"))
16764 (use (reg:CC FLAGS_REG))
16765 (clobber (match_operand 0 "register_operand"))
16766 (clobber (match_operand 1 "register_operand"))
16767 (clobber (match_dup 2))])]
16771 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16774 (define_insn "*cmpstrnqi_1"
16775 [(set (reg:CC FLAGS_REG)
16776 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16778 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16779 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16781 (use (match_operand:SI 3 "immediate_operand" "i"))
16782 (use (reg:CC FLAGS_REG))
16783 (clobber (match_operand:P 0 "register_operand" "=S"))
16784 (clobber (match_operand:P 1 "register_operand" "=D"))
16785 (clobber (match_operand:P 2 "register_operand" "=c"))]
16786 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16787 && ix86_check_no_addr_space (insn)"
16789 [(set_attr "type" "str")
16790 (set_attr "mode" "QI")
16791 (set (attr "prefix_rex")
16793 (match_test "<P:MODE>mode == DImode")
16795 (const_string "*")))
16796 (set_attr "prefix_rep" "1")])
16798 (define_expand "strlen<mode>"
16799 [(set (match_operand:P 0 "register_operand")
16800 (unspec:P [(match_operand:BLK 1 "general_operand")
16801 (match_operand:QI 2 "immediate_operand")
16802 (match_operand 3 "immediate_operand")]
16806 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16812 (define_expand "strlenqi_1"
16813 [(parallel [(set (match_operand 0 "register_operand")
16815 (clobber (match_operand 1 "register_operand"))
16816 (clobber (reg:CC FLAGS_REG))])]
16820 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16823 (define_insn "*strlenqi_1"
16824 [(set (match_operand:P 0 "register_operand" "=&c")
16825 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16826 (match_operand:QI 2 "register_operand" "a")
16827 (match_operand:P 3 "immediate_operand" "i")
16828 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16829 (clobber (match_operand:P 1 "register_operand" "=D"))
16830 (clobber (reg:CC FLAGS_REG))]
16831 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16832 && ix86_check_no_addr_space (insn)"
16833 "%^repnz{%;} scasb"
16834 [(set_attr "type" "str")
16835 (set_attr "mode" "QI")
16836 (set (attr "prefix_rex")
16838 (match_test "<P:MODE>mode == DImode")
16840 (const_string "*")))
16841 (set_attr "prefix_rep" "1")])
16843 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16844 ;; handled in combine, but it is not currently up to the task.
16845 ;; When used for their truth value, the cmpstrn* expanders generate
16854 ;; The intermediate three instructions are unnecessary.
16856 ;; This one handles cmpstrn*_nz_1...
16859 (set (reg:CC FLAGS_REG)
16860 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16861 (mem:BLK (match_operand 5 "register_operand"))))
16862 (use (match_operand 6 "register_operand"))
16863 (use (match_operand:SI 3 "immediate_operand"))
16864 (clobber (match_operand 0 "register_operand"))
16865 (clobber (match_operand 1 "register_operand"))
16866 (clobber (match_operand 2 "register_operand"))])
16867 (set (match_operand:QI 7 "register_operand")
16868 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16869 (set (match_operand:QI 8 "register_operand")
16870 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16871 (set (reg FLAGS_REG)
16872 (compare (match_dup 7) (match_dup 8)))
16874 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16876 (set (reg:CC FLAGS_REG)
16877 (compare:CC (mem:BLK (match_dup 4))
16878 (mem:BLK (match_dup 5))))
16879 (use (match_dup 6))
16880 (use (match_dup 3))
16881 (clobber (match_dup 0))
16882 (clobber (match_dup 1))
16883 (clobber (match_dup 2))])])
16885 ;; ...and this one handles cmpstrn*_1.
16888 (set (reg:CC FLAGS_REG)
16889 (if_then_else:CC (ne (match_operand 6 "register_operand")
16891 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16892 (mem:BLK (match_operand 5 "register_operand")))
16894 (use (match_operand:SI 3 "immediate_operand"))
16895 (use (reg:CC FLAGS_REG))
16896 (clobber (match_operand 0 "register_operand"))
16897 (clobber (match_operand 1 "register_operand"))
16898 (clobber (match_operand 2 "register_operand"))])
16899 (set (match_operand:QI 7 "register_operand")
16900 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16901 (set (match_operand:QI 8 "register_operand")
16902 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16903 (set (reg FLAGS_REG)
16904 (compare (match_dup 7) (match_dup 8)))
16906 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16908 (set (reg:CC FLAGS_REG)
16909 (if_then_else:CC (ne (match_dup 6)
16911 (compare:CC (mem:BLK (match_dup 4))
16912 (mem:BLK (match_dup 5)))
16914 (use (match_dup 3))
16915 (use (reg:CC FLAGS_REG))
16916 (clobber (match_dup 0))
16917 (clobber (match_dup 1))
16918 (clobber (match_dup 2))])])
16920 ;; Conditional move instructions.
16922 (define_expand "mov<mode>cc"
16923 [(set (match_operand:SWIM 0 "register_operand")
16924 (if_then_else:SWIM (match_operand 1 "comparison_operator")
16925 (match_operand:SWIM 2 "<general_operand>")
16926 (match_operand:SWIM 3 "<general_operand>")))]
16928 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16930 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16931 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16932 ;; So just document what we're doing explicitly.
16934 (define_expand "x86_mov<mode>cc_0_m1"
16936 [(set (match_operand:SWI48 0 "register_operand")
16937 (if_then_else:SWI48
16938 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16939 [(match_operand 1 "flags_reg_operand")
16943 (clobber (reg:CC FLAGS_REG))])])
16945 (define_insn "*x86_mov<mode>cc_0_m1"
16946 [(set (match_operand:SWI48 0 "register_operand" "=r")
16947 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16948 [(reg FLAGS_REG) (const_int 0)])
16951 (clobber (reg:CC FLAGS_REG))]
16953 "sbb{<imodesuffix>}\t%0, %0"
16954 ; Since we don't have the proper number of operands for an alu insn,
16955 ; fill in all the blanks.
16956 [(set_attr "type" "alu")
16957 (set_attr "modrm_class" "op0")
16958 (set_attr "use_carry" "1")
16959 (set_attr "pent_pair" "pu")
16960 (set_attr "memory" "none")
16961 (set_attr "imm_disp" "false")
16962 (set_attr "mode" "<MODE>")
16963 (set_attr "length_immediate" "0")])
16965 (define_insn "*x86_mov<mode>cc_0_m1_se"
16966 [(set (match_operand:SWI48 0 "register_operand" "=r")
16967 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16968 [(reg FLAGS_REG) (const_int 0)])
16971 (clobber (reg:CC FLAGS_REG))]
16973 "sbb{<imodesuffix>}\t%0, %0"
16974 [(set_attr "type" "alu")
16975 (set_attr "modrm_class" "op0")
16976 (set_attr "use_carry" "1")
16977 (set_attr "pent_pair" "pu")
16978 (set_attr "memory" "none")
16979 (set_attr "imm_disp" "false")
16980 (set_attr "mode" "<MODE>")
16981 (set_attr "length_immediate" "0")])
16983 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16984 [(set (match_operand:SWI48 0 "register_operand" "=r")
16985 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16986 [(reg FLAGS_REG) (const_int 0)])))
16987 (clobber (reg:CC FLAGS_REG))]
16989 "sbb{<imodesuffix>}\t%0, %0"
16990 [(set_attr "type" "alu")
16991 (set_attr "modrm_class" "op0")
16992 (set_attr "use_carry" "1")
16993 (set_attr "pent_pair" "pu")
16994 (set_attr "memory" "none")
16995 (set_attr "imm_disp" "false")
16996 (set_attr "mode" "<MODE>")
16997 (set_attr "length_immediate" "0")])
16999 (define_insn "*mov<mode>cc_noc"
17000 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
17001 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17002 [(reg FLAGS_REG) (const_int 0)])
17003 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
17004 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
17005 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17007 cmov%O2%C1\t{%2, %0|%0, %2}
17008 cmov%O2%c1\t{%3, %0|%0, %3}"
17009 [(set_attr "type" "icmov")
17010 (set_attr "mode" "<MODE>")])
17012 (define_insn "*movsicc_noc_zext"
17013 [(set (match_operand:DI 0 "register_operand" "=r,r")
17014 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17015 [(reg FLAGS_REG) (const_int 0)])
17017 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
17019 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
17021 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17023 cmov%O2%C1\t{%2, %k0|%k0, %2}
17024 cmov%O2%c1\t{%3, %k0|%k0, %3}"
17025 [(set_attr "type" "icmov")
17026 (set_attr "mode" "SI")])
17028 ;; Don't do conditional moves with memory inputs. This splitter helps
17029 ;; register starved x86_32 by forcing inputs into registers before reload.
17031 [(set (match_operand:SWI248 0 "register_operand")
17032 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17033 [(reg FLAGS_REG) (const_int 0)])
17034 (match_operand:SWI248 2 "nonimmediate_operand")
17035 (match_operand:SWI248 3 "nonimmediate_operand")))]
17036 "!TARGET_64BIT && TARGET_CMOVE
17037 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17038 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17039 && can_create_pseudo_p ()
17040 && optimize_insn_for_speed_p ()"
17041 [(set (match_dup 0)
17042 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17044 if (MEM_P (operands[2]))
17045 operands[2] = force_reg (<MODE>mode, operands[2]);
17046 if (MEM_P (operands[3]))
17047 operands[3] = force_reg (<MODE>mode, operands[3]);
17050 (define_insn "*movqicc_noc"
17051 [(set (match_operand:QI 0 "register_operand" "=r,r")
17052 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17053 [(reg FLAGS_REG) (const_int 0)])
17054 (match_operand:QI 2 "register_operand" "r,0")
17055 (match_operand:QI 3 "register_operand" "0,r")))]
17056 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17058 [(set_attr "type" "icmov")
17059 (set_attr "mode" "QI")])
17062 [(set (match_operand:SWI12 0 "register_operand")
17063 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
17064 [(reg FLAGS_REG) (const_int 0)])
17065 (match_operand:SWI12 2 "register_operand")
17066 (match_operand:SWI12 3 "register_operand")))]
17067 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
17068 && reload_completed"
17069 [(set (match_dup 0)
17070 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17072 operands[0] = gen_lowpart (SImode, operands[0]);
17073 operands[2] = gen_lowpart (SImode, operands[2]);
17074 operands[3] = gen_lowpart (SImode, operands[3]);
17077 ;; Don't do conditional moves with memory inputs
17079 [(match_scratch:SWI248 4 "r")
17080 (set (match_operand:SWI248 0 "register_operand")
17081 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17082 [(reg FLAGS_REG) (const_int 0)])
17083 (match_operand:SWI248 2 "nonimmediate_operand")
17084 (match_operand:SWI248 3 "nonimmediate_operand")))]
17085 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17086 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17087 && optimize_insn_for_speed_p ()"
17088 [(set (match_dup 4) (match_dup 5))
17090 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17092 if (MEM_P (operands[2]))
17094 operands[5] = operands[2];
17095 operands[2] = operands[4];
17097 else if (MEM_P (operands[3]))
17099 operands[5] = operands[3];
17100 operands[3] = operands[4];
17103 gcc_unreachable ();
17107 [(match_scratch:SI 4 "r")
17108 (set (match_operand:DI 0 "register_operand")
17109 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17110 [(reg FLAGS_REG) (const_int 0)])
17112 (match_operand:SI 2 "nonimmediate_operand"))
17114 (match_operand:SI 3 "nonimmediate_operand"))))]
17116 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17117 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17118 && optimize_insn_for_speed_p ()"
17119 [(set (match_dup 4) (match_dup 5))
17121 (if_then_else:DI (match_dup 1)
17122 (zero_extend:DI (match_dup 2))
17123 (zero_extend:DI (match_dup 3))))]
17125 if (MEM_P (operands[2]))
17127 operands[5] = operands[2];
17128 operands[2] = operands[4];
17130 else if (MEM_P (operands[3]))
17132 operands[5] = operands[3];
17133 operands[3] = operands[4];
17136 gcc_unreachable ();
17139 (define_expand "mov<mode>cc"
17140 [(set (match_operand:X87MODEF 0 "register_operand")
17141 (if_then_else:X87MODEF
17142 (match_operand 1 "comparison_operator")
17143 (match_operand:X87MODEF 2 "register_operand")
17144 (match_operand:X87MODEF 3 "register_operand")))]
17145 "(TARGET_80387 && TARGET_CMOVE)
17146 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17147 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
17149 (define_insn "*movxfcc_1"
17150 [(set (match_operand:XF 0 "register_operand" "=f,f")
17151 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17152 [(reg FLAGS_REG) (const_int 0)])
17153 (match_operand:XF 2 "register_operand" "f,0")
17154 (match_operand:XF 3 "register_operand" "0,f")))]
17155 "TARGET_80387 && TARGET_CMOVE"
17157 fcmov%F1\t{%2, %0|%0, %2}
17158 fcmov%f1\t{%3, %0|%0, %3}"
17159 [(set_attr "type" "fcmov")
17160 (set_attr "mode" "XF")])
17162 (define_insn "*movdfcc_1"
17163 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
17164 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17165 [(reg FLAGS_REG) (const_int 0)])
17166 (match_operand:DF 2 "nonimmediate_operand"
17168 (match_operand:DF 3 "nonimmediate_operand"
17169 "0 ,f,0 ,rm,0, rm")))]
17170 "TARGET_80387 && TARGET_CMOVE
17171 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17173 fcmov%F1\t{%2, %0|%0, %2}
17174 fcmov%f1\t{%3, %0|%0, %3}
17177 cmov%O2%C1\t{%2, %0|%0, %2}
17178 cmov%O2%c1\t{%3, %0|%0, %3}"
17179 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
17180 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
17181 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
17184 [(set (match_operand:DF 0 "general_reg_operand")
17185 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17186 [(reg FLAGS_REG) (const_int 0)])
17187 (match_operand:DF 2 "nonimmediate_operand")
17188 (match_operand:DF 3 "nonimmediate_operand")))]
17189 "!TARGET_64BIT && reload_completed"
17190 [(set (match_dup 2)
17191 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
17193 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
17195 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
17196 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
17199 (define_insn "*movsfcc_1_387"
17200 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
17201 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17202 [(reg FLAGS_REG) (const_int 0)])
17203 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
17204 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
17205 "TARGET_80387 && TARGET_CMOVE
17206 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17208 fcmov%F1\t{%2, %0|%0, %2}
17209 fcmov%f1\t{%3, %0|%0, %3}
17210 cmov%O2%C1\t{%2, %0|%0, %2}
17211 cmov%O2%c1\t{%3, %0|%0, %3}"
17212 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17213 (set_attr "mode" "SF,SF,SI,SI")])
17215 ;; Don't do conditional moves with memory inputs. This splitter helps
17216 ;; register starved x86_32 by forcing inputs into registers before reload.
17218 [(set (match_operand:MODEF 0 "register_operand")
17219 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
17220 [(reg FLAGS_REG) (const_int 0)])
17221 (match_operand:MODEF 2 "nonimmediate_operand")
17222 (match_operand:MODEF 3 "nonimmediate_operand")))]
17223 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17224 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17225 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17226 && can_create_pseudo_p ()
17227 && optimize_insn_for_speed_p ()"
17228 [(set (match_dup 0)
17229 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17231 if (MEM_P (operands[2]))
17232 operands[2] = force_reg (<MODE>mode, operands[2]);
17233 if (MEM_P (operands[3]))
17234 operands[3] = force_reg (<MODE>mode, operands[3]);
17237 ;; Don't do conditional moves with memory inputs
17239 [(match_scratch:MODEF 4 "r")
17240 (set (match_operand:MODEF 0 "general_reg_operand")
17241 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
17242 [(reg FLAGS_REG) (const_int 0)])
17243 (match_operand:MODEF 2 "nonimmediate_operand")
17244 (match_operand:MODEF 3 "nonimmediate_operand")))]
17245 "(<MODE>mode != DFmode || TARGET_64BIT)
17246 && TARGET_80387 && TARGET_CMOVE
17247 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17248 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17249 && optimize_insn_for_speed_p ()"
17250 [(set (match_dup 4) (match_dup 5))
17252 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17254 if (MEM_P (operands[2]))
17256 operands[5] = operands[2];
17257 operands[2] = operands[4];
17259 else if (MEM_P (operands[3]))
17261 operands[5] = operands[3];
17262 operands[3] = operands[4];
17265 gcc_unreachable ();
17268 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
17269 ;; the scalar versions to have only XMM registers as operands.
17271 ;; XOP conditional move
17272 (define_insn "*xop_pcmov_<mode>"
17273 [(set (match_operand:MODEF 0 "register_operand" "=x")
17274 (if_then_else:MODEF
17275 (match_operand:MODEF 1 "register_operand" "x")
17276 (match_operand:MODEF 2 "register_operand" "x")
17277 (match_operand:MODEF 3 "register_operand" "x")))]
17279 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
17280 [(set_attr "type" "sse4arg")])
17282 ;; These versions of the min/max patterns are intentionally ignorant of
17283 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17284 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17285 ;; are undefined in this condition, we're certain this is correct.
17287 (define_insn "<code><mode>3"
17288 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17290 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
17291 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
17292 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17294 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
17295 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17296 [(set_attr "isa" "noavx,avx")
17297 (set_attr "prefix" "orig,vex")
17298 (set_attr "type" "sseadd")
17299 (set_attr "mode" "<MODE>")])
17301 ;; These versions of the min/max patterns implement exactly the operations
17302 ;; min = (op1 < op2 ? op1 : op2)
17303 ;; max = (!(op1 < op2) ? op1 : op2)
17304 ;; Their operands are not commutative, and thus they may be used in the
17305 ;; presence of -0.0 and NaN.
17307 (define_insn "*ieee_s<ieee_maxmin><mode>3"
17308 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17310 [(match_operand:MODEF 1 "register_operand" "0,v")
17311 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
17313 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17315 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
17316 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17317 [(set_attr "isa" "noavx,avx")
17318 (set_attr "prefix" "orig,maybe_evex")
17319 (set_attr "type" "sseadd")
17320 (set_attr "mode" "<MODE>")])
17322 ;; Make two stack loads independent:
17324 ;; fld %st(0) -> fld bb
17325 ;; fmul bb fmul %st(1), %st
17327 ;; Actually we only match the last two instructions for simplicity.
17330 [(set (match_operand 0 "fp_register_operand")
17331 (match_operand 1 "fp_register_operand"))
17333 (match_operator 2 "binary_fp_operator"
17335 (match_operand 3 "memory_operand")]))]
17336 "REGNO (operands[0]) != REGNO (operands[1])"
17337 [(set (match_dup 0) (match_dup 3))
17340 [(match_dup 5) (match_dup 4)]))]
17342 operands[4] = operands[0];
17343 operands[5] = operands[1];
17345 /* The % modifier is not operational anymore in peephole2's, so we have to
17346 swap the operands manually in the case of addition and multiplication. */
17347 if (COMMUTATIVE_ARITH_P (operands[2]))
17348 std::swap (operands[4], operands[5]);
17352 [(set (match_operand 0 "fp_register_operand")
17353 (match_operand 1 "fp_register_operand"))
17355 (match_operator 2 "binary_fp_operator"
17356 [(match_operand 3 "memory_operand")
17358 "REGNO (operands[0]) != REGNO (operands[1])"
17359 [(set (match_dup 0) (match_dup 3))
17362 [(match_dup 4) (match_dup 5)]))]
17364 operands[4] = operands[0];
17365 operands[5] = operands[1];
17367 /* The % modifier is not operational anymore in peephole2's, so we have to
17368 swap the operands manually in the case of addition and multiplication. */
17369 if (COMMUTATIVE_ARITH_P (operands[2]))
17370 std::swap (operands[4], operands[5]);
17373 ;; Conditional addition patterns
17374 (define_expand "add<mode>cc"
17375 [(match_operand:SWI 0 "register_operand")
17376 (match_operand 1 "ordered_comparison_operator")
17377 (match_operand:SWI 2 "register_operand")
17378 (match_operand:SWI 3 "const_int_operand")]
17380 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17382 ;; Misc patterns (?)
17384 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17385 ;; Otherwise there will be nothing to keep
17387 ;; [(set (reg ebp) (reg esp))]
17388 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17389 ;; (clobber (eflags)]
17390 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17392 ;; in proper program order.
17394 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
17395 [(set (match_operand:P 0 "register_operand" "=r,r")
17396 (plus:P (match_operand:P 1 "register_operand" "0,r")
17397 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17398 (clobber (reg:CC FLAGS_REG))
17399 (clobber (mem:BLK (scratch)))]
17402 switch (get_attr_type (insn))
17405 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17408 gcc_assert (rtx_equal_p (operands[0], operands[1]));
17409 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17410 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17412 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17415 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17416 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17419 [(set (attr "type")
17420 (cond [(and (eq_attr "alternative" "0")
17421 (not (match_test "TARGET_OPT_AGU")))
17422 (const_string "alu")
17423 (match_operand:<MODE> 2 "const0_operand")
17424 (const_string "imov")
17426 (const_string "lea")))
17427 (set (attr "length_immediate")
17428 (cond [(eq_attr "type" "imov")
17430 (and (eq_attr "type" "alu")
17431 (match_operand 2 "const128_operand"))
17434 (const_string "*")))
17435 (set_attr "mode" "<MODE>")])
17437 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
17438 [(set (match_operand:P 0 "register_operand" "=r")
17439 (minus:P (match_operand:P 1 "register_operand" "0")
17440 (match_operand:P 2 "register_operand" "r")))
17441 (clobber (reg:CC FLAGS_REG))
17442 (clobber (mem:BLK (scratch)))]
17444 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17445 [(set_attr "type" "alu")
17446 (set_attr "mode" "<MODE>")])
17448 (define_insn "allocate_stack_worker_probe_<mode>"
17449 [(set (match_operand:P 0 "register_operand" "=a")
17450 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17451 UNSPECV_STACK_PROBE))
17452 (clobber (reg:CC FLAGS_REG))]
17453 "ix86_target_stack_probe ()"
17454 "call\t___chkstk_ms"
17455 [(set_attr "type" "multi")
17456 (set_attr "length" "5")])
17458 (define_expand "allocate_stack"
17459 [(match_operand 0 "register_operand")
17460 (match_operand 1 "general_operand")]
17461 "ix86_target_stack_probe ()"
17465 #ifndef CHECK_STACK_LIMIT
17466 #define CHECK_STACK_LIMIT 0
17469 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17470 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17474 rtx (*insn) (rtx, rtx);
17476 x = copy_to_mode_reg (Pmode, operands[1]);
17478 insn = (TARGET_64BIT
17479 ? gen_allocate_stack_worker_probe_di
17480 : gen_allocate_stack_worker_probe_si);
17482 emit_insn (insn (x, x));
17485 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17486 stack_pointer_rtx, 0, OPTAB_DIRECT);
17488 if (x != stack_pointer_rtx)
17489 emit_move_insn (stack_pointer_rtx, x);
17491 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17495 (define_expand "probe_stack"
17496 [(match_operand 0 "memory_operand")]
17499 rtx (*insn) (rtx, rtx)
17500 = (GET_MODE (operands[0]) == DImode
17501 ? gen_probe_stack_di : gen_probe_stack_si);
17503 emit_insn (insn (operands[0], const0_rtx));
17507 ;; Use OR for stack probes, this is shorter.
17508 (define_insn "probe_stack_<mode>"
17509 [(set (match_operand:W 0 "memory_operand" "=m")
17510 (unspec:W [(match_operand:W 1 "const0_operand")]
17511 UNSPEC_PROBE_STACK))
17512 (clobber (reg:CC FLAGS_REG))]
17514 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
17515 [(set_attr "type" "alu1")
17516 (set_attr "mode" "<MODE>")
17517 (set_attr "length_immediate" "1")])
17519 (define_insn "adjust_stack_and_probe<mode>"
17520 [(set (match_operand:P 0 "register_operand" "=r")
17521 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17522 UNSPECV_PROBE_STACK_RANGE))
17523 (set (reg:P SP_REG)
17524 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17525 (clobber (reg:CC FLAGS_REG))
17526 (clobber (mem:BLK (scratch)))]
17528 "* return output_adjust_stack_and_probe (operands[0]);"
17529 [(set_attr "type" "multi")])
17531 (define_insn "probe_stack_range<mode>"
17532 [(set (match_operand:P 0 "register_operand" "=r")
17533 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17534 (match_operand:P 2 "const_int_operand" "n")]
17535 UNSPECV_PROBE_STACK_RANGE))
17536 (clobber (reg:CC FLAGS_REG))]
17538 "* return output_probe_stack_range (operands[0], operands[2]);"
17539 [(set_attr "type" "multi")])
17541 (define_expand "builtin_setjmp_receiver"
17542 [(label_ref (match_operand 0))]
17543 "!TARGET_64BIT && flag_pic"
17549 rtx_code_label *label_rtx = gen_label_rtx ();
17550 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17551 xops[0] = xops[1] = pic_offset_table_rtx;
17552 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17553 ix86_expand_binary_operator (MINUS, SImode, xops);
17557 emit_insn (gen_set_got (pic_offset_table_rtx));
17561 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17562 ;; Do not split instructions with mask registers.
17564 [(set (match_operand 0 "general_reg_operand")
17565 (match_operator 3 "promotable_binary_operator"
17566 [(match_operand 1 "general_reg_operand")
17567 (match_operand 2 "aligned_operand")]))
17568 (clobber (reg:CC FLAGS_REG))]
17569 "! TARGET_PARTIAL_REG_STALL && reload_completed
17570 && ((GET_MODE (operands[0]) == HImode
17571 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17572 /* ??? next two lines just !satisfies_constraint_K (...) */
17573 || !CONST_INT_P (operands[2])
17574 || satisfies_constraint_K (operands[2])))
17575 || (GET_MODE (operands[0]) == QImode
17576 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17577 [(parallel [(set (match_dup 0)
17578 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17579 (clobber (reg:CC FLAGS_REG))])]
17581 operands[0] = gen_lowpart (SImode, operands[0]);
17582 operands[1] = gen_lowpart (SImode, operands[1]);
17583 if (GET_CODE (operands[3]) != ASHIFT)
17584 operands[2] = gen_lowpart (SImode, operands[2]);
17585 operands[3] = shallow_copy_rtx (operands[3]);
17586 PUT_MODE (operands[3], SImode);
17589 ; Promote the QImode tests, as i386 has encoding of the AND
17590 ; instruction with 32-bit sign-extended immediate and thus the
17591 ; instruction size is unchanged, except in the %eax case for
17592 ; which it is increased by one byte, hence the ! optimize_size.
17594 [(set (match_operand 0 "flags_reg_operand")
17595 (match_operator 2 "compare_operator"
17596 [(and (match_operand 3 "aligned_operand")
17597 (match_operand 4 "const_int_operand"))
17599 (set (match_operand 1 "register_operand")
17600 (and (match_dup 3) (match_dup 4)))]
17601 "! TARGET_PARTIAL_REG_STALL && reload_completed
17602 && optimize_insn_for_speed_p ()
17603 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17604 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17605 /* Ensure that the operand will remain sign-extended immediate. */
17606 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17607 [(parallel [(set (match_dup 0)
17608 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17611 (and:SI (match_dup 3) (match_dup 4)))])]
17614 = gen_int_mode (INTVAL (operands[4])
17615 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17616 operands[1] = gen_lowpart (SImode, operands[1]);
17617 operands[3] = gen_lowpart (SImode, operands[3]);
17620 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17621 ; the TEST instruction with 32-bit sign-extended immediate and thus
17622 ; the instruction size would at least double, which is not what we
17623 ; want even with ! optimize_size.
17625 [(set (match_operand 0 "flags_reg_operand")
17626 (match_operator 1 "compare_operator"
17627 [(and (match_operand:HI 2 "aligned_operand")
17628 (match_operand:HI 3 "const_int_operand"))
17630 "! TARGET_PARTIAL_REG_STALL && reload_completed
17631 && ! TARGET_FAST_PREFIX
17632 && optimize_insn_for_speed_p ()
17633 /* Ensure that the operand will remain sign-extended immediate. */
17634 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17635 [(set (match_dup 0)
17636 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17640 = gen_int_mode (INTVAL (operands[3])
17641 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17642 operands[2] = gen_lowpart (SImode, operands[2]);
17646 [(set (match_operand 0 "register_operand")
17647 (neg (match_operand 1 "register_operand")))
17648 (clobber (reg:CC FLAGS_REG))]
17649 "! TARGET_PARTIAL_REG_STALL && reload_completed
17650 && (GET_MODE (operands[0]) == HImode
17651 || (GET_MODE (operands[0]) == QImode
17652 && (TARGET_PROMOTE_QImode
17653 || optimize_insn_for_size_p ())))"
17654 [(parallel [(set (match_dup 0)
17655 (neg:SI (match_dup 1)))
17656 (clobber (reg:CC FLAGS_REG))])]
17658 operands[0] = gen_lowpart (SImode, operands[0]);
17659 operands[1] = gen_lowpart (SImode, operands[1]);
17662 ;; Do not split instructions with mask regs.
17664 [(set (match_operand 0 "general_reg_operand")
17665 (not (match_operand 1 "general_reg_operand")))]
17666 "! TARGET_PARTIAL_REG_STALL && reload_completed
17667 && (GET_MODE (operands[0]) == HImode
17668 || (GET_MODE (operands[0]) == QImode
17669 && (TARGET_PROMOTE_QImode
17670 || optimize_insn_for_size_p ())))"
17671 [(set (match_dup 0)
17672 (not:SI (match_dup 1)))]
17674 operands[0] = gen_lowpart (SImode, operands[0]);
17675 operands[1] = gen_lowpart (SImode, operands[1]);
17678 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17679 ;; transform a complex memory operation into two memory to register operations.
17681 ;; Don't push memory operands
17683 [(set (match_operand:SWI 0 "push_operand")
17684 (match_operand:SWI 1 "memory_operand"))
17685 (match_scratch:SWI 2 "<r>")]
17686 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17687 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17688 [(set (match_dup 2) (match_dup 1))
17689 (set (match_dup 0) (match_dup 2))])
17691 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17694 [(set (match_operand:SF 0 "push_operand")
17695 (match_operand:SF 1 "memory_operand"))
17696 (match_scratch:SF 2 "r")]
17697 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17698 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17699 [(set (match_dup 2) (match_dup 1))
17700 (set (match_dup 0) (match_dup 2))])
17702 ;; Don't move an immediate directly to memory when the instruction
17703 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17705 [(match_scratch:SWI124 1 "<r>")
17706 (set (match_operand:SWI124 0 "memory_operand")
17708 "optimize_insn_for_speed_p ()
17709 && ((<MODE>mode == HImode
17710 && TARGET_LCP_STALL)
17711 || (!TARGET_USE_MOV0
17712 && TARGET_SPLIT_LONG_MOVES
17713 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17714 && peep2_regno_dead_p (0, FLAGS_REG)"
17715 [(parallel [(set (match_dup 2) (const_int 0))
17716 (clobber (reg:CC FLAGS_REG))])
17717 (set (match_dup 0) (match_dup 1))]
17718 "operands[2] = gen_lowpart (SImode, operands[1]);")
17721 [(match_scratch:SWI124 2 "<r>")
17722 (set (match_operand:SWI124 0 "memory_operand")
17723 (match_operand:SWI124 1 "immediate_operand"))]
17724 "optimize_insn_for_speed_p ()
17725 && ((<MODE>mode == HImode
17726 && TARGET_LCP_STALL)
17727 || (TARGET_SPLIT_LONG_MOVES
17728 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17729 [(set (match_dup 2) (match_dup 1))
17730 (set (match_dup 0) (match_dup 2))])
17732 ;; Don't compare memory with zero, load and use a test instead.
17734 [(set (match_operand 0 "flags_reg_operand")
17735 (match_operator 1 "compare_operator"
17736 [(match_operand:SI 2 "memory_operand")
17738 (match_scratch:SI 3 "r")]
17739 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17740 [(set (match_dup 3) (match_dup 2))
17741 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17743 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17744 ;; Don't split NOTs with a displacement operand, because resulting XOR
17745 ;; will not be pairable anyway.
17747 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17748 ;; represented using a modRM byte. The XOR replacement is long decoded,
17749 ;; so this split helps here as well.
17751 ;; Note: Can't do this as a regular split because we can't get proper
17752 ;; lifetime information then.
17755 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
17756 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
17757 "optimize_insn_for_speed_p ()
17758 && ((TARGET_NOT_UNPAIRABLE
17759 && (!MEM_P (operands[0])
17760 || !memory_displacement_operand (operands[0], <MODE>mode)))
17761 || (TARGET_NOT_VECTORMODE
17762 && long_memory_operand (operands[0], <MODE>mode)))
17763 && peep2_regno_dead_p (0, FLAGS_REG)"
17764 [(parallel [(set (match_dup 0)
17765 (xor:SWI124 (match_dup 1) (const_int -1)))
17766 (clobber (reg:CC FLAGS_REG))])])
17768 ;; Non pairable "test imm, reg" instructions can be translated to
17769 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17770 ;; byte opcode instead of two, have a short form for byte operands),
17771 ;; so do it for other CPUs as well. Given that the value was dead,
17772 ;; this should not create any new dependencies. Pass on the sub-word
17773 ;; versions if we're concerned about partial register stalls.
17776 [(set (match_operand 0 "flags_reg_operand")
17777 (match_operator 1 "compare_operator"
17778 [(and:SI (match_operand:SI 2 "register_operand")
17779 (match_operand:SI 3 "immediate_operand"))
17781 "ix86_match_ccmode (insn, CCNOmode)
17782 && (REGNO (operands[2]) != AX_REG
17783 || satisfies_constraint_K (operands[3]))
17784 && peep2_reg_dead_p (1, operands[2])"
17786 [(set (match_dup 0)
17787 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17790 (and:SI (match_dup 2) (match_dup 3)))])])
17792 ;; We don't need to handle HImode case, because it will be promoted to SImode
17793 ;; on ! TARGET_PARTIAL_REG_STALL
17796 [(set (match_operand 0 "flags_reg_operand")
17797 (match_operator 1 "compare_operator"
17798 [(and:QI (match_operand:QI 2 "register_operand")
17799 (match_operand:QI 3 "immediate_operand"))
17801 "! TARGET_PARTIAL_REG_STALL
17802 && ix86_match_ccmode (insn, CCNOmode)
17803 && REGNO (operands[2]) != AX_REG
17804 && peep2_reg_dead_p (1, operands[2])"
17806 [(set (match_dup 0)
17807 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17810 (and:QI (match_dup 2) (match_dup 3)))])])
17813 [(set (match_operand 0 "flags_reg_operand")
17814 (match_operator 1 "compare_operator"
17817 (zero_extract:SI (match_operand 2 "QIreg_operand")
17820 (match_operand 3 "const_int_operand"))
17822 "! TARGET_PARTIAL_REG_STALL
17823 && ix86_match_ccmode (insn, CCNOmode)
17824 && REGNO (operands[2]) != AX_REG
17825 && peep2_reg_dead_p (1, operands[2])"
17827 [(set (match_dup 0)
17831 (zero_extract:SI (match_dup 2)
17836 (set (zero_extract:SI (match_dup 2)
17842 (zero_extract:SI (match_dup 2)
17845 (match_dup 3)) 0))])])
17847 ;; Don't do logical operations with memory inputs.
17849 [(match_scratch:SWI 2 "<r>")
17850 (parallel [(set (match_operand:SWI 0 "register_operand")
17851 (match_operator:SWI 3 "arith_or_logical_operator"
17853 (match_operand:SWI 1 "memory_operand")]))
17854 (clobber (reg:CC FLAGS_REG))])]
17855 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17856 [(set (match_dup 2) (match_dup 1))
17857 (parallel [(set (match_dup 0)
17858 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17859 (clobber (reg:CC FLAGS_REG))])])
17862 [(match_scratch:SWI 2 "<r>")
17863 (parallel [(set (match_operand:SWI 0 "register_operand")
17864 (match_operator:SWI 3 "arith_or_logical_operator"
17865 [(match_operand:SWI 1 "memory_operand")
17867 (clobber (reg:CC FLAGS_REG))])]
17868 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17869 [(set (match_dup 2) (match_dup 1))
17870 (parallel [(set (match_dup 0)
17871 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17872 (clobber (reg:CC FLAGS_REG))])])
17874 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
17875 ;; the memory address refers to the destination of the load!
17878 [(set (match_operand:SWI 0 "general_reg_operand")
17879 (match_operand:SWI 1 "general_reg_operand"))
17880 (parallel [(set (match_dup 0)
17881 (match_operator:SWI 3 "commutative_operator"
17883 (match_operand:SWI 2 "memory_operand")]))
17884 (clobber (reg:CC FLAGS_REG))])]
17885 "REGNO (operands[0]) != REGNO (operands[1])
17886 && (<MODE>mode != QImode
17887 || any_QIreg_operand (operands[1], QImode))"
17888 [(set (match_dup 0) (match_dup 4))
17889 (parallel [(set (match_dup 0)
17890 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17891 (clobber (reg:CC FLAGS_REG))])]
17892 "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
17895 [(set (match_operand 0 "mmx_reg_operand")
17896 (match_operand 1 "mmx_reg_operand"))
17898 (match_operator 3 "commutative_operator"
17900 (match_operand 2 "memory_operand")]))]
17901 "REGNO (operands[0]) != REGNO (operands[1])"
17902 [(set (match_dup 0) (match_dup 2))
17904 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17907 [(set (match_operand 0 "sse_reg_operand")
17908 (match_operand 1 "sse_reg_operand"))
17910 (match_operator 3 "commutative_operator"
17912 (match_operand 2 "memory_operand")]))]
17913 "REGNO (operands[0]) != REGNO (operands[1])"
17914 [(set (match_dup 0) (match_dup 2))
17916 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17918 ; Don't do logical operations with memory outputs
17920 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17921 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17922 ; the same decoder scheduling characteristics as the original.
17925 [(match_scratch:SWI 2 "<r>")
17926 (parallel [(set (match_operand:SWI 0 "memory_operand")
17927 (match_operator:SWI 3 "arith_or_logical_operator"
17929 (match_operand:SWI 1 "<nonmemory_operand>")]))
17930 (clobber (reg:CC FLAGS_REG))])]
17931 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
17932 [(set (match_dup 2) (match_dup 0))
17933 (parallel [(set (match_dup 2)
17934 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17935 (clobber (reg:CC FLAGS_REG))])
17936 (set (match_dup 0) (match_dup 2))])
17939 [(match_scratch:SWI 2 "<r>")
17940 (parallel [(set (match_operand:SWI 0 "memory_operand")
17941 (match_operator:SWI 3 "arith_or_logical_operator"
17942 [(match_operand:SWI 1 "<nonmemory_operand>")
17944 (clobber (reg:CC FLAGS_REG))])]
17945 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
17946 [(set (match_dup 2) (match_dup 0))
17947 (parallel [(set (match_dup 2)
17948 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17949 (clobber (reg:CC FLAGS_REG))])
17950 (set (match_dup 0) (match_dup 2))])
17952 ;; Attempt to use arith or logical operations with memory outputs with
17953 ;; setting of flags.
17955 [(set (match_operand:SWI 0 "register_operand")
17956 (match_operand:SWI 1 "memory_operand"))
17957 (parallel [(set (match_dup 0)
17958 (match_operator:SWI 3 "plusminuslogic_operator"
17960 (match_operand:SWI 2 "<nonmemory_operand>")]))
17961 (clobber (reg:CC FLAGS_REG))])
17962 (set (match_dup 1) (match_dup 0))
17963 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17964 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17965 && peep2_reg_dead_p (4, operands[0])
17966 && !reg_overlap_mentioned_p (operands[0], operands[1])
17967 && !reg_overlap_mentioned_p (operands[0], operands[2])
17968 && (<MODE>mode != QImode
17969 || immediate_operand (operands[2], QImode)
17970 || any_QIreg_operand (operands[2], QImode))
17971 && ix86_match_ccmode (peep2_next_insn (3),
17972 (GET_CODE (operands[3]) == PLUS
17973 || GET_CODE (operands[3]) == MINUS)
17974 ? CCGOCmode : CCNOmode)"
17975 [(parallel [(set (match_dup 4) (match_dup 6))
17976 (set (match_dup 1) (match_dup 5))])]
17978 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17980 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
17981 copy_rtx (operands[1]),
17984 = gen_rtx_COMPARE (GET_MODE (operands[4]),
17985 copy_rtx (operands[5]),
17989 ;; Likewise for instances where we have a lea pattern.
17991 [(set (match_operand:SWI 0 "register_operand")
17992 (match_operand:SWI 1 "memory_operand"))
17993 (set (match_operand:SWI 3 "register_operand")
17994 (plus:SWI (match_dup 0)
17995 (match_operand:SWI 2 "<nonmemory_operand>")))
17996 (set (match_dup 1) (match_dup 3))
17997 (set (reg FLAGS_REG) (compare (match_dup 3) (const_int 0)))]
17998 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17999 && peep2_reg_dead_p (4, operands[3])
18000 && (rtx_equal_p (operands[0], operands[3])
18001 || peep2_reg_dead_p (2, operands[0]))
18002 && !reg_overlap_mentioned_p (operands[0], operands[1])
18003 && !reg_overlap_mentioned_p (operands[3], operands[1])
18004 && !reg_overlap_mentioned_p (operands[0], operands[2])
18005 && (<MODE>mode != QImode
18006 || immediate_operand (operands[2], QImode)
18007 || any_QIreg_operand (operands[2], QImode))
18008 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
18009 [(parallel [(set (match_dup 4) (match_dup 6))
18010 (set (match_dup 1) (match_dup 5))])]
18012 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18014 = gen_rtx_PLUS (<MODE>mode,
18015 copy_rtx (operands[1]),
18018 = gen_rtx_COMPARE (GET_MODE (operands[4]),
18019 copy_rtx (operands[5]),
18024 [(parallel [(set (match_operand:SWI 0 "register_operand")
18025 (match_operator:SWI 2 "plusminuslogic_operator"
18027 (match_operand:SWI 1 "memory_operand")]))
18028 (clobber (reg:CC FLAGS_REG))])
18029 (set (match_dup 1) (match_dup 0))
18030 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18031 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18032 && GET_CODE (operands[2]) != MINUS
18033 && peep2_reg_dead_p (3, operands[0])
18034 && !reg_overlap_mentioned_p (operands[0], operands[1])
18035 && ix86_match_ccmode (peep2_next_insn (2),
18036 GET_CODE (operands[2]) == PLUS
18037 ? CCGOCmode : CCNOmode)"
18038 [(parallel [(set (match_dup 3) (match_dup 5))
18039 (set (match_dup 1) (match_dup 4))])]
18041 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
18043 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18044 copy_rtx (operands[1]),
18047 = gen_rtx_COMPARE (GET_MODE (operands[3]),
18048 copy_rtx (operands[4]),
18053 [(set (match_operand:SWI12 0 "register_operand")
18054 (match_operand:SWI12 1 "memory_operand"))
18055 (parallel [(set (match_operand:SI 4 "register_operand")
18056 (match_operator:SI 3 "plusminuslogic_operator"
18058 (match_operand:SI 2 "nonmemory_operand")]))
18059 (clobber (reg:CC FLAGS_REG))])
18060 (set (match_dup 1) (match_dup 0))
18061 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18062 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18063 && REGNO (operands[0]) == REGNO (operands[4])
18064 && peep2_reg_dead_p (4, operands[0])
18065 && (<MODE>mode != QImode
18066 || immediate_operand (operands[2], SImode)
18067 || any_QIreg_operand (operands[2], SImode))
18068 && !reg_overlap_mentioned_p (operands[0], operands[1])
18069 && !reg_overlap_mentioned_p (operands[0], operands[2])
18070 && ix86_match_ccmode (peep2_next_insn (3),
18071 (GET_CODE (operands[3]) == PLUS
18072 || GET_CODE (operands[3]) == MINUS)
18073 ? CCGOCmode : CCNOmode)"
18074 [(parallel [(set (match_dup 4) (match_dup 6))
18075 (set (match_dup 1) (match_dup 5))])]
18077 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18079 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18080 copy_rtx (operands[1]),
18081 gen_lowpart (<MODE>mode, operands[2]));
18083 = gen_rtx_COMPARE (GET_MODE (operands[4]),
18084 copy_rtx (operands[5]),
18088 ;; Attempt to always use XOR for zeroing registers (including FP modes).
18090 [(set (match_operand 0 "general_reg_operand")
18091 (match_operand 1 "const0_operand"))]
18092 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18093 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18094 && peep2_regno_dead_p (0, FLAGS_REG)"
18095 [(parallel [(set (match_dup 0) (const_int 0))
18096 (clobber (reg:CC FLAGS_REG))])]
18097 "operands[0] = gen_lowpart (word_mode, operands[0]);")
18100 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
18102 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18103 && peep2_regno_dead_p (0, FLAGS_REG)"
18104 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18105 (clobber (reg:CC FLAGS_REG))])])
18107 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
18109 [(set (match_operand:SWI248 0 "general_reg_operand")
18111 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
18112 && peep2_regno_dead_p (0, FLAGS_REG)"
18113 [(parallel [(set (match_dup 0) (const_int -1))
18114 (clobber (reg:CC FLAGS_REG))])]
18116 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
18117 operands[0] = gen_lowpart (SImode, operands[0]);
18120 ;; Attempt to convert simple lea to add/shift.
18121 ;; These can be created by move expanders.
18122 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
18123 ;; relevant lea instructions were already split.
18126 [(set (match_operand:SWI48 0 "register_operand")
18127 (plus:SWI48 (match_dup 0)
18128 (match_operand:SWI48 1 "<nonmemory_operand>")))]
18130 && peep2_regno_dead_p (0, FLAGS_REG)"
18131 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18132 (clobber (reg:CC FLAGS_REG))])])
18135 [(set (match_operand:SWI48 0 "register_operand")
18136 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
18139 && peep2_regno_dead_p (0, FLAGS_REG)"
18140 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18141 (clobber (reg:CC FLAGS_REG))])])
18144 [(set (match_operand:DI 0 "register_operand")
18146 (plus:SI (match_operand:SI 1 "register_operand")
18147 (match_operand:SI 2 "nonmemory_operand"))))]
18148 "TARGET_64BIT && !TARGET_OPT_AGU
18149 && REGNO (operands[0]) == REGNO (operands[1])
18150 && peep2_regno_dead_p (0, FLAGS_REG)"
18151 [(parallel [(set (match_dup 0)
18152 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
18153 (clobber (reg:CC FLAGS_REG))])])
18156 [(set (match_operand:DI 0 "register_operand")
18158 (plus:SI (match_operand:SI 1 "nonmemory_operand")
18159 (match_operand:SI 2 "register_operand"))))]
18160 "TARGET_64BIT && !TARGET_OPT_AGU
18161 && REGNO (operands[0]) == REGNO (operands[2])
18162 && peep2_regno_dead_p (0, FLAGS_REG)"
18163 [(parallel [(set (match_dup 0)
18164 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
18165 (clobber (reg:CC FLAGS_REG))])])
18168 [(set (match_operand:SWI48 0 "register_operand")
18169 (mult:SWI48 (match_dup 0)
18170 (match_operand:SWI48 1 "const_int_operand")))]
18171 "pow2p_hwi (INTVAL (operands[1]))
18172 && peep2_regno_dead_p (0, FLAGS_REG)"
18173 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
18174 (clobber (reg:CC FLAGS_REG))])]
18175 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18178 [(set (match_operand:DI 0 "register_operand")
18180 (mult:SI (match_operand:SI 1 "register_operand")
18181 (match_operand:SI 2 "const_int_operand"))))]
18183 && pow2p_hwi (INTVAL (operands[2]))
18184 && REGNO (operands[0]) == REGNO (operands[1])
18185 && peep2_regno_dead_p (0, FLAGS_REG)"
18186 [(parallel [(set (match_dup 0)
18187 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
18188 (clobber (reg:CC FLAGS_REG))])]
18189 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18191 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18192 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
18193 ;; On many CPUs it is also faster, since special hardware to avoid esp
18194 ;; dependencies is present.
18196 ;; While some of these conversions may be done using splitters, we use
18197 ;; peepholes in order to allow combine_stack_adjustments pass to see
18198 ;; nonobfuscated RTL.
18200 ;; Convert prologue esp subtractions to push.
18201 ;; We need register to push. In order to keep verify_flow_info happy we have
18203 ;; - use scratch and clobber it in order to avoid dependencies
18204 ;; - use already live register
18205 ;; We can't use the second way right now, since there is no reliable way how to
18206 ;; verify that given register is live. First choice will also most likely in
18207 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18208 ;; call clobbered registers are dead. We may want to use base pointer as an
18209 ;; alternative when no register is available later.
18212 [(match_scratch:W 1 "r")
18213 (parallel [(set (reg:P SP_REG)
18214 (plus:P (reg:P SP_REG)
18215 (match_operand:P 0 "const_int_operand")))
18216 (clobber (reg:CC FLAGS_REG))
18217 (clobber (mem:BLK (scratch)))])]
18218 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18219 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
18220 && !ix86_using_red_zone ()"
18221 [(clobber (match_dup 1))
18222 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18223 (clobber (mem:BLK (scratch)))])])
18226 [(match_scratch:W 1 "r")
18227 (parallel [(set (reg:P SP_REG)
18228 (plus:P (reg:P SP_REG)
18229 (match_operand:P 0 "const_int_operand")))
18230 (clobber (reg:CC FLAGS_REG))
18231 (clobber (mem:BLK (scratch)))])]
18232 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
18233 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
18234 && !ix86_using_red_zone ()"
18235 [(clobber (match_dup 1))
18236 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18237 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18238 (clobber (mem:BLK (scratch)))])])
18240 ;; Convert esp subtractions to push.
18242 [(match_scratch:W 1 "r")
18243 (parallel [(set (reg:P SP_REG)
18244 (plus:P (reg:P SP_REG)
18245 (match_operand:P 0 "const_int_operand")))
18246 (clobber (reg:CC FLAGS_REG))])]
18247 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18248 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
18249 && !ix86_using_red_zone ()"
18250 [(clobber (match_dup 1))
18251 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
18254 [(match_scratch:W 1 "r")
18255 (parallel [(set (reg:P SP_REG)
18256 (plus:P (reg:P SP_REG)
18257 (match_operand:P 0 "const_int_operand")))
18258 (clobber (reg:CC FLAGS_REG))])]
18259 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
18260 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
18261 && !ix86_using_red_zone ()"
18262 [(clobber (match_dup 1))
18263 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18264 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
18266 ;; Convert epilogue deallocator to pop.
18268 [(match_scratch:W 1 "r")
18269 (parallel [(set (reg:P SP_REG)
18270 (plus:P (reg:P SP_REG)
18271 (match_operand:P 0 "const_int_operand")))
18272 (clobber (reg:CC FLAGS_REG))
18273 (clobber (mem:BLK (scratch)))])]
18274 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
18275 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
18276 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18277 (clobber (mem:BLK (scratch)))])])
18279 ;; Two pops case is tricky, since pop causes dependency
18280 ;; on destination register. We use two registers if available.
18282 [(match_scratch:W 1 "r")
18283 (match_scratch:W 2 "r")
18284 (parallel [(set (reg:P SP_REG)
18285 (plus:P (reg:P SP_REG)
18286 (match_operand:P 0 "const_int_operand")))
18287 (clobber (reg:CC FLAGS_REG))
18288 (clobber (mem:BLK (scratch)))])]
18289 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
18290 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18291 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18292 (clobber (mem:BLK (scratch)))])
18293 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
18296 [(match_scratch:W 1 "r")
18297 (parallel [(set (reg:P SP_REG)
18298 (plus:P (reg:P SP_REG)
18299 (match_operand:P 0 "const_int_operand")))
18300 (clobber (reg:CC FLAGS_REG))
18301 (clobber (mem:BLK (scratch)))])]
18302 "optimize_insn_for_size_p ()
18303 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18304 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18305 (clobber (mem:BLK (scratch)))])
18306 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18308 ;; Convert esp additions to pop.
18310 [(match_scratch:W 1 "r")
18311 (parallel [(set (reg:P SP_REG)
18312 (plus:P (reg:P SP_REG)
18313 (match_operand:P 0 "const_int_operand")))
18314 (clobber (reg:CC FLAGS_REG))])]
18315 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
18316 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18318 ;; Two pops case is tricky, since pop causes dependency
18319 ;; on destination register. We use two registers if available.
18321 [(match_scratch:W 1 "r")
18322 (match_scratch:W 2 "r")
18323 (parallel [(set (reg:P SP_REG)
18324 (plus:P (reg:P SP_REG)
18325 (match_operand:P 0 "const_int_operand")))
18326 (clobber (reg:CC FLAGS_REG))])]
18327 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18328 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18329 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
18332 [(match_scratch:W 1 "r")
18333 (parallel [(set (reg:P SP_REG)
18334 (plus:P (reg:P SP_REG)
18335 (match_operand:P 0 "const_int_operand")))
18336 (clobber (reg:CC FLAGS_REG))])]
18337 "optimize_insn_for_size_p ()
18338 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18339 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18340 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18342 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18343 ;; required and register dies. Similarly for 128 to -128.
18345 [(set (match_operand 0 "flags_reg_operand")
18346 (match_operator 1 "compare_operator"
18347 [(match_operand 2 "register_operand")
18348 (match_operand 3 "const_int_operand")]))]
18349 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
18350 && incdec_operand (operands[3], GET_MODE (operands[3])))
18351 || (!TARGET_FUSE_CMP_AND_BRANCH
18352 && INTVAL (operands[3]) == 128))
18353 && ix86_match_ccmode (insn, CCGCmode)
18354 && peep2_reg_dead_p (1, operands[2])"
18355 [(parallel [(set (match_dup 0)
18356 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18357 (clobber (match_dup 2))])])
18359 ;; Convert imul by three, five and nine into lea
18362 [(set (match_operand:SWI48 0 "register_operand")
18363 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
18364 (match_operand:SWI48 2 "const359_operand")))
18365 (clobber (reg:CC FLAGS_REG))])]
18366 "!TARGET_PARTIAL_REG_STALL
18367 || <MODE>mode == SImode
18368 || optimize_function_for_size_p (cfun)"
18369 [(set (match_dup 0)
18370 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
18372 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18376 [(set (match_operand:SWI48 0 "register_operand")
18377 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
18378 (match_operand:SWI48 2 "const359_operand")))
18379 (clobber (reg:CC FLAGS_REG))])]
18380 "optimize_insn_for_speed_p ()
18381 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
18382 [(set (match_dup 0) (match_dup 1))
18384 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
18386 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18388 ;; imul $32bit_imm, mem, reg is vector decoded, while
18389 ;; imul $32bit_imm, reg, reg is direct decoded.
18391 [(match_scratch:SWI48 3 "r")
18392 (parallel [(set (match_operand:SWI48 0 "register_operand")
18393 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
18394 (match_operand:SWI48 2 "immediate_operand")))
18395 (clobber (reg:CC FLAGS_REG))])]
18396 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18397 && !satisfies_constraint_K (operands[2])"
18398 [(set (match_dup 3) (match_dup 1))
18399 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
18400 (clobber (reg:CC FLAGS_REG))])])
18403 [(match_scratch:SI 3 "r")
18404 (parallel [(set (match_operand:DI 0 "register_operand")
18406 (mult:SI (match_operand:SI 1 "memory_operand")
18407 (match_operand:SI 2 "immediate_operand"))))
18408 (clobber (reg:CC FLAGS_REG))])]
18410 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18411 && !satisfies_constraint_K (operands[2])"
18412 [(set (match_dup 3) (match_dup 1))
18413 (parallel [(set (match_dup 0)
18414 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18415 (clobber (reg:CC FLAGS_REG))])])
18417 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18418 ;; Convert it into imul reg, reg
18419 ;; It would be better to force assembler to encode instruction using long
18420 ;; immediate, but there is apparently no way to do so.
18422 [(parallel [(set (match_operand:SWI248 0 "register_operand")
18424 (match_operand:SWI248 1 "nonimmediate_operand")
18425 (match_operand:SWI248 2 "const_int_operand")))
18426 (clobber (reg:CC FLAGS_REG))])
18427 (match_scratch:SWI248 3 "r")]
18428 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18429 && satisfies_constraint_K (operands[2])"
18430 [(set (match_dup 3) (match_dup 2))
18431 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
18432 (clobber (reg:CC FLAGS_REG))])]
18434 if (!rtx_equal_p (operands[0], operands[1]))
18435 emit_move_insn (operands[0], operands[1]);
18438 ;; After splitting up read-modify operations, array accesses with memory
18439 ;; operands might end up in form:
18441 ;; movl 4(%esp), %edx
18443 ;; instead of pre-splitting:
18445 ;; addl 4(%esp), %eax
18447 ;; movl 4(%esp), %edx
18448 ;; leal (%edx,%eax,4), %eax
18451 [(match_scratch:W 5 "r")
18452 (parallel [(set (match_operand 0 "register_operand")
18453 (ashift (match_operand 1 "register_operand")
18454 (match_operand 2 "const_int_operand")))
18455 (clobber (reg:CC FLAGS_REG))])
18456 (parallel [(set (match_operand 3 "register_operand")
18457 (plus (match_dup 0)
18458 (match_operand 4 "x86_64_general_operand")))
18459 (clobber (reg:CC FLAGS_REG))])]
18460 "IN_RANGE (INTVAL (operands[2]), 1, 3)
18461 /* Validate MODE for lea. */
18462 && ((!TARGET_PARTIAL_REG_STALL
18463 && (GET_MODE (operands[0]) == QImode
18464 || GET_MODE (operands[0]) == HImode))
18465 || GET_MODE (operands[0]) == SImode
18466 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18467 && (rtx_equal_p (operands[0], operands[3])
18468 || peep2_reg_dead_p (2, operands[0]))
18469 /* We reorder load and the shift. */
18470 && !reg_overlap_mentioned_p (operands[0], operands[4])"
18471 [(set (match_dup 5) (match_dup 4))
18472 (set (match_dup 0) (match_dup 1))]
18474 machine_mode op1mode = GET_MODE (operands[1]);
18475 machine_mode mode = op1mode == DImode ? DImode : SImode;
18476 int scale = 1 << INTVAL (operands[2]);
18477 rtx index = gen_lowpart (word_mode, operands[1]);
18478 rtx base = gen_lowpart (word_mode, operands[5]);
18479 rtx dest = gen_lowpart (mode, operands[3]);
18481 operands[1] = gen_rtx_PLUS (word_mode, base,
18482 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
18483 if (mode != word_mode)
18484 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18486 operands[5] = base;
18487 if (op1mode != word_mode)
18488 operands[5] = gen_lowpart (op1mode, operands[5]);
18490 operands[0] = dest;
18493 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18494 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18495 ;; caught for use by garbage collectors and the like. Using an insn that
18496 ;; maps to SIGILL makes it more likely the program will rightfully die.
18497 ;; Keeping with tradition, "6" is in honor of #UD.
18498 (define_insn "trap"
18499 [(trap_if (const_int 1) (const_int 6))]
18502 #ifdef HAVE_AS_IX86_UD2
18505 return ASM_SHORT "0x0b0f";
18508 [(set_attr "length" "2")])
18510 (define_expand "prefetch"
18511 [(prefetch (match_operand 0 "address_operand")
18512 (match_operand:SI 1 "const_int_operand")
18513 (match_operand:SI 2 "const_int_operand"))]
18514 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18516 bool write = INTVAL (operands[1]) != 0;
18517 int locality = INTVAL (operands[2]);
18519 gcc_assert (IN_RANGE (locality, 0, 3));
18521 /* Use 3dNOW prefetch in case we are asking for write prefetch not
18522 supported by SSE counterpart (non-SSE2 athlon machines) or the
18523 SSE prefetch is not available (K6 machines). Otherwise use SSE
18524 prefetch as it allows specifying of locality. */
18528 if (TARGET_PREFETCHWT1)
18529 operands[2] = GEN_INT (MAX (locality, 2));
18530 else if (TARGET_PRFCHW)
18531 operands[2] = GEN_INT (3);
18532 else if (TARGET_3DNOW && !TARGET_SSE2)
18533 operands[2] = GEN_INT (3);
18534 else if (TARGET_PREFETCH_SSE)
18535 operands[1] = const0_rtx;
18538 gcc_assert (TARGET_3DNOW);
18539 operands[2] = GEN_INT (3);
18544 if (TARGET_PREFETCH_SSE)
18548 gcc_assert (TARGET_3DNOW);
18549 operands[2] = GEN_INT (3);
18554 (define_insn "*prefetch_sse"
18555 [(prefetch (match_operand 0 "address_operand" "p")
18557 (match_operand:SI 1 "const_int_operand"))]
18558 "TARGET_PREFETCH_SSE"
18560 static const char * const patterns[4] = {
18561 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18564 int locality = INTVAL (operands[1]);
18565 gcc_assert (IN_RANGE (locality, 0, 3));
18567 return patterns[locality];
18569 [(set_attr "type" "sse")
18570 (set_attr "atom_sse_attr" "prefetch")
18571 (set (attr "length_address")
18572 (symbol_ref "memory_address_length (operands[0], false)"))
18573 (set_attr "memory" "none")])
18575 (define_insn "*prefetch_3dnow"
18576 [(prefetch (match_operand 0 "address_operand" "p")
18577 (match_operand:SI 1 "const_int_operand" "n")
18579 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18581 if (INTVAL (operands[1]) == 0)
18582 return "prefetch\t%a0";
18584 return "prefetchw\t%a0";
18586 [(set_attr "type" "mmx")
18587 (set (attr "length_address")
18588 (symbol_ref "memory_address_length (operands[0], false)"))
18589 (set_attr "memory" "none")])
18591 (define_insn "*prefetch_prefetchwt1"
18592 [(prefetch (match_operand 0 "address_operand" "p")
18595 "TARGET_PREFETCHWT1"
18596 "prefetchwt1\t%a0";
18597 [(set_attr "type" "sse")
18598 (set (attr "length_address")
18599 (symbol_ref "memory_address_length (operands[0], false)"))
18600 (set_attr "memory" "none")])
18602 (define_expand "stack_protect_set"
18603 [(match_operand 0 "memory_operand")
18604 (match_operand 1 "memory_operand")]
18605 "TARGET_SSP_TLS_GUARD"
18607 rtx (*insn)(rtx, rtx);
18609 #ifdef TARGET_THREAD_SSP_OFFSET
18610 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18611 insn = (TARGET_LP64
18612 ? gen_stack_tls_protect_set_di
18613 : gen_stack_tls_protect_set_si);
18615 insn = (TARGET_LP64
18616 ? gen_stack_protect_set_di
18617 : gen_stack_protect_set_si);
18620 emit_insn (insn (operands[0], operands[1]));
18624 (define_insn "stack_protect_set_<mode>"
18625 [(set (match_operand:PTR 0 "memory_operand" "=m")
18626 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18628 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18629 (clobber (reg:CC FLAGS_REG))]
18630 "TARGET_SSP_TLS_GUARD"
18631 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18632 [(set_attr "type" "multi")])
18634 (define_insn "stack_tls_protect_set_<mode>"
18635 [(set (match_operand:PTR 0 "memory_operand" "=m")
18636 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
18637 UNSPEC_SP_TLS_SET))
18638 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18639 (clobber (reg:CC FLAGS_REG))]
18641 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18642 [(set_attr "type" "multi")])
18644 (define_expand "stack_protect_test"
18645 [(match_operand 0 "memory_operand")
18646 (match_operand 1 "memory_operand")
18648 "TARGET_SSP_TLS_GUARD"
18650 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18652 rtx (*insn)(rtx, rtx, rtx);
18654 #ifdef TARGET_THREAD_SSP_OFFSET
18655 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18656 insn = (TARGET_LP64
18657 ? gen_stack_tls_protect_test_di
18658 : gen_stack_tls_protect_test_si);
18660 insn = (TARGET_LP64
18661 ? gen_stack_protect_test_di
18662 : gen_stack_protect_test_si);
18665 emit_insn (insn (flags, operands[0], operands[1]));
18667 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18668 flags, const0_rtx, operands[2]));
18672 (define_insn "stack_protect_test_<mode>"
18673 [(set (match_operand:CCZ 0 "flags_reg_operand")
18674 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18675 (match_operand:PTR 2 "memory_operand" "m")]
18677 (clobber (match_scratch:PTR 3 "=&r"))]
18678 "TARGET_SSP_TLS_GUARD"
18679 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18680 [(set_attr "type" "multi")])
18682 (define_insn "stack_tls_protect_test_<mode>"
18683 [(set (match_operand:CCZ 0 "flags_reg_operand")
18684 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18685 (match_operand:PTR 2 "const_int_operand" "i")]
18686 UNSPEC_SP_TLS_TEST))
18687 (clobber (match_scratch:PTR 3 "=r"))]
18689 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18690 [(set_attr "type" "multi")])
18692 (define_insn "sse4_2_crc32<mode>"
18693 [(set (match_operand:SI 0 "register_operand" "=r")
18695 [(match_operand:SI 1 "register_operand" "0")
18696 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18698 "TARGET_SSE4_2 || TARGET_CRC32"
18699 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18700 [(set_attr "type" "sselog1")
18701 (set_attr "prefix_rep" "1")
18702 (set_attr "prefix_extra" "1")
18703 (set (attr "prefix_data16")
18704 (if_then_else (match_operand:HI 2)
18706 (const_string "*")))
18707 (set (attr "prefix_rex")
18708 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18710 (const_string "*")))
18711 (set_attr "mode" "SI")])
18713 (define_insn "sse4_2_crc32di"
18714 [(set (match_operand:DI 0 "register_operand" "=r")
18716 [(match_operand:DI 1 "register_operand" "0")
18717 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18719 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18720 "crc32{q}\t{%2, %0|%0, %2}"
18721 [(set_attr "type" "sselog1")
18722 (set_attr "prefix_rep" "1")
18723 (set_attr "prefix_extra" "1")
18724 (set_attr "mode" "DI")])
18726 (define_insn "rdpmc"
18727 [(set (match_operand:DI 0 "register_operand" "=A")
18728 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18732 [(set_attr "type" "other")
18733 (set_attr "length" "2")])
18735 (define_insn "rdpmc_rex64"
18736 [(set (match_operand:DI 0 "register_operand" "=a")
18737 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18739 (set (match_operand:DI 1 "register_operand" "=d")
18740 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18743 [(set_attr "type" "other")
18744 (set_attr "length" "2")])
18746 (define_insn "rdtsc"
18747 [(set (match_operand:DI 0 "register_operand" "=A")
18748 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18751 [(set_attr "type" "other")
18752 (set_attr "length" "2")])
18754 (define_insn "rdtsc_rex64"
18755 [(set (match_operand:DI 0 "register_operand" "=a")
18756 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18757 (set (match_operand:DI 1 "register_operand" "=d")
18758 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18761 [(set_attr "type" "other")
18762 (set_attr "length" "2")])
18764 (define_insn "rdtscp"
18765 [(set (match_operand:DI 0 "register_operand" "=A")
18766 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18767 (set (match_operand:SI 1 "register_operand" "=c")
18768 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18771 [(set_attr "type" "other")
18772 (set_attr "length" "3")])
18774 (define_insn "rdtscp_rex64"
18775 [(set (match_operand:DI 0 "register_operand" "=a")
18776 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18777 (set (match_operand:DI 1 "register_operand" "=d")
18778 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18779 (set (match_operand:SI 2 "register_operand" "=c")
18780 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18783 [(set_attr "type" "other")
18784 (set_attr "length" "3")])
18786 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18788 ;; FXSR, XSAVE and XSAVEOPT instructions
18790 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18792 (define_insn "fxsave"
18793 [(set (match_operand:BLK 0 "memory_operand" "=m")
18794 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18797 [(set_attr "type" "other")
18798 (set_attr "memory" "store")
18799 (set (attr "length")
18800 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18802 (define_insn "fxsave64"
18803 [(set (match_operand:BLK 0 "memory_operand" "=m")
18804 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18805 "TARGET_64BIT && TARGET_FXSR"
18807 [(set_attr "type" "other")
18808 (set_attr "memory" "store")
18809 (set (attr "length")
18810 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18812 (define_insn "fxrstor"
18813 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18817 [(set_attr "type" "other")
18818 (set_attr "memory" "load")
18819 (set (attr "length")
18820 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18822 (define_insn "fxrstor64"
18823 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18824 UNSPECV_FXRSTOR64)]
18825 "TARGET_64BIT && TARGET_FXSR"
18827 [(set_attr "type" "other")
18828 (set_attr "memory" "load")
18829 (set (attr "length")
18830 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18832 (define_int_iterator ANY_XSAVE
18834 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18835 (UNSPECV_XSAVEC "TARGET_XSAVEC")
18836 (UNSPECV_XSAVES "TARGET_XSAVES")])
18838 (define_int_iterator ANY_XSAVE64
18840 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18841 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18842 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18844 (define_int_attr xsave
18845 [(UNSPECV_XSAVE "xsave")
18846 (UNSPECV_XSAVE64 "xsave64")
18847 (UNSPECV_XSAVEOPT "xsaveopt")
18848 (UNSPECV_XSAVEOPT64 "xsaveopt64")
18849 (UNSPECV_XSAVEC "xsavec")
18850 (UNSPECV_XSAVEC64 "xsavec64")
18851 (UNSPECV_XSAVES "xsaves")
18852 (UNSPECV_XSAVES64 "xsaves64")])
18854 (define_int_iterator ANY_XRSTOR
18856 (UNSPECV_XRSTORS "TARGET_XSAVES")])
18858 (define_int_iterator ANY_XRSTOR64
18860 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18862 (define_int_attr xrstor
18863 [(UNSPECV_XRSTOR "xrstor")
18864 (UNSPECV_XRSTOR64 "xrstor")
18865 (UNSPECV_XRSTORS "xrstors")
18866 (UNSPECV_XRSTORS64 "xrstors")])
18868 (define_insn "<xsave>"
18869 [(set (match_operand:BLK 0 "memory_operand" "=m")
18870 (unspec_volatile:BLK
18871 [(match_operand:DI 1 "register_operand" "A")]
18873 "!TARGET_64BIT && TARGET_XSAVE"
18875 [(set_attr "type" "other")
18876 (set_attr "memory" "store")
18877 (set (attr "length")
18878 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18880 (define_insn "<xsave>_rex64"
18881 [(set (match_operand:BLK 0 "memory_operand" "=m")
18882 (unspec_volatile:BLK
18883 [(match_operand:SI 1 "register_operand" "a")
18884 (match_operand:SI 2 "register_operand" "d")]
18886 "TARGET_64BIT && TARGET_XSAVE"
18888 [(set_attr "type" "other")
18889 (set_attr "memory" "store")
18890 (set (attr "length")
18891 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18893 (define_insn "<xsave>"
18894 [(set (match_operand:BLK 0 "memory_operand" "=m")
18895 (unspec_volatile:BLK
18896 [(match_operand:SI 1 "register_operand" "a")
18897 (match_operand:SI 2 "register_operand" "d")]
18899 "TARGET_64BIT && TARGET_XSAVE"
18901 [(set_attr "type" "other")
18902 (set_attr "memory" "store")
18903 (set (attr "length")
18904 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18906 (define_insn "<xrstor>"
18907 [(unspec_volatile:BLK
18908 [(match_operand:BLK 0 "memory_operand" "m")
18909 (match_operand:DI 1 "register_operand" "A")]
18911 "!TARGET_64BIT && TARGET_XSAVE"
18913 [(set_attr "type" "other")
18914 (set_attr "memory" "load")
18915 (set (attr "length")
18916 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18918 (define_insn "<xrstor>_rex64"
18919 [(unspec_volatile:BLK
18920 [(match_operand:BLK 0 "memory_operand" "m")
18921 (match_operand:SI 1 "register_operand" "a")
18922 (match_operand:SI 2 "register_operand" "d")]
18924 "TARGET_64BIT && TARGET_XSAVE"
18926 [(set_attr "type" "other")
18927 (set_attr "memory" "load")
18928 (set (attr "length")
18929 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18931 (define_insn "<xrstor>64"
18932 [(unspec_volatile:BLK
18933 [(match_operand:BLK 0 "memory_operand" "m")
18934 (match_operand:SI 1 "register_operand" "a")
18935 (match_operand:SI 2 "register_operand" "d")]
18937 "TARGET_64BIT && TARGET_XSAVE"
18939 [(set_attr "type" "other")
18940 (set_attr "memory" "load")
18941 (set (attr "length")
18942 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18944 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18946 ;; Floating-point instructions for atomic compound assignments
18948 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18950 ; Clobber all floating-point registers on environment save and restore
18951 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18952 (define_insn "fnstenv"
18953 [(set (match_operand:BLK 0 "memory_operand" "=m")
18954 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18955 (clobber (reg:HI FPCR_REG))
18956 (clobber (reg:XF ST0_REG))
18957 (clobber (reg:XF ST1_REG))
18958 (clobber (reg:XF ST2_REG))
18959 (clobber (reg:XF ST3_REG))
18960 (clobber (reg:XF ST4_REG))
18961 (clobber (reg:XF ST5_REG))
18962 (clobber (reg:XF ST6_REG))
18963 (clobber (reg:XF ST7_REG))]
18966 [(set_attr "type" "other")
18967 (set_attr "memory" "store")
18968 (set (attr "length")
18969 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18971 (define_insn "fldenv"
18972 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18974 (clobber (reg:CCFP FPSR_REG))
18975 (clobber (reg:HI FPCR_REG))
18976 (clobber (reg:XF ST0_REG))
18977 (clobber (reg:XF ST1_REG))
18978 (clobber (reg:XF ST2_REG))
18979 (clobber (reg:XF ST3_REG))
18980 (clobber (reg:XF ST4_REG))
18981 (clobber (reg:XF ST5_REG))
18982 (clobber (reg:XF ST6_REG))
18983 (clobber (reg:XF ST7_REG))]
18986 [(set_attr "type" "other")
18987 (set_attr "memory" "load")
18988 (set (attr "length")
18989 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18991 (define_insn "fnstsw"
18992 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18993 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18996 [(set_attr "type" "other,other")
18997 (set_attr "memory" "none,store")
18998 (set (attr "length")
18999 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19001 (define_insn "fnclex"
19002 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
19005 [(set_attr "type" "other")
19006 (set_attr "memory" "none")
19007 (set_attr "length" "2")])
19009 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19011 ;; LWP instructions
19013 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19015 (define_expand "lwp_llwpcb"
19016 [(unspec_volatile [(match_operand 0 "register_operand")]
19017 UNSPECV_LLWP_INTRINSIC)]
19020 (define_insn "*lwp_llwpcb<mode>1"
19021 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
19022 UNSPECV_LLWP_INTRINSIC)]
19025 [(set_attr "type" "lwp")
19026 (set_attr "mode" "<MODE>")
19027 (set_attr "length" "5")])
19029 (define_expand "lwp_slwpcb"
19030 [(set (match_operand 0 "register_operand")
19031 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19036 insn = (Pmode == DImode
19038 : gen_lwp_slwpcbsi);
19040 emit_insn (insn (operands[0]));
19044 (define_insn "lwp_slwpcb<mode>"
19045 [(set (match_operand:P 0 "register_operand" "=r")
19046 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19049 [(set_attr "type" "lwp")
19050 (set_attr "mode" "<MODE>")
19051 (set_attr "length" "5")])
19053 (define_expand "lwp_lwpval<mode>3"
19054 [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
19055 (match_operand:SI 2 "nonimmediate_operand")
19056 (match_operand:SI 3 "const_int_operand")]
19057 UNSPECV_LWPVAL_INTRINSIC)]
19059 ;; Avoid unused variable warning.
19060 "(void) operands[0];")
19062 (define_insn "*lwp_lwpval<mode>3_1"
19063 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
19064 (match_operand:SI 1 "nonimmediate_operand" "rm")
19065 (match_operand:SI 2 "const_int_operand" "i")]
19066 UNSPECV_LWPVAL_INTRINSIC)]
19068 "lwpval\t{%2, %1, %0|%0, %1, %2}"
19069 [(set_attr "type" "lwp")
19070 (set_attr "mode" "<MODE>")
19071 (set (attr "length")
19072 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19074 (define_expand "lwp_lwpins<mode>3"
19075 [(set (reg:CCC FLAGS_REG)
19076 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
19077 (match_operand:SI 2 "nonimmediate_operand")
19078 (match_operand:SI 3 "const_int_operand")]
19079 UNSPECV_LWPINS_INTRINSIC))
19080 (set (match_operand:QI 0 "nonimmediate_operand")
19081 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
19084 (define_insn "*lwp_lwpins<mode>3_1"
19085 [(set (reg:CCC FLAGS_REG)
19086 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
19087 (match_operand:SI 1 "nonimmediate_operand" "rm")
19088 (match_operand:SI 2 "const_int_operand" "i")]
19089 UNSPECV_LWPINS_INTRINSIC))]
19091 "lwpins\t{%2, %1, %0|%0, %1, %2}"
19092 [(set_attr "type" "lwp")
19093 (set_attr "mode" "<MODE>")
19094 (set (attr "length")
19095 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19097 (define_int_iterator RDFSGSBASE
19101 (define_int_iterator WRFSGSBASE
19105 (define_int_attr fsgs
19106 [(UNSPECV_RDFSBASE "fs")
19107 (UNSPECV_RDGSBASE "gs")
19108 (UNSPECV_WRFSBASE "fs")
19109 (UNSPECV_WRGSBASE "gs")])
19111 (define_insn "rd<fsgs>base<mode>"
19112 [(set (match_operand:SWI48 0 "register_operand" "=r")
19113 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
19114 "TARGET_64BIT && TARGET_FSGSBASE"
19116 [(set_attr "type" "other")
19117 (set_attr "prefix_extra" "2")])
19119 (define_insn "wr<fsgs>base<mode>"
19120 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
19122 "TARGET_64BIT && TARGET_FSGSBASE"
19124 [(set_attr "type" "other")
19125 (set_attr "prefix_extra" "2")])
19127 (define_insn "rdrand<mode>_1"
19128 [(set (match_operand:SWI248 0 "register_operand" "=r")
19129 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
19130 (set (reg:CCC FLAGS_REG)
19131 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
19134 [(set_attr "type" "other")
19135 (set_attr "prefix_extra" "1")])
19137 (define_insn "rdseed<mode>_1"
19138 [(set (match_operand:SWI248 0 "register_operand" "=r")
19139 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
19140 (set (reg:CCC FLAGS_REG)
19141 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
19144 [(set_attr "type" "other")
19145 (set_attr "prefix_extra" "1")])
19147 (define_expand "pause"
19148 [(set (match_dup 0)
19149 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19152 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
19153 MEM_VOLATILE_P (operands[0]) = 1;
19156 ;; Use "rep; nop", instead of "pause", to support older assemblers.
19157 ;; They have the same encoding.
19158 (define_insn "*pause"
19159 [(set (match_operand:BLK 0)
19160 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19163 [(set_attr "length" "2")
19164 (set_attr "memory" "unknown")])
19166 (define_expand "xbegin"
19167 [(set (match_operand:SI 0 "register_operand")
19168 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
19171 rtx_code_label *label = gen_label_rtx ();
19173 /* xbegin is emitted as jump_insn, so reload won't be able
19174 to reload its operand. Force the value into AX hard register. */
19175 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
19176 emit_move_insn (ax_reg, constm1_rtx);
19178 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
19180 emit_label (label);
19181 LABEL_NUSES (label) = 1;
19183 emit_move_insn (operands[0], ax_reg);
19188 (define_insn "xbegin_1"
19190 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
19192 (label_ref (match_operand 1))
19194 (set (match_operand:SI 0 "register_operand" "+a")
19195 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
19198 [(set_attr "type" "other")
19199 (set_attr "length" "6")])
19201 (define_insn "xend"
19202 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
19205 [(set_attr "type" "other")
19206 (set_attr "length" "3")])
19208 (define_insn "xabort"
19209 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
19213 [(set_attr "type" "other")
19214 (set_attr "length" "3")])
19216 (define_expand "xtest"
19217 [(set (match_operand:QI 0 "register_operand")
19218 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
19221 emit_insn (gen_xtest_1 ());
19223 ix86_expand_setcc (operands[0], NE,
19224 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
19228 (define_insn "xtest_1"
19229 [(set (reg:CCZ FLAGS_REG)
19230 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
19233 [(set_attr "type" "other")
19234 (set_attr "length" "3")])
19236 (define_insn "clwb"
19237 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
19241 [(set_attr "type" "sse")
19242 (set_attr "atom_sse_attr" "fence")
19243 (set_attr "memory" "unknown")])
19245 (define_insn "clflushopt"
19246 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
19247 UNSPECV_CLFLUSHOPT)]
19248 "TARGET_CLFLUSHOPT"
19250 [(set_attr "type" "sse")
19251 (set_attr "atom_sse_attr" "fence")
19252 (set_attr "memory" "unknown")])
19254 ;; MONITORX and MWAITX
19255 (define_insn "mwaitx"
19256 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
19257 (match_operand:SI 1 "register_operand" "a")
19258 (match_operand:SI 2 "register_operand" "b")]
19261 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
19262 ;; Since 32bit register operands are implicitly zero extended to 64bit,
19263 ;; we only need to set up 32bit registers.
19265 [(set_attr "length" "3")])
19267 (define_insn "monitorx_<mode>"
19268 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
19269 (match_operand:SI 1 "register_operand" "c")
19270 (match_operand:SI 2 "register_operand" "d")]
19273 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
19274 ;; RCX and RDX are used. Since 32bit register operands are implicitly
19275 ;; zero extended to 64bit, we only need to set up 32bit registers.
19277 [(set (attr "length")
19278 (symbol_ref ("(Pmode != word_mode) + 3")))])
19281 (define_insn "clzero_<mode>"
19282 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
19286 [(set_attr "length" "3")
19287 (set_attr "memory" "unknown")])
19289 ;; MPX instructions
19291 (define_expand "<mode>_mk"
19292 [(set (match_operand:BND 0 "register_operand")
19296 [(match_operand:<bnd_ptr> 1 "register_operand")
19297 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
19301 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
19303 UNSPEC_BNDMK_ADDR);
19306 (define_insn "*<mode>_mk"
19307 [(set (match_operand:BND 0 "register_operand" "=w")
19309 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19311 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
19312 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
19313 UNSPEC_BNDMK_ADDR)])]
19316 "bndmk\t{%3, %0|%0, %3}"
19317 [(set_attr "type" "mpxmk")])
19319 (define_expand "mov<mode>"
19320 [(set (match_operand:BND 0 "general_operand")
19321 (match_operand:BND 1 "general_operand"))]
19323 "ix86_expand_move (<MODE>mode, operands); DONE;")
19325 (define_insn "*mov<mode>_internal_mpx"
19326 [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
19327 (match_operand:BND 1 "general_operand" "wm,w"))]
19329 "bndmov\t{%1, %0|%0, %1}"
19330 [(set_attr "type" "mpxmov")])
19332 (define_expand "<mode>_<bndcheck>"
19335 [(match_operand:BND 0 "register_operand")
19336 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
19338 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
19341 operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
19342 MEM_VOLATILE_P (operands[2]) = 1;
19345 (define_insn "*<mode>_<bndcheck>"
19347 [(match_operand:BND 0 "register_operand" "w")
19348 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
19349 (set (match_operand:BLK 2 "bnd_mem_operator")
19350 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))]
19352 "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
19353 [(set_attr "type" "mpxchk")])
19355 (define_expand "<mode>_ldx"
19357 [(set (match_operand:BND 0 "register_operand")
19361 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
19362 (match_operand:<bnd_ptr> 2 "register_operand")]))]
19364 (use (mem:BLK (match_dup 1)))])]
19367 /* Avoid registers which cannot be used as index. */
19368 if (!index_register_operand (operands[2], Pmode))
19369 operands[2] = copy_addr_to_reg (operands[2]);
19371 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
19373 UNSPEC_BNDLDX_ADDR);
19376 (define_insn "*<mode>_ldx"
19377 [(set (match_operand:BND 0 "register_operand" "=w")
19379 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19381 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
19382 (match_operand:<bnd_ptr> 2 "register_operand" "l")]
19383 UNSPEC_BNDLDX_ADDR)])]
19385 (use (mem:BLK (match_dup 1)))]
19387 "bndldx\t{%3, %0|%0, %3}"
19388 [(set_attr "type" "mpxld")])
19390 (define_expand "<mode>_stx"
19395 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
19396 (match_operand:<bnd_ptr> 1 "register_operand")]))
19397 (match_operand:BND 2 "register_operand")]
19400 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
19403 /* Avoid registers which cannot be used as index. */
19404 if (!index_register_operand (operands[1], Pmode))
19405 operands[1] = copy_addr_to_reg (operands[1]);
19407 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
19409 UNSPEC_BNDLDX_ADDR);
19410 operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
19411 MEM_VOLATILE_P (operands[4]) = 1;
19414 (define_insn "*<mode>_stx"
19416 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19418 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
19419 (match_operand:<bnd_ptr> 1 "register_operand" "l")]
19420 UNSPEC_BNDLDX_ADDR)])
19421 (match_operand:BND 2 "register_operand" "w")]
19423 (set (match_operand:BLK 4 "bnd_mem_operator")
19424 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))]
19426 "bndstx\t{%2, %3|%3, %2}"
19427 [(set_attr "type" "mpxst")])
19429 (define_insn "move_size_reloc_<mode>"
19430 [(set (match_operand:SWI48 0 "register_operand" "=r")
19432 [(match_operand:SWI48 1 "symbol_operand")]
19436 if (x86_64_immediate_size_operand (operands[1], VOIDmode))
19437 return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
19439 return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
19441 [(set_attr "type" "imov")
19442 (set_attr "mode" "<MODE>")])
19444 ;; RDPKRU and WRPKRU
19446 (define_expand "rdpkru"
19448 [(set (match_operand:SI 0 "register_operand")
19449 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
19450 (set (match_dup 2) (const_int 0))])]
19453 operands[1] = force_reg (SImode, const0_rtx);
19454 operands[2] = gen_reg_rtx (SImode);
19457 (define_insn "*rdpkru"
19458 [(set (match_operand:SI 0 "register_operand" "=a")
19459 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
19461 (set (match_operand:SI 1 "register_operand" "=d")
19465 [(set_attr "type" "other")])
19467 (define_expand "wrpkru"
19468 [(unspec_volatile:SI
19469 [(match_operand:SI 0 "register_operand")
19470 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
19473 operands[1] = force_reg (SImode, const0_rtx);
19474 operands[2] = force_reg (SImode, const0_rtx);
19477 (define_insn "*wrpkru"
19478 [(unspec_volatile:SI
19479 [(match_operand:SI 0 "register_operand" "a")
19480 (match_operand:SI 1 "register_operand" "d")
19481 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
19484 [(set_attr "type" "other")])
19488 (include "sync.md")