1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2016 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
185 ;; For AVX512F support
199 UNSPEC_INTERRUPT_RETURN
202 (define_c_enum "unspecv" [
205 UNSPECV_PROBE_STACK_RANGE
208 UNSPECV_SPLIT_STACK_RETURN
214 UNSPECV_LLWP_INTRINSIC
215 UNSPECV_SLWP_INTRINSIC
216 UNSPECV_LWPVAL_INTRINSIC
217 UNSPECV_LWPINS_INTRINSIC
239 ;; For atomic compound assignments.
245 ;; For RDRAND support
248 ;; For RDSEED support
262 ;; For PCOMMIT support
265 ;; For CLFLUSHOPT support
268 ;; For MONITORX and MWAITX support
272 ;; For CLZERO support
275 ;; For RDPKRU and WRPKRU support
279 ;; Constants to represent rounding modes in the ROUND instruction
288 ;; Constants to represent AVX512F embeded rounding
290 [(ROUND_NEAREST_INT 0)
298 ;; Constants to represent pcomtrue/pcomfalse variants
308 ;; Constants used in the XOP pperm instruction
310 [(PPERM_SRC 0x00) /* copy source */
311 (PPERM_INVERT 0x20) /* invert source */
312 (PPERM_REVERSE 0x40) /* bit reverse source */
313 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
314 (PPERM_ZERO 0x80) /* all 0's */
315 (PPERM_ONES 0xa0) /* all 1's */
316 (PPERM_SIGN 0xc0) /* propagate sign bit */
317 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
318 (PPERM_SRC1 0x00) /* use first source byte */
319 (PPERM_SRC2 0x10) /* use second source byte */
322 ;; Registers by name.
405 (FIRST_PSEUDO_REG 81)
408 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
411 ;; In C guard expressions, put expressions which may be compile-time
412 ;; constants first. This allows for better optimization. For
413 ;; example, write "TARGET_64BIT && reload_completed", not
414 ;; "reload_completed && TARGET_64BIT".
418 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
419 atom,slm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
420 bdver4,btver2,znver1"
421 (const (symbol_ref "ix86_schedule")))
423 ;; A basic instruction type. Refinements due to arguments to be
424 ;; provided in other attributes.
427 alu,alu1,negnot,imov,imovx,lea,
428 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
429 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
430 push,pop,call,callv,leave,
432 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
433 fxch,fistp,fisttp,frndint,
434 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
435 ssemul,sseimul,ssediv,sselog,sselog1,
436 sseishft,sseishft1,ssecmp,ssecomi,
437 ssecvt,ssecvt1,sseicvt,sseins,
438 sseshuf,sseshuf1,ssemuladd,sse4arg,
440 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
441 mpxmov,mpxmk,mpxchk,mpxld,mpxst"
442 (const_string "other"))
444 ;; Main data type used by the insn
446 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
448 (const_string "unknown"))
450 ;; The CPU unit operations uses.
451 (define_attr "unit" "integer,i387,sse,mmx,unknown"
452 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
453 fxch,fistp,fisttp,frndint")
454 (const_string "i387")
455 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
456 ssemul,sseimul,ssediv,sselog,sselog1,
457 sseishft,sseishft1,ssecmp,ssecomi,
458 ssecvt,ssecvt1,sseicvt,sseins,
459 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
461 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
463 (eq_attr "type" "other")
464 (const_string "unknown")]
465 (const_string "integer")))
467 ;; The (bounding maximum) length of an instruction immediate.
468 (define_attr "length_immediate" ""
469 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
470 bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
473 (eq_attr "unit" "i387,sse,mmx")
475 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
476 rotate,rotatex,rotate1,imul,icmp,push,pop")
477 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
478 (eq_attr "type" "imov,test")
479 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
480 (eq_attr "type" "call")
481 (if_then_else (match_operand 0 "constant_call_address_operand")
484 (eq_attr "type" "callv")
485 (if_then_else (match_operand 1 "constant_call_address_operand")
488 ;; We don't know the size before shorten_branches. Expect
489 ;; the instruction to fit for better scheduling.
490 (eq_attr "type" "ibr")
493 (symbol_ref "/* Update immediate_length and other attributes! */
494 gcc_unreachable (),1")))
496 ;; The (bounding maximum) length of an instruction address.
497 (define_attr "length_address" ""
498 (cond [(eq_attr "type" "str,other,multi,fxch")
500 (and (eq_attr "type" "call")
501 (match_operand 0 "constant_call_address_operand"))
503 (and (eq_attr "type" "callv")
504 (match_operand 1 "constant_call_address_operand"))
507 (symbol_ref "ix86_attr_length_address_default (insn)")))
509 ;; Set when length prefix is used.
510 (define_attr "prefix_data16" ""
511 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
513 (eq_attr "mode" "HI")
515 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
520 ;; Set when string REP prefix is used.
521 (define_attr "prefix_rep" ""
522 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
524 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
526 (and (eq_attr "type" "ibr,call,callv")
527 (match_test "ix86_bnd_prefixed_insn_p (insn)"))
532 ;; Set when 0f opcode prefix is used.
533 (define_attr "prefix_0f" ""
535 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
536 mpxmk,mpxmov,mpxchk,mpxld,mpxst")
537 (eq_attr "unit" "sse,mmx"))
541 ;; Set when REX opcode prefix is used.
542 (define_attr "prefix_rex" ""
543 (cond [(not (match_test "TARGET_64BIT"))
545 (and (eq_attr "mode" "DI")
546 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
547 (eq_attr "unit" "!mmx")))
549 (and (eq_attr "mode" "QI")
550 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
552 (match_test "x86_extended_reg_mentioned_p (insn)")
554 (and (eq_attr "type" "imovx")
555 (match_operand:QI 1 "ext_QIreg_operand"))
560 ;; There are also additional prefixes in 3DNOW, SSSE3.
561 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
562 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
563 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
564 (define_attr "prefix_extra" ""
565 (cond [(eq_attr "type" "ssemuladd,sse4arg")
567 (eq_attr "type" "sseiadd1,ssecvt1")
572 ;; Set when BND opcode prefix may be used.
573 (define_attr "maybe_prefix_bnd" "" (const_int 0))
575 ;; Prefix used: original, VEX or maybe VEX.
576 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
577 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
579 (eq_attr "mode" "XI,V16SF,V8DF")
580 (const_string "evex")
582 (const_string "orig")))
584 ;; VEX W bit is used.
585 (define_attr "prefix_vex_w" "" (const_int 0))
587 ;; The length of VEX prefix
588 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
589 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
590 ;; still prefix_0f 1, with prefix_extra 1.
591 (define_attr "length_vex" ""
592 (if_then_else (and (eq_attr "prefix_0f" "1")
593 (eq_attr "prefix_extra" "0"))
594 (if_then_else (eq_attr "prefix_vex_w" "1")
595 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
596 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
597 (if_then_else (eq_attr "prefix_vex_w" "1")
598 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
599 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
601 ;; 4-bytes evex prefix and 1 byte opcode.
602 (define_attr "length_evex" "" (const_int 5))
604 ;; Set when modrm byte is used.
605 (define_attr "modrm" ""
606 (cond [(eq_attr "type" "str,leave")
608 (eq_attr "unit" "i387")
610 (and (eq_attr "type" "incdec")
611 (and (not (match_test "TARGET_64BIT"))
612 (ior (match_operand:SI 1 "register_operand")
613 (match_operand:HI 1 "register_operand"))))
615 (and (eq_attr "type" "push")
616 (not (match_operand 1 "memory_operand")))
618 (and (eq_attr "type" "pop")
619 (not (match_operand 0 "memory_operand")))
621 (and (eq_attr "type" "imov")
622 (and (not (eq_attr "mode" "DI"))
623 (ior (and (match_operand 0 "register_operand")
624 (match_operand 1 "immediate_operand"))
625 (ior (and (match_operand 0 "ax_reg_operand")
626 (match_operand 1 "memory_displacement_only_operand"))
627 (and (match_operand 0 "memory_displacement_only_operand")
628 (match_operand 1 "ax_reg_operand"))))))
630 (and (eq_attr "type" "call")
631 (match_operand 0 "constant_call_address_operand"))
633 (and (eq_attr "type" "callv")
634 (match_operand 1 "constant_call_address_operand"))
636 (and (eq_attr "type" "alu,alu1,icmp,test")
637 (match_operand 0 "ax_reg_operand"))
638 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
642 (define_attr "modrm_class" "none,incdec,op0,op01,op02,pushpop,unknown"
643 (cond [(eq_attr "modrm" "0")
644 (const_string "none")
645 (eq_attr "type" "alu,imul,ishift")
646 (const_string "op02")
647 (eq_attr "type" "imov,imovx,lea,alu1,icmp")
648 (const_string "op01")
649 (eq_attr "type" "incdec")
650 (const_string "incdec")
651 (eq_attr "type" "push,pop")
652 (const_string "pushpop")]
653 (const_string "unknown")))
655 ;; The (bounding maximum) length of an instruction in bytes.
656 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
657 ;; Later we may want to split them and compute proper length as for
659 (define_attr "length" ""
660 (cond [(eq_attr "type" "other,multi,fistp,frndint")
662 (eq_attr "type" "fcmp")
664 (eq_attr "unit" "i387")
666 (plus (attr "prefix_data16")
667 (attr "length_address")))
668 (ior (eq_attr "prefix" "evex")
669 (and (ior (eq_attr "prefix" "maybe_evex")
670 (eq_attr "prefix" "maybe_vex"))
671 (match_test "TARGET_AVX512F")))
672 (plus (attr "length_evex")
673 (plus (attr "length_immediate")
675 (attr "length_address"))))
676 (ior (eq_attr "prefix" "vex")
677 (and (ior (eq_attr "prefix" "maybe_vex")
678 (eq_attr "prefix" "maybe_evex"))
679 (match_test "TARGET_AVX")))
680 (plus (attr "length_vex")
681 (plus (attr "length_immediate")
683 (attr "length_address"))))]
684 (plus (plus (attr "modrm")
685 (plus (attr "prefix_0f")
686 (plus (attr "prefix_rex")
687 (plus (attr "prefix_extra")
689 (plus (attr "prefix_rep")
690 (plus (attr "prefix_data16")
691 (plus (attr "length_immediate")
692 (attr "length_address")))))))
694 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
695 ;; `store' if there is a simple memory reference therein, or `unknown'
696 ;; if the instruction is complex.
698 (define_attr "memory" "none,load,store,both,unknown"
699 (cond [(eq_attr "type" "other,multi,str,lwp")
700 (const_string "unknown")
701 (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
702 (const_string "none")
703 (eq_attr "type" "fistp,leave")
704 (const_string "both")
705 (eq_attr "type" "frndint")
706 (const_string "load")
707 (eq_attr "type" "mpxld")
708 (const_string "load")
709 (eq_attr "type" "mpxst")
710 (const_string "store")
711 (eq_attr "type" "push")
712 (if_then_else (match_operand 1 "memory_operand")
713 (const_string "both")
714 (const_string "store"))
715 (eq_attr "type" "pop")
716 (if_then_else (match_operand 0 "memory_operand")
717 (const_string "both")
718 (const_string "load"))
719 (eq_attr "type" "setcc")
720 (if_then_else (match_operand 0 "memory_operand")
721 (const_string "store")
722 (const_string "none"))
723 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
724 (if_then_else (ior (match_operand 0 "memory_operand")
725 (match_operand 1 "memory_operand"))
726 (const_string "load")
727 (const_string "none"))
728 (eq_attr "type" "ibr")
729 (if_then_else (match_operand 0 "memory_operand")
730 (const_string "load")
731 (const_string "none"))
732 (eq_attr "type" "call")
733 (if_then_else (match_operand 0 "constant_call_address_operand")
734 (const_string "none")
735 (const_string "load"))
736 (eq_attr "type" "callv")
737 (if_then_else (match_operand 1 "constant_call_address_operand")
738 (const_string "none")
739 (const_string "load"))
740 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
741 (match_operand 1 "memory_operand"))
742 (const_string "both")
743 (and (match_operand 0 "memory_operand")
744 (match_operand 1 "memory_operand"))
745 (const_string "both")
746 (match_operand 0 "memory_operand")
747 (const_string "store")
748 (match_operand 1 "memory_operand")
749 (const_string "load")
751 "!alu1,negnot,ishift1,
752 imov,imovx,icmp,test,bitmanip,
754 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
755 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
756 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
757 (match_operand 2 "memory_operand"))
758 (const_string "load")
759 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
760 (match_operand 3 "memory_operand"))
761 (const_string "load")
763 (const_string "none")))
765 ;; Indicates if an instruction has both an immediate and a displacement.
767 (define_attr "imm_disp" "false,true,unknown"
768 (cond [(eq_attr "type" "other,multi")
769 (const_string "unknown")
770 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
771 (and (match_operand 0 "memory_displacement_operand")
772 (match_operand 1 "immediate_operand")))
773 (const_string "true")
774 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
775 (and (match_operand 0 "memory_displacement_operand")
776 (match_operand 2 "immediate_operand")))
777 (const_string "true")
779 (const_string "false")))
781 ;; Indicates if an FP operation has an integer source.
783 (define_attr "fp_int_src" "false,true"
784 (const_string "false"))
786 ;; Defines rounding mode of an FP operation.
788 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
789 (const_string "any"))
791 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
792 (define_attr "use_carry" "0,1" (const_string "0"))
794 ;; Define attribute to indicate unaligned ssemov insns
795 (define_attr "movu" "0,1" (const_string "0"))
797 ;; Used to control the "enabled" attribute on a per-instruction basis.
798 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
799 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
800 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
801 fma_avx512f,avx512bw,noavx512bw,avx512dq,noavx512dq,
802 avx512vl,noavx512vl,x64_avx512dq"
803 (const_string "base"))
805 (define_attr "enabled" ""
806 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
807 (eq_attr "isa" "x64_sse4")
808 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
809 (eq_attr "isa" "x64_sse4_noavx")
810 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
811 (eq_attr "isa" "x64_avx")
812 (symbol_ref "TARGET_64BIT && TARGET_AVX")
813 (eq_attr "isa" "x64_avx512dq")
814 (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
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 ;; Mapping of logic operators
889 (define_code_iterator any_logic [and ior xor])
890 (define_code_iterator any_or [ior xor])
891 (define_code_iterator fpint_logic [and xor])
893 ;; Base name for insn mnemonic.
894 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
896 ;; Mapping of logic-shift operators
897 (define_code_iterator any_lshift [ashift lshiftrt])
899 ;; Mapping of shift-right operators
900 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
902 ;; Mapping of all shift operators
903 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
905 ;; Base name for define_insn
906 (define_code_attr shift_insn
907 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
909 ;; Base name for insn mnemonic.
910 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
911 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
913 ;; Mask variant left right mnemonics
914 (define_code_attr mshift [(ashift "shiftl") (lshiftrt "shiftr")])
916 ;; Mapping of rotate operators
917 (define_code_iterator any_rotate [rotate rotatert])
919 ;; Base name for define_insn
920 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
922 ;; Base name for insn mnemonic.
923 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
925 ;; Mapping of abs neg operators
926 (define_code_iterator absneg [abs neg])
928 ;; Base name for x87 insn mnemonic.
929 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
931 ;; Used in signed and unsigned widening multiplications.
932 (define_code_iterator any_extend [sign_extend zero_extend])
934 ;; Prefix for insn menmonic.
935 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
937 ;; Prefix for define_insn
938 (define_code_attr u [(sign_extend "") (zero_extend "u")])
939 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
940 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
942 ;; Used in signed and unsigned truncations.
943 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
944 ;; Instruction suffix for truncations.
945 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
947 ;; Used in signed and unsigned fix.
948 (define_code_iterator any_fix [fix unsigned_fix])
949 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
951 ;; Used in signed and unsigned float.
952 (define_code_iterator any_float [float unsigned_float])
953 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
955 ;; All integer modes.
956 (define_mode_iterator SWI1248x [QI HI SI DI])
958 ;; All integer modes with AVX512BW/DQ.
959 (define_mode_iterator SWI1248_AVX512BWDQ
960 [(QI "TARGET_AVX512DQ") HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
962 ;; All integer modes without QImode.
963 (define_mode_iterator SWI248x [HI SI DI])
965 ;; All integer modes without QImode and HImode.
966 (define_mode_iterator SWI48x [SI DI])
968 ;; All integer modes without SImode and DImode.
969 (define_mode_iterator SWI12 [QI HI])
971 ;; All integer modes without DImode.
972 (define_mode_iterator SWI124 [QI HI SI])
974 ;; All integer modes without QImode and DImode.
975 (define_mode_iterator SWI24 [HI SI])
977 ;; Single word integer modes.
978 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
980 ;; Single word integer modes without QImode.
981 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
983 ;; Single word integer modes without QImode and HImode.
984 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
986 ;; All math-dependant single and double word integer modes.
987 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
988 (HI "TARGET_HIMODE_MATH")
989 SI DI (TI "TARGET_64BIT")])
991 ;; Math-dependant single word integer modes.
992 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
993 (HI "TARGET_HIMODE_MATH")
994 SI (DI "TARGET_64BIT")])
996 ;; Math-dependant integer modes without DImode.
997 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
998 (HI "TARGET_HIMODE_MATH")
1001 ;; Math-dependant integer modes with DImode.
1002 (define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH")
1003 (HI "TARGET_HIMODE_MATH")
1004 SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")])
1006 ;; Math-dependant single word integer modes without QImode.
1007 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1008 SI (DI "TARGET_64BIT")])
1010 ;; Double word integer modes.
1011 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1012 (TI "TARGET_64BIT")])
1014 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1015 ;; compile time constant, it is faster to use <MODE_SIZE> than
1016 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1017 ;; command line options just use GET_MODE_SIZE macro.
1018 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1019 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1020 (V16QI "16") (V32QI "32") (V64QI "64")
1021 (V8HI "16") (V16HI "32") (V32HI "64")
1022 (V4SI "16") (V8SI "32") (V16SI "64")
1023 (V2DI "16") (V4DI "32") (V8DI "64")
1024 (V1TI "16") (V2TI "32") (V4TI "64")
1025 (V2DF "16") (V4DF "32") (V8DF "64")
1026 (V4SF "16") (V8SF "32") (V16SF "64")])
1028 ;; Double word integer modes as mode attribute.
1029 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1030 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1032 ;; LEA mode corresponding to an integer mode
1033 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1035 ;; Half mode for double word integer modes.
1036 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1037 (DI "TARGET_64BIT")])
1040 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1041 (BND64 "TARGET_LP64")])
1043 ;; Pointer mode corresponding to bound mode.
1044 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1047 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1050 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1052 (UNSPEC_BNDCN "cn")])
1054 ;; Instruction suffix for integer modes.
1055 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1057 ;; Instruction suffix for masks.
1058 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1060 ;; Pointer size prefix for integer modes (Intel asm dialect)
1061 (define_mode_attr iptrsize [(QI "BYTE")
1066 ;; Register class for integer modes.
1067 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1069 ;; Immediate operand constraint for integer modes.
1070 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1072 ;; General operand constraint for word modes.
1073 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1075 ;; Immediate operand constraint for double integer modes.
1076 (define_mode_attr di [(SI "nF") (DI "Wd")])
1078 ;; Immediate operand constraint for shifts.
1079 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1081 ;; General operand predicate for integer modes.
1082 (define_mode_attr general_operand
1083 [(QI "general_operand")
1084 (HI "general_operand")
1085 (SI "x86_64_general_operand")
1086 (DI "x86_64_general_operand")
1087 (TI "x86_64_general_operand")])
1089 ;; General operand predicate for integer modes, where for TImode
1090 ;; we need both words of the operand to be general operands.
1091 (define_mode_attr general_hilo_operand
1092 [(QI "general_operand")
1093 (HI "general_operand")
1094 (SI "x86_64_general_operand")
1095 (DI "x86_64_general_operand")
1096 (TI "x86_64_hilo_general_operand")])
1098 ;; General sign extend operand predicate for integer modes,
1099 ;; which disallows VOIDmode operands and thus it is suitable
1100 ;; for use inside sign_extend.
1101 (define_mode_attr general_sext_operand
1102 [(QI "sext_operand")
1104 (SI "x86_64_sext_operand")
1105 (DI "x86_64_sext_operand")])
1107 ;; General sign/zero extend operand predicate for integer modes.
1108 (define_mode_attr general_szext_operand
1109 [(QI "general_operand")
1110 (HI "general_operand")
1111 (SI "x86_64_szext_general_operand")
1112 (DI "x86_64_szext_general_operand")])
1114 ;; Immediate operand predicate for integer modes.
1115 (define_mode_attr immediate_operand
1116 [(QI "immediate_operand")
1117 (HI "immediate_operand")
1118 (SI "x86_64_immediate_operand")
1119 (DI "x86_64_immediate_operand")])
1121 ;; Nonmemory operand predicate for integer modes.
1122 (define_mode_attr nonmemory_operand
1123 [(QI "nonmemory_operand")
1124 (HI "nonmemory_operand")
1125 (SI "x86_64_nonmemory_operand")
1126 (DI "x86_64_nonmemory_operand")])
1128 ;; Operand predicate for shifts.
1129 (define_mode_attr shift_operand
1130 [(QI "nonimmediate_operand")
1131 (HI "nonimmediate_operand")
1132 (SI "nonimmediate_operand")
1133 (DI "shiftdi_operand")
1134 (TI "register_operand")])
1136 ;; Operand predicate for shift argument.
1137 (define_mode_attr shift_immediate_operand
1138 [(QI "const_1_to_31_operand")
1139 (HI "const_1_to_31_operand")
1140 (SI "const_1_to_31_operand")
1141 (DI "const_1_to_63_operand")])
1143 ;; Input operand predicate for arithmetic left shifts.
1144 (define_mode_attr ashl_input_operand
1145 [(QI "nonimmediate_operand")
1146 (HI "nonimmediate_operand")
1147 (SI "nonimmediate_operand")
1148 (DI "ashldi_input_operand")
1149 (TI "reg_or_pm1_operand")])
1151 ;; SSE and x87 SFmode and DFmode floating point modes
1152 (define_mode_iterator MODEF [SF DF])
1154 ;; All x87 floating point modes
1155 (define_mode_iterator X87MODEF [SF DF XF])
1157 ;; SSE instruction suffix for various modes
1158 (define_mode_attr ssemodesuffix
1159 [(SF "ss") (DF "sd")
1160 (V16SF "ps") (V8DF "pd")
1161 (V8SF "ps") (V4DF "pd")
1162 (V4SF "ps") (V2DF "pd")
1163 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1164 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1165 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1167 ;; SSE vector suffix for floating point modes
1168 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1170 ;; SSE vector mode corresponding to a scalar mode
1171 (define_mode_attr ssevecmode
1172 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1173 (define_mode_attr ssevecmodelower
1174 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1176 ;; AVX512F vector mode corresponding to a scalar mode
1177 (define_mode_attr avx512fvecmode
1178 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1180 ;; Instruction suffix for REX 64bit operators.
1181 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1183 ;; This mode iterator allows :P to be used for patterns that operate on
1184 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1185 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1187 ;; This mode iterator allows :W to be used for patterns that operate on
1188 ;; word_mode sized quantities.
1189 (define_mode_iterator W
1190 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1192 ;; This mode iterator allows :PTR to be used for patterns that operate on
1193 ;; ptr_mode sized quantities.
1194 (define_mode_iterator PTR
1195 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1197 ;; Scheduling descriptions
1199 (include "pentium.md")
1202 (include "athlon.md")
1203 (include "bdver1.md")
1204 (include "bdver3.md")
1205 (include "btver2.md")
1206 (include "znver1.md")
1207 (include "geode.md")
1210 (include "core2.md")
1211 (include "haswell.md")
1214 ;; Operand and operator predicates and constraints
1216 (include "predicates.md")
1217 (include "constraints.md")
1220 ;; Compare and branch/compare and store instructions.
1222 (define_expand "cbranch<mode>4"
1223 [(set (reg:CC FLAGS_REG)
1224 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1225 (match_operand:SDWIM 2 "<general_operand>")))
1226 (set (pc) (if_then_else
1227 (match_operator 0 "ordered_comparison_operator"
1228 [(reg:CC FLAGS_REG) (const_int 0)])
1229 (label_ref (match_operand 3))
1233 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1234 operands[1] = force_reg (<MODE>mode, operands[1]);
1235 ix86_expand_branch (GET_CODE (operands[0]),
1236 operands[1], operands[2], operands[3]);
1240 (define_expand "cstore<mode>4"
1241 [(set (reg:CC FLAGS_REG)
1242 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1243 (match_operand:SWIM 3 "<general_operand>")))
1244 (set (match_operand:QI 0 "register_operand")
1245 (match_operator 1 "ordered_comparison_operator"
1246 [(reg:CC FLAGS_REG) (const_int 0)]))]
1249 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1250 operands[2] = force_reg (<MODE>mode, operands[2]);
1251 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1252 operands[2], operands[3]);
1256 (define_expand "cmp<mode>_1"
1257 [(set (reg:CC FLAGS_REG)
1258 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1259 (match_operand:SWI48 1 "<general_operand>")))])
1261 (define_insn "*cmp<mode>_ccno_1"
1262 [(set (reg FLAGS_REG)
1263 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1264 (match_operand:SWI 1 "const0_operand")))]
1265 "ix86_match_ccmode (insn, CCNOmode)"
1267 test{<imodesuffix>}\t%0, %0
1268 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1269 [(set_attr "type" "test,icmp")
1270 (set_attr "length_immediate" "0,1")
1271 (set_attr "modrm_class" "op0,unknown")
1272 (set_attr "mode" "<MODE>")])
1274 (define_insn "*cmp<mode>_1"
1275 [(set (reg FLAGS_REG)
1276 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1277 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1278 "ix86_match_ccmode (insn, CCmode)"
1279 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1280 [(set_attr "type" "icmp")
1281 (set_attr "mode" "<MODE>")])
1283 (define_insn "*cmp<mode>_minus_1"
1284 [(set (reg FLAGS_REG)
1286 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1287 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1289 "ix86_match_ccmode (insn, CCGOCmode)"
1290 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1291 [(set_attr "type" "icmp")
1292 (set_attr "mode" "<MODE>")])
1294 (define_insn "*cmpqi_ext_1"
1295 [(set (reg FLAGS_REG)
1297 (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1300 (match_operand 1 "ext_register_operand" "Q,Q")
1302 (const_int 8)) 0)))]
1303 "ix86_match_ccmode (insn, CCmode)"
1304 "cmp{b}\t{%h1, %0|%0, %h1}"
1305 [(set_attr "isa" "*,nox64")
1306 (set_attr "type" "icmp")
1307 (set_attr "mode" "QI")])
1309 (define_insn "*cmpqi_ext_2"
1310 [(set (reg FLAGS_REG)
1314 (match_operand 0 "ext_register_operand" "Q")
1317 (match_operand:QI 1 "const0_operand")))]
1318 "ix86_match_ccmode (insn, CCNOmode)"
1320 [(set_attr "type" "test")
1321 (set_attr "length_immediate" "0")
1322 (set_attr "mode" "QI")])
1324 (define_expand "cmpqi_ext_3"
1325 [(set (reg:CC FLAGS_REG)
1329 (match_operand 0 "ext_register_operand")
1332 (match_operand:QI 1 "const_int_operand")))])
1334 (define_insn "*cmpqi_ext_3"
1335 [(set (reg FLAGS_REG)
1339 (match_operand 0 "ext_register_operand" "Q,Q")
1342 (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1343 "ix86_match_ccmode (insn, CCmode)"
1344 "cmp{b}\t{%1, %h0|%h0, %1}"
1345 [(set_attr "isa" "*,nox64")
1346 (set_attr "type" "icmp")
1347 (set_attr "modrm" "1")
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:TI 0 "push_operand")
1752 (match_operand:TI 1 "general_operand"))]
1753 "TARGET_64BIT && reload_completed
1754 && !SSE_REG_P (operands[1])"
1756 "ix86_split_long_move (operands); DONE;")
1758 (define_insn "*pushdi2_rex64"
1759 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1760 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1765 [(set_attr "type" "push,multi")
1766 (set_attr "mode" "DI")])
1768 ;; Convert impossible pushes of immediate to existing instructions.
1769 ;; First try to get scratch register and go through it. In case this
1770 ;; fails, push sign extended lower part first and then overwrite
1771 ;; upper part by 32bit move.
1773 [(match_scratch:DI 2 "r")
1774 (set (match_operand:DI 0 "push_operand")
1775 (match_operand:DI 1 "immediate_operand"))]
1776 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1777 && !x86_64_immediate_operand (operands[1], DImode)"
1778 [(set (match_dup 2) (match_dup 1))
1779 (set (match_dup 0) (match_dup 2))])
1781 ;; We need to define this as both peepholer and splitter for case
1782 ;; peephole2 pass is not run.
1783 ;; "&& 1" is needed to keep it from matching the previous pattern.
1785 [(set (match_operand:DI 0 "push_operand")
1786 (match_operand:DI 1 "immediate_operand"))]
1787 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1788 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1789 [(set (match_dup 0) (match_dup 1))
1790 (set (match_dup 2) (match_dup 3))]
1792 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1794 operands[1] = gen_lowpart (DImode, operands[2]);
1795 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1800 [(set (match_operand:DI 0 "push_operand")
1801 (match_operand:DI 1 "immediate_operand"))]
1802 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1803 ? epilogue_completed : reload_completed)
1804 && !symbolic_operand (operands[1], DImode)
1805 && !x86_64_immediate_operand (operands[1], DImode)"
1806 [(set (match_dup 0) (match_dup 1))
1807 (set (match_dup 2) (match_dup 3))]
1809 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1811 operands[1] = gen_lowpart (DImode, operands[2]);
1812 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1817 [(set (match_operand:DI 0 "push_operand")
1818 (match_operand:DI 1 "general_operand"))]
1819 "!TARGET_64BIT && reload_completed
1820 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1822 "ix86_split_long_move (operands); DONE;")
1824 (define_insn "*pushsi2"
1825 [(set (match_operand:SI 0 "push_operand" "=<")
1826 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1829 [(set_attr "type" "push")
1830 (set_attr "mode" "SI")])
1832 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1833 ;; "push a byte/word". But actually we use pushl, which has the effect
1834 ;; of rounding the amount pushed up to a word.
1836 ;; For TARGET_64BIT we always round up to 8 bytes.
1837 (define_insn "*push<mode>2_rex64"
1838 [(set (match_operand:SWI124 0 "push_operand" "=X")
1839 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1842 [(set_attr "type" "push")
1843 (set_attr "mode" "DI")])
1845 (define_insn "*push<mode>2"
1846 [(set (match_operand:SWI12 0 "push_operand" "=X")
1847 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1850 [(set_attr "type" "push")
1851 (set_attr "mode" "SI")])
1853 (define_insn "*push<mode>2_prologue"
1854 [(set (match_operand:W 0 "push_operand" "=<")
1855 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1856 (clobber (mem:BLK (scratch)))]
1858 "push{<imodesuffix>}\t%1"
1859 [(set_attr "type" "push")
1860 (set_attr "mode" "<MODE>")])
1862 (define_insn "*pop<mode>1"
1863 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1864 (match_operand:W 1 "pop_operand" ">"))]
1866 "pop{<imodesuffix>}\t%0"
1867 [(set_attr "type" "pop")
1868 (set_attr "mode" "<MODE>")])
1870 (define_insn "*pop<mode>1_epilogue"
1871 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1872 (match_operand:W 1 "pop_operand" ">"))
1873 (clobber (mem:BLK (scratch)))]
1875 "pop{<imodesuffix>}\t%0"
1876 [(set_attr "type" "pop")
1877 (set_attr "mode" "<MODE>")])
1879 (define_insn "*pushfl<mode>2"
1880 [(set (match_operand:W 0 "push_operand" "=<")
1881 (match_operand:W 1 "flags_reg_operand"))]
1883 "pushf{<imodesuffix>}"
1884 [(set_attr "type" "push")
1885 (set_attr "mode" "<MODE>")])
1887 (define_insn "*popfl<mode>1"
1888 [(set (match_operand:W 0 "flags_reg_operand")
1889 (match_operand:W 1 "pop_operand" ">"))]
1891 "popf{<imodesuffix>}"
1892 [(set_attr "type" "pop")
1893 (set_attr "mode" "<MODE>")])
1896 ;; Reload patterns to support multi-word load/store
1897 ;; with non-offsetable address.
1898 (define_expand "reload_noff_store"
1899 [(parallel [(match_operand 0 "memory_operand" "=m")
1900 (match_operand 1 "register_operand" "r")
1901 (match_operand:DI 2 "register_operand" "=&r")])]
1904 rtx mem = operands[0];
1905 rtx addr = XEXP (mem, 0);
1907 emit_move_insn (operands[2], addr);
1908 mem = replace_equiv_address_nv (mem, operands[2]);
1910 emit_insn (gen_rtx_SET (mem, operands[1]));
1914 (define_expand "reload_noff_load"
1915 [(parallel [(match_operand 0 "register_operand" "=r")
1916 (match_operand 1 "memory_operand" "m")
1917 (match_operand:DI 2 "register_operand" "=r")])]
1920 rtx mem = operands[1];
1921 rtx addr = XEXP (mem, 0);
1923 emit_move_insn (operands[2], addr);
1924 mem = replace_equiv_address_nv (mem, operands[2]);
1926 emit_insn (gen_rtx_SET (operands[0], mem));
1930 ;; Move instructions.
1932 (define_expand "movxi"
1933 [(set (match_operand:XI 0 "nonimmediate_operand")
1934 (match_operand:XI 1 "general_operand"))]
1936 "ix86_expand_vector_move (XImode, operands); DONE;")
1938 (define_expand "movoi"
1939 [(set (match_operand:OI 0 "nonimmediate_operand")
1940 (match_operand:OI 1 "general_operand"))]
1942 "ix86_expand_vector_move (OImode, operands); DONE;")
1944 (define_expand "movti"
1945 [(set (match_operand:TI 0 "nonimmediate_operand")
1946 (match_operand:TI 1 "general_operand"))]
1947 "TARGET_64BIT || TARGET_SSE"
1950 ix86_expand_move (TImode, operands);
1952 ix86_expand_vector_move (TImode, operands);
1956 ;; This expands to what emit_move_complex would generate if we didn't
1957 ;; have a movti pattern. Having this avoids problems with reload on
1958 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1959 ;; to have around all the time.
1960 (define_expand "movcdi"
1961 [(set (match_operand:CDI 0 "nonimmediate_operand")
1962 (match_operand:CDI 1 "general_operand"))]
1965 if (push_operand (operands[0], CDImode))
1966 emit_move_complex_push (CDImode, operands[0], operands[1]);
1968 emit_move_complex_parts (operands[0], operands[1]);
1972 (define_expand "mov<mode>"
1973 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1974 (match_operand:SWI1248x 1 "general_operand"))]
1976 "ix86_expand_move (<MODE>mode, operands); DONE;")
1978 (define_insn "*mov<mode>_xor"
1979 [(set (match_operand:SWI48 0 "register_operand" "=r")
1980 (match_operand:SWI48 1 "const0_operand"))
1981 (clobber (reg:CC FLAGS_REG))]
1984 [(set_attr "type" "alu1")
1985 (set_attr "modrm_class" "op0")
1986 (set_attr "mode" "SI")
1987 (set_attr "length_immediate" "0")])
1989 (define_insn "*mov<mode>_or"
1990 [(set (match_operand:SWI48 0 "register_operand" "=r")
1991 (match_operand:SWI48 1 "constm1_operand"))
1992 (clobber (reg:CC FLAGS_REG))]
1994 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1995 [(set_attr "type" "alu1")
1996 (set_attr "mode" "<MODE>")
1997 (set_attr "length_immediate" "1")])
1999 (define_insn "*movxi_internal_avx512f"
2000 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m")
2001 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2003 && (register_operand (operands[0], XImode)
2004 || register_operand (operands[1], XImode))"
2006 switch (get_attr_type (insn))
2009 return standard_sse_constant_opcode (insn, operands[1]);
2012 if (misaligned_operand (operands[0], XImode)
2013 || misaligned_operand (operands[1], XImode))
2014 return "vmovdqu32\t{%1, %0|%0, %1}";
2016 return "vmovdqa32\t{%1, %0|%0, %1}";
2022 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2023 (set_attr "prefix" "evex")
2024 (set_attr "mode" "XI")])
2026 (define_insn "*movoi_internal_avx"
2027 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m")
2028 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2030 && (register_operand (operands[0], OImode)
2031 || register_operand (operands[1], OImode))"
2033 switch (get_attr_type (insn))
2036 return standard_sse_constant_opcode (insn, operands[1]);
2039 if (misaligned_operand (operands[0], OImode)
2040 || misaligned_operand (operands[1], OImode))
2042 if (get_attr_mode (insn) == MODE_V8SF)
2043 return "vmovups\t{%1, %0|%0, %1}";
2044 else if (get_attr_mode (insn) == MODE_XI)
2045 return "vmovdqu32\t{%1, %0|%0, %1}";
2047 return "vmovdqu\t{%1, %0|%0, %1}";
2051 if (get_attr_mode (insn) == MODE_V8SF)
2052 return "vmovaps\t{%1, %0|%0, %1}";
2053 else if (get_attr_mode (insn) == MODE_XI)
2054 return "vmovdqa32\t{%1, %0|%0, %1}";
2056 return "vmovdqa\t{%1, %0|%0, %1}";
2063 [(set_attr "isa" "*,avx2,*,*")
2064 (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2065 (set_attr "prefix" "vex")
2067 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2068 (match_operand 1 "ext_sse_reg_operand"))
2070 (and (eq_attr "alternative" "1")
2071 (match_test "TARGET_AVX512VL"))
2073 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2074 (and (eq_attr "alternative" "3")
2075 (match_test "TARGET_SSE_TYPELESS_STORES")))
2076 (const_string "V8SF")
2078 (const_string "OI")))])
2080 (define_insn "*movti_internal"
2081 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m")
2082 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v"))]
2084 && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2086 && nonimmediate_or_sse_const_operand (operands[1], TImode)
2087 && (register_operand (operands[0], TImode)
2088 || register_operand (operands[1], TImode)))"
2090 switch (get_attr_type (insn))
2096 return standard_sse_constant_opcode (insn, operands[1]);
2099 /* TDmode values are passed as TImode on the stack. Moving them
2100 to stack may result in unaligned memory access. */
2101 if (misaligned_operand (operands[0], TImode)
2102 || misaligned_operand (operands[1], TImode))
2104 if (get_attr_mode (insn) == MODE_V4SF)
2105 return "%vmovups\t{%1, %0|%0, %1}";
2106 else if (get_attr_mode (insn) == MODE_XI)
2107 return "vmovdqu32\t{%1, %0|%0, %1}";
2109 return "%vmovdqu\t{%1, %0|%0, %1}";
2113 if (get_attr_mode (insn) == MODE_V4SF)
2114 return "%vmovaps\t{%1, %0|%0, %1}";
2115 else if (get_attr_mode (insn) == MODE_XI)
2116 return "vmovdqa32\t{%1, %0|%0, %1}";
2118 return "%vmovdqa\t{%1, %0|%0, %1}";
2125 [(set_attr "isa" "x64,x64,*,sse2,*,*")
2126 (set_attr "type" "multi,multi,sselog1,sselog1,ssemov,ssemov")
2127 (set (attr "prefix")
2128 (if_then_else (eq_attr "type" "sselog1,ssemov")
2129 (const_string "maybe_vex")
2130 (const_string "orig")))
2132 (cond [(eq_attr "alternative" "0,1")
2134 (ior (match_operand 0 "ext_sse_reg_operand")
2135 (match_operand 1 "ext_sse_reg_operand"))
2137 (and (eq_attr "alternative" "3")
2138 (match_test "TARGET_AVX512VL"))
2140 (ior (not (match_test "TARGET_SSE2"))
2141 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2142 (and (eq_attr "alternative" "5")
2143 (match_test "TARGET_SSE_TYPELESS_STORES"))))
2144 (const_string "V4SF")
2145 (match_test "TARGET_AVX")
2147 (match_test "optimize_function_for_size_p (cfun)")
2148 (const_string "V4SF")
2150 (const_string "TI")))])
2153 [(set (match_operand:TI 0 "nonimmediate_operand")
2154 (match_operand:TI 1 "general_operand"))]
2156 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2158 "ix86_split_long_move (operands); DONE;")
2160 (define_insn "*movdi_internal"
2161 [(set (match_operand:DI 0 "nonimmediate_operand"
2162 "=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")
2163 (match_operand:DI 1 "general_operand"
2164 "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"))]
2165 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2167 switch (get_attr_type (insn))
2170 return "kmovq\t{%1, %0|%0, %1}";
2176 return "pxor\t%0, %0";
2179 /* Handle broken assemblers that require movd instead of movq. */
2180 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2181 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2182 return "movd\t{%1, %0|%0, %1}";
2183 return "movq\t{%1, %0|%0, %1}";
2186 if (GENERAL_REG_P (operands[0]))
2187 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2189 return standard_sse_constant_opcode (insn, operands[1]);
2192 switch (get_attr_mode (insn))
2195 /* Handle broken assemblers that require movd instead of movq. */
2196 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2197 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2198 return "%vmovd\t{%1, %0|%0, %1}";
2199 return "%vmovq\t{%1, %0|%0, %1}";
2201 return "%vmovdqa\t{%1, %0|%0, %1}";
2203 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2206 gcc_assert (!TARGET_AVX);
2207 return "movlps\t{%1, %0|%0, %1}";
2209 return "%vmovaps\t{%1, %0|%0, %1}";
2216 if (SSE_REG_P (operands[0]))
2217 return "movq2dq\t{%1, %0|%0, %1}";
2219 return "movdq2q\t{%1, %0|%0, %1}";
2222 return "lea{q}\t{%E1, %0|%0, %E1}";
2225 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2226 if (get_attr_mode (insn) == MODE_SI)
2227 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2228 else if (which_alternative == 4)
2229 return "movabs{q}\t{%1, %0|%0, %1}";
2230 else if (ix86_use_lea_for_mov (insn, operands))
2231 return "lea{q}\t{%E1, %0|%0, %E1}";
2233 return "mov{q}\t{%1, %0|%0, %1}";
2240 (cond [(eq_attr "alternative" "0,1")
2241 (const_string "nox64")
2242 (eq_attr "alternative" "2,3,4,5,10,11,17,19,22,24")
2243 (const_string "x64")
2244 (eq_attr "alternative" "18")
2245 (const_string "x64_sse4")
2247 (const_string "*")))
2249 (cond [(eq_attr "alternative" "0,1")
2250 (const_string "multi")
2251 (eq_attr "alternative" "6")
2252 (const_string "mmx")
2253 (eq_attr "alternative" "7,8,9,10,11")
2254 (const_string "mmxmov")
2255 (eq_attr "alternative" "12,18")
2256 (const_string "sselog1")
2257 (eq_attr "alternative" "13,14,15,16,17,19")
2258 (const_string "ssemov")
2259 (eq_attr "alternative" "20,21")
2260 (const_string "ssecvt")
2261 (eq_attr "alternative" "22,23,24,25")
2262 (const_string "mskmov")
2263 (and (match_operand 0 "register_operand")
2264 (match_operand 1 "pic_32bit_operand"))
2265 (const_string "lea")
2267 (const_string "imov")))
2270 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2272 (const_string "*")))
2273 (set (attr "length_immediate")
2274 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2276 (eq_attr "alternative" "18")
2279 (const_string "*")))
2280 (set (attr "prefix_rex")
2281 (if_then_else (eq_attr "alternative" "10,11,17,18,19")
2283 (const_string "*")))
2284 (set (attr "prefix_extra")
2285 (if_then_else (eq_attr "alternative" "18")
2287 (const_string "*")))
2288 (set (attr "prefix")
2289 (if_then_else (eq_attr "type" "sselog1,ssemov")
2290 (const_string "maybe_vex")
2291 (const_string "orig")))
2292 (set (attr "prefix_data16")
2293 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2295 (const_string "*")))
2297 (cond [(eq_attr "alternative" "2")
2299 (eq_attr "alternative" "12,13")
2300 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2301 (match_operand 1 "ext_sse_reg_operand"))
2303 (ior (not (match_test "TARGET_SSE2"))
2304 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2305 (const_string "V4SF")
2306 (match_test "TARGET_AVX")
2308 (match_test "optimize_function_for_size_p (cfun)")
2309 (const_string "V4SF")
2311 (const_string "TI"))
2313 (and (eq_attr "alternative" "14,15,16")
2314 (not (match_test "TARGET_SSE2")))
2315 (const_string "V2SF")
2316 (eq_attr "alternative" "18")
2319 (const_string "DI")))
2320 (set (attr "enabled")
2321 (cond [(eq_attr "alternative" "15")
2323 (match_test "TARGET_STV && TARGET_SSE2")
2324 (symbol_ref "false")
2326 (eq_attr "alternative" "16")
2328 (match_test "TARGET_STV && TARGET_SSE2")
2330 (symbol_ref "false"))
2332 (const_string "*")))])
2335 [(set (match_operand:DI 0 "nonimmediate_operand")
2336 (match_operand:DI 1 "general_operand"))]
2337 "!TARGET_64BIT && reload_completed
2338 && !(MMX_REG_P (operands[0])
2339 || SSE_REG_P (operands[0])
2340 || MASK_REG_P (operands[0]))
2341 && !(MMX_REG_P (operands[1])
2342 || SSE_REG_P (operands[1])
2343 || MASK_REG_P (operands[1]))"
2345 "ix86_split_long_move (operands); DONE;")
2347 (define_insn "*movsi_internal"
2348 [(set (match_operand:SI 0 "nonimmediate_operand"
2349 "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k ,*rm")
2350 (match_operand:SI 1 "general_operand"
2351 "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r ,*krm,*k"))]
2352 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2354 switch (get_attr_type (insn))
2357 if (GENERAL_REG_P (operands[0]))
2358 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2360 return standard_sse_constant_opcode (insn, operands[1]);
2363 return "kmovd\t{%1, %0|%0, %1}";
2366 switch (get_attr_mode (insn))
2369 return "%vmovd\t{%1, %0|%0, %1}";
2371 return "%vmovdqa\t{%1, %0|%0, %1}";
2373 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2376 return "%vmovaps\t{%1, %0|%0, %1}";
2379 gcc_assert (!TARGET_AVX);
2380 return "movss\t{%1, %0|%0, %1}";
2387 return "pxor\t%0, %0";
2390 switch (get_attr_mode (insn))
2393 return "movq\t{%1, %0|%0, %1}";
2395 return "movd\t{%1, %0|%0, %1}";
2402 return "lea{l}\t{%E1, %0|%0, %E1}";
2405 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2406 if (ix86_use_lea_for_mov (insn, operands))
2407 return "lea{l}\t{%E1, %0|%0, %E1}";
2409 return "mov{l}\t{%1, %0|%0, %1}";
2416 (if_then_else (eq_attr "alternative" "11")
2417 (const_string "sse4")
2418 (const_string "*")))
2420 (cond [(eq_attr "alternative" "2")
2421 (const_string "mmx")
2422 (eq_attr "alternative" "3,4,5")
2423 (const_string "mmxmov")
2424 (eq_attr "alternative" "6,11")
2425 (const_string "sselog1")
2426 (eq_attr "alternative" "7,8,9,10,12")
2427 (const_string "ssemov")
2428 (eq_attr "alternative" "13,14")
2429 (const_string "mskmov")
2430 (and (match_operand 0 "register_operand")
2431 (match_operand 1 "pic_32bit_operand"))
2432 (const_string "lea")
2434 (const_string "imov")))
2435 (set (attr "length_immediate")
2436 (if_then_else (eq_attr "alternative" "11")
2438 (const_string "*")))
2439 (set (attr "prefix_extra")
2440 (if_then_else (eq_attr "alternative" "11")
2442 (const_string "*")))
2443 (set (attr "prefix")
2444 (if_then_else (eq_attr "type" "sselog1,ssemov")
2445 (const_string "maybe_vex")
2446 (const_string "orig")))
2447 (set (attr "prefix_data16")
2448 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2450 (const_string "*")))
2452 (cond [(eq_attr "alternative" "2,3")
2454 (eq_attr "alternative" "6,7")
2455 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2456 (match_operand 1 "ext_sse_reg_operand"))
2458 (ior (not (match_test "TARGET_SSE2"))
2459 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2460 (const_string "V4SF")
2461 (match_test "TARGET_AVX")
2463 (match_test "optimize_function_for_size_p (cfun)")
2464 (const_string "V4SF")
2466 (const_string "TI"))
2468 (and (eq_attr "alternative" "8,9")
2469 (not (match_test "TARGET_SSE2")))
2471 (eq_attr "alternative" "11")
2474 (const_string "SI")))])
2476 (define_insn "kmovw"
2477 [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2479 [(match_operand:HI 1 "nonimmediate_operand" "r,km")]
2481 "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2483 kmovw\t{%k1, %0|%0, %k1}
2484 kmovw\t{%1, %0|%0, %1}";
2485 [(set_attr "mode" "HI")
2486 (set_attr "type" "mskmov")
2487 (set_attr "prefix" "vex")])
2490 (define_insn "*movhi_internal"
2491 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k, r,m")
2492 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,r,km,k,k"))]
2493 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2495 switch (get_attr_type (insn))
2498 /* movzwl is faster than movw on p2 due to partial word stalls,
2499 though not as fast as an aligned movl. */
2500 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2503 switch (which_alternative)
2505 case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2506 case 5: /* FALLTHRU */
2507 case 7: return "kmovw\t{%1, %0|%0, %1}";
2508 case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2509 default: gcc_unreachable ();
2513 if (get_attr_mode (insn) == MODE_SI)
2514 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2516 return "mov{w}\t{%1, %0|%0, %1}";
2520 (cond [(eq_attr "alternative" "4,5,6,7")
2521 (const_string "mskmov")
2522 (match_test "optimize_function_for_size_p (cfun)")
2523 (const_string "imov")
2524 (and (eq_attr "alternative" "0")
2525 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2526 (not (match_test "TARGET_HIMODE_MATH"))))
2527 (const_string "imov")
2528 (and (eq_attr "alternative" "1,2")
2529 (match_operand:HI 1 "aligned_operand"))
2530 (const_string "imov")
2531 (and (match_test "TARGET_MOVX")
2532 (eq_attr "alternative" "0,2"))
2533 (const_string "imovx")
2535 (const_string "imov")))
2536 (set (attr "prefix")
2537 (if_then_else (eq_attr "alternative" "4,5,6,7")
2538 (const_string "vex")
2539 (const_string "orig")))
2541 (cond [(eq_attr "type" "imovx")
2543 (and (eq_attr "alternative" "1,2")
2544 (match_operand:HI 1 "aligned_operand"))
2546 (and (eq_attr "alternative" "0")
2547 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2548 (not (match_test "TARGET_HIMODE_MATH"))))
2551 (const_string "HI")))])
2553 ;; Situation is quite tricky about when to choose full sized (SImode) move
2554 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2555 ;; partial register dependency machines (such as AMD Athlon), where QImode
2556 ;; moves issue extra dependency and for partial register stalls machines
2557 ;; that don't use QImode patterns (and QImode move cause stall on the next
2560 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2561 ;; register stall machines with, where we use QImode instructions, since
2562 ;; partial register stall can be caused there. Then we use movzx.
2564 (define_insn "*movqi_internal"
2565 [(set (match_operand:QI 0 "nonimmediate_operand"
2566 "=q,q ,q ,r,r ,?r,m ,k,k,r ,m,k")
2567 (match_operand:QI 1 "general_operand"
2568 "q ,qn,qm,q,rn,qm,qn,r ,k,k,k,m"))]
2569 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2571 switch (get_attr_type (insn))
2574 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2575 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2578 switch (which_alternative)
2580 case 7: return TARGET_AVX512DQ ? "kmovb\t{%k1, %0|%0, %k1}"
2581 : "kmovw\t{%k1, %0|%0, %k1}";
2582 case 8: return TARGET_AVX512DQ ? "kmovb\t{%1, %0|%0, %1}"
2583 : "kmovw\t{%1, %0|%0, %1}";
2584 case 9: return TARGET_AVX512DQ ? "kmovb\t{%1, %k0|%k0, %1}"
2585 : "kmovw\t{%1, %k0|%k0, %1}";
2588 gcc_assert (TARGET_AVX512DQ);
2589 return "kmovb\t{%1, %0|%0, %1}";
2590 default: gcc_unreachable ();
2594 if (get_attr_mode (insn) == MODE_SI)
2595 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2597 return "mov{b}\t{%1, %0|%0, %1}";
2601 (if_then_else (eq_attr "alternative" "10,11")
2602 (const_string "avx512dq")
2603 (const_string "*")))
2605 (cond [(eq_attr "alternative" "7,8,9,10,11")
2606 (const_string "mskmov")
2607 (and (eq_attr "alternative" "5")
2608 (not (match_operand:QI 1 "aligned_operand")))
2609 (const_string "imovx")
2610 (match_test "optimize_function_for_size_p (cfun)")
2611 (const_string "imov")
2612 (and (eq_attr "alternative" "3")
2613 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2614 (not (match_test "TARGET_QIMODE_MATH"))))
2615 (const_string "imov")
2616 (eq_attr "alternative" "3,5")
2617 (const_string "imovx")
2618 (and (match_test "TARGET_MOVX")
2619 (eq_attr "alternative" "2"))
2620 (const_string "imovx")
2622 (const_string "imov")))
2623 (set (attr "prefix")
2624 (if_then_else (eq_attr "alternative" "7,8,9")
2625 (const_string "vex")
2626 (const_string "orig")))
2628 (cond [(eq_attr "alternative" "3,4,5")
2630 (eq_attr "alternative" "6")
2632 (eq_attr "type" "imovx")
2634 (and (eq_attr "type" "imov")
2635 (and (eq_attr "alternative" "0,1")
2636 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2637 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2638 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2640 ;; Avoid partial register stalls when not using QImode arithmetic
2641 (and (eq_attr "type" "imov")
2642 (and (eq_attr "alternative" "0,1")
2643 (and (match_test "TARGET_PARTIAL_REG_STALL")
2644 (not (match_test "TARGET_QIMODE_MATH")))))
2647 (const_string "QI")))])
2649 ;; Stores and loads of ax to arbitrary constant address.
2650 ;; We fake an second form of instruction to force reload to load address
2651 ;; into register when rax is not available
2652 (define_insn "*movabs<mode>_1"
2653 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2654 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2655 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2657 /* Recover the full memory rtx. */
2658 operands[0] = SET_DEST (PATTERN (insn));
2659 switch (which_alternative)
2662 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2664 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2669 [(set_attr "type" "imov")
2670 (set_attr "modrm" "0,*")
2671 (set_attr "length_address" "8,0")
2672 (set_attr "length_immediate" "0,*")
2673 (set_attr "memory" "store")
2674 (set_attr "mode" "<MODE>")])
2676 (define_insn "*movabs<mode>_2"
2677 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2678 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2679 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2681 /* Recover the full memory rtx. */
2682 operands[1] = SET_SRC (PATTERN (insn));
2683 switch (which_alternative)
2686 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2688 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2693 [(set_attr "type" "imov")
2694 (set_attr "modrm" "0,*")
2695 (set_attr "length_address" "8,0")
2696 (set_attr "length_immediate" "0")
2697 (set_attr "memory" "load")
2698 (set_attr "mode" "<MODE>")])
2700 (define_insn "*swap<mode>"
2701 [(set (match_operand:SWI48 0 "register_operand" "+r")
2702 (match_operand:SWI48 1 "register_operand" "+r"))
2706 "xchg{<imodesuffix>}\t%1, %0"
2707 [(set_attr "type" "imov")
2708 (set_attr "mode" "<MODE>")
2709 (set_attr "pent_pair" "np")
2710 (set_attr "athlon_decode" "vector")
2711 (set_attr "amdfam10_decode" "double")
2712 (set_attr "bdver1_decode" "double")])
2714 (define_insn "*swap<mode>"
2715 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2716 (match_operand:SWI12 1 "register_operand" "+<r>,r"))
2721 xchg{<imodesuffix>}\t%1, %0
2723 [(set_attr "type" "imov")
2724 (set_attr "mode" "<MODE>,SI")
2725 (set (attr "preferred_for_size")
2726 (cond [(eq_attr "alternative" "0")
2727 (symbol_ref "false")]
2728 (symbol_ref "true")))
2729 ;; Potential partial reg stall on alternative 1.
2730 (set (attr "preferred_for_speed")
2731 (cond [(eq_attr "alternative" "1")
2732 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2733 (symbol_ref "true")))
2734 (set_attr "pent_pair" "np")
2735 (set_attr "athlon_decode" "vector")
2736 (set_attr "amdfam10_decode" "double")
2737 (set_attr "bdver1_decode" "double")])
2739 (define_expand "movstrict<mode>"
2740 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2741 (match_operand:SWI12 1 "general_operand"))]
2744 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2746 if (SUBREG_P (operands[0])
2747 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2749 /* Don't generate memory->memory moves, go through a register */
2750 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2751 operands[1] = force_reg (<MODE>mode, operands[1]);
2754 (define_insn "*movstrict<mode>_1"
2755 [(set (strict_low_part
2756 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2757 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2758 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2759 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2760 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2761 [(set_attr "type" "imov")
2762 (set_attr "mode" "<MODE>")])
2764 (define_insn "*movstrict<mode>_xor"
2765 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2766 (match_operand:SWI12 1 "const0_operand"))
2767 (clobber (reg:CC FLAGS_REG))]
2769 "xor{<imodesuffix>}\t%0, %0"
2770 [(set_attr "type" "alu1")
2771 (set_attr "modrm_class" "op0")
2772 (set_attr "mode" "<MODE>")
2773 (set_attr "length_immediate" "0")])
2775 (define_expand "extv<mode>"
2776 [(set (match_operand:SWI24 0 "register_operand")
2777 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2778 (match_operand:SI 2 "const_int_operand")
2779 (match_operand:SI 3 "const_int_operand")))]
2782 /* Handle extractions from %ah et al. */
2783 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2786 if (! ext_register_operand (operands[1], VOIDmode))
2787 operands[1] = copy_to_reg (operands[1]);
2790 (define_insn "*extv<mode>"
2791 [(set (match_operand:SWI24 0 "register_operand" "=R")
2792 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2796 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2797 [(set_attr "type" "imovx")
2798 (set_attr "mode" "SI")])
2800 (define_insn "*extvqi"
2801 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2802 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2807 switch (get_attr_type (insn))
2810 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2812 return "mov{b}\t{%h1, %0|%0, %h1}";
2815 [(set_attr "isa" "*,*,nox64")
2817 (if_then_else (and (match_operand:QI 0 "register_operand")
2818 (ior (not (match_operand:QI 0 "QIreg_operand"))
2819 (match_test "TARGET_MOVX")))
2820 (const_string "imovx")
2821 (const_string "imov")))
2823 (if_then_else (eq_attr "type" "imovx")
2825 (const_string "QI")))])
2827 (define_expand "extzv<mode>"
2828 [(set (match_operand:SWI248 0 "register_operand")
2829 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2830 (match_operand:SI 2 "const_int_operand")
2831 (match_operand:SI 3 "const_int_operand")))]
2834 if (ix86_expand_pextr (operands))
2837 /* Handle extractions from %ah et al. */
2838 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2841 if (! ext_register_operand (operands[1], VOIDmode))
2842 operands[1] = copy_to_reg (operands[1]);
2845 (define_insn "*extzv<mode>"
2846 [(set (match_operand:SWI248 0 "register_operand" "=R")
2847 (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2851 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2852 [(set_attr "type" "imovx")
2853 (set_attr "mode" "SI")])
2855 (define_insn "*extzvqi"
2856 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2858 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2863 switch (get_attr_type (insn))
2866 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2868 return "mov{b}\t{%h1, %0|%0, %h1}";
2871 [(set_attr "isa" "*,*,nox64")
2873 (if_then_else (and (match_operand:QI 0 "register_operand")
2874 (ior (not (match_operand:QI 0 "QIreg_operand"))
2875 (match_test "TARGET_MOVX")))
2876 (const_string "imovx")
2877 (const_string "imov")))
2879 (if_then_else (eq_attr "type" "imovx")
2881 (const_string "QI")))])
2883 (define_expand "insv<mode>"
2884 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
2885 (match_operand:SI 1 "const_int_operand")
2886 (match_operand:SI 2 "const_int_operand"))
2887 (match_operand:SWI248 3 "register_operand"))]
2892 if (ix86_expand_pinsr (operands))
2895 /* Handle insertions to %ah et al. */
2896 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
2901 if (!ext_register_operand (dst, VOIDmode))
2902 dst = copy_to_reg (dst);
2904 emit_insn (gen_insv<mode>_1 (dst, operands[3]));
2906 /* Fix up the destination if needed. */
2907 if (dst != operands[0])
2908 emit_move_insn (operands[0], dst);
2913 (define_insn "insv<mode>_1"
2914 [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
2917 (match_operand:SWI248 1 "general_x64nomem_operand" "Qn,m"))]
2920 if (CONST_INT_P (operands[1]))
2921 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
2922 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2924 [(set_attr "isa" "*,nox64")
2925 (set_attr "type" "imov")
2926 (set_attr "mode" "QI")])
2928 (define_insn "*insvqi"
2929 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2932 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2935 "mov{b}\t{%h1, %h0|%h0, %h1}"
2936 [(set_attr "type" "imov")
2937 (set_attr "mode" "QI")])
2939 ;; Floating point push instructions.
2941 (define_insn "*pushtf"
2942 [(set (match_operand:TF 0 "push_operand" "=<,<")
2943 (match_operand:TF 1 "general_no_elim_operand" "v,*roF"))]
2944 "TARGET_64BIT || TARGET_SSE"
2946 /* This insn should be already split before reg-stack. */
2949 [(set_attr "isa" "*,x64")
2950 (set_attr "type" "multi")
2951 (set_attr "unit" "sse,*")
2952 (set_attr "mode" "TF,DI")])
2954 ;; %%% Kill this when call knows how to work this out.
2956 [(set (match_operand:TF 0 "push_operand")
2957 (match_operand:TF 1 "sse_reg_operand"))]
2958 "TARGET_SSE && reload_completed"
2959 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2960 (set (match_dup 0) (match_dup 1))]
2962 /* Preserve memory attributes. */
2963 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2966 (define_insn "*pushxf"
2967 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<")
2968 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF"))]
2971 /* This insn should be already split before reg-stack. */
2974 [(set_attr "type" "multi")
2975 (set_attr "unit" "i387,*,*,*")
2977 (cond [(eq_attr "alternative" "1,2,3")
2978 (if_then_else (match_test "TARGET_64BIT")
2980 (const_string "SI"))
2982 (const_string "XF")))
2983 (set (attr "preferred_for_size")
2984 (cond [(eq_attr "alternative" "1")
2985 (symbol_ref "false")]
2986 (symbol_ref "true")))])
2988 ;; %%% Kill this when call knows how to work this out.
2990 [(set (match_operand:XF 0 "push_operand")
2991 (match_operand:XF 1 "fp_register_operand"))]
2993 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2994 (set (match_dup 0) (match_dup 1))]
2996 operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2997 /* Preserve memory attributes. */
2998 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3001 (define_insn "*pushdf"
3002 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3003 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmF,x"))]
3006 /* This insn should be already split before reg-stack. */
3009 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3010 (set_attr "type" "multi")
3011 (set_attr "unit" "i387,*,*,*,*,sse")
3012 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3013 (set (attr "preferred_for_size")
3014 (cond [(eq_attr "alternative" "1")
3015 (symbol_ref "false")]
3016 (symbol_ref "true")))
3017 (set (attr "preferred_for_speed")
3018 (cond [(eq_attr "alternative" "1")
3019 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3020 (symbol_ref "true")))])
3022 ;; %%% Kill this when call knows how to work this out.
3024 [(set (match_operand:DF 0 "push_operand")
3025 (match_operand:DF 1 "any_fp_register_operand"))]
3027 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3028 (set (match_dup 0) (match_dup 1))]
3030 /* Preserve memory attributes. */
3031 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3034 (define_insn "*pushsf_rex64"
3035 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3036 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3039 /* Anything else should be already split before reg-stack. */
3040 gcc_assert (which_alternative == 1);
3041 return "push{q}\t%q1";
3043 [(set_attr "type" "multi,push,multi")
3044 (set_attr "unit" "i387,*,*")
3045 (set_attr "mode" "SF,DI,SF")])
3047 (define_insn "*pushsf"
3048 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3049 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3052 /* Anything else should be already split before reg-stack. */
3053 gcc_assert (which_alternative == 1);
3054 return "push{l}\t%1";
3056 [(set_attr "type" "multi,push,multi")
3057 (set_attr "unit" "i387,*,*")
3058 (set_attr "mode" "SF,SI,SF")])
3060 ;; %%% Kill this when call knows how to work this out.
3062 [(set (match_operand:SF 0 "push_operand")
3063 (match_operand:SF 1 "any_fp_register_operand"))]
3065 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3066 (set (match_dup 0) (match_dup 1))]
3068 rtx op = XEXP (operands[0], 0);
3069 if (GET_CODE (op) == PRE_DEC)
3071 gcc_assert (!TARGET_64BIT);
3076 op = XEXP (XEXP (op, 1), 1);
3077 gcc_assert (CONST_INT_P (op));
3080 /* Preserve memory attributes. */
3081 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3085 [(set (match_operand:SF 0 "push_operand")
3086 (match_operand:SF 1 "memory_operand"))]
3088 && find_constant_src (insn)"
3089 [(set (match_dup 0) (match_dup 2))]
3090 "operands[2] = find_constant_src (curr_insn);")
3093 [(set (match_operand 0 "push_operand")
3094 (match_operand 1 "general_operand"))]
3096 && (GET_MODE (operands[0]) == TFmode
3097 || GET_MODE (operands[0]) == XFmode
3098 || GET_MODE (operands[0]) == DFmode)
3099 && !ANY_FP_REG_P (operands[1])"
3101 "ix86_split_long_move (operands); DONE;")
3103 ;; Floating point move instructions.
3105 (define_expand "movtf"
3106 [(set (match_operand:TF 0 "nonimmediate_operand")
3107 (match_operand:TF 1 "nonimmediate_operand"))]
3108 "TARGET_64BIT || TARGET_SSE"
3109 "ix86_expand_move (TFmode, operands); DONE;")
3111 (define_expand "mov<mode>"
3112 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3113 (match_operand:X87MODEF 1 "general_operand"))]
3115 "ix86_expand_move (<MODE>mode, operands); DONE;")
3117 (define_insn "*movtf_internal"
3118 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3119 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3120 "(TARGET_64BIT || TARGET_SSE)
3121 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3122 && (!can_create_pseudo_p ()
3123 || !CONST_DOUBLE_P (operands[1])
3124 || ((optimize_function_for_size_p (cfun)
3125 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3126 && standard_sse_constant_p (operands[1], TFmode) == 1
3127 && !memory_operand (operands[0], TFmode))
3128 || (!TARGET_MEMORY_MISMATCH_STALL
3129 && memory_operand (operands[0], TFmode)))"
3131 switch (get_attr_type (insn))
3134 return standard_sse_constant_opcode (insn, operands[1]);
3137 /* Handle misaligned load/store since we
3138 don't have movmisaligntf pattern. */
3139 if (misaligned_operand (operands[0], TFmode)
3140 || misaligned_operand (operands[1], TFmode))
3142 if (get_attr_mode (insn) == MODE_V4SF)
3143 return "%vmovups\t{%1, %0|%0, %1}";
3144 else if (TARGET_AVX512VL
3145 && (EXT_REX_SSE_REG_P (operands[0])
3146 || EXT_REX_SSE_REG_P (operands[1])))
3147 return "vmovdqu64\t{%1, %0|%0, %1}";
3149 return "%vmovdqu\t{%1, %0|%0, %1}";
3153 if (get_attr_mode (insn) == MODE_V4SF)
3154 return "%vmovaps\t{%1, %0|%0, %1}";
3155 else if (TARGET_AVX512VL
3156 && (EXT_REX_SSE_REG_P (operands[0])
3157 || EXT_REX_SSE_REG_P (operands[1])))
3158 return "vmovdqa64\t{%1, %0|%0, %1}";
3160 return "%vmovdqa\t{%1, %0|%0, %1}";
3170 [(set_attr "isa" "*,*,*,x64,x64")
3171 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3172 (set (attr "prefix")
3173 (if_then_else (eq_attr "type" "sselog1,ssemov")
3174 (const_string "maybe_vex")
3175 (const_string "orig")))
3177 (cond [(eq_attr "alternative" "3,4")
3179 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3180 (const_string "V4SF")
3181 (and (eq_attr "alternative" "2")
3182 (match_test "TARGET_SSE_TYPELESS_STORES"))
3183 (const_string "V4SF")
3184 (match_test "TARGET_AVX")
3186 (ior (not (match_test "TARGET_SSE2"))
3187 (match_test "optimize_function_for_size_p (cfun)"))
3188 (const_string "V4SF")
3190 (const_string "TI")))])
3193 [(set (match_operand:TF 0 "nonimmediate_operand")
3194 (match_operand:TF 1 "general_operand"))]
3196 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3198 "ix86_split_long_move (operands); DONE;")
3200 ;; Possible store forwarding (partial memory) stall
3201 ;; in alternatives 4, 6, 7 and 8.
3202 (define_insn "*movxf_internal"
3203 [(set (match_operand:XF 0 "nonimmediate_operand"
3204 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o")
3205 (match_operand:XF 1 "general_operand"
3206 "fm,f,G,roF,r , *roF,*r,F ,C,roF,rF"))]
3207 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3208 && (!can_create_pseudo_p ()
3209 || !CONST_DOUBLE_P (operands[1])
3210 || ((optimize_function_for_size_p (cfun)
3211 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3212 && standard_80387_constant_p (operands[1]) > 0
3213 && !memory_operand (operands[0], XFmode))
3214 || (!TARGET_MEMORY_MISMATCH_STALL
3215 && memory_operand (operands[0], XFmode))
3216 || !TARGET_HARD_XF_REGS)"
3218 switch (get_attr_type (insn))
3221 if (which_alternative == 2)
3222 return standard_80387_constant_opcode (operands[1]);
3223 return output_387_reg_move (insn, operands);
3233 (cond [(eq_attr "alternative" "7")
3234 (const_string "nox64")
3235 (eq_attr "alternative" "8")
3236 (const_string "x64")
3238 (const_string "*")))
3240 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10")
3241 (const_string "multi")
3243 (const_string "fmov")))
3245 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10")
3246 (if_then_else (match_test "TARGET_64BIT")
3248 (const_string "SI"))
3250 (const_string "XF")))
3251 (set (attr "preferred_for_size")
3252 (cond [(eq_attr "alternative" "3,4")
3253 (symbol_ref "false")]
3254 (symbol_ref "true")))
3255 (set (attr "enabled")
3256 (cond [(eq_attr "alternative" "9,10")
3258 (match_test "TARGET_HARD_XF_REGS")
3259 (symbol_ref "false")
3261 (not (match_test "TARGET_HARD_XF_REGS"))
3262 (symbol_ref "false")
3264 (const_string "*")))])
3267 [(set (match_operand:XF 0 "nonimmediate_operand")
3268 (match_operand:XF 1 "general_operand"))]
3270 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3272 "ix86_split_long_move (operands); DONE;")
3274 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3275 (define_insn "*movdf_internal"
3276 [(set (match_operand:DF 0 "nonimmediate_operand"
3277 "=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")
3278 (match_operand:DF 1 "general_operand"
3279 "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"))]
3280 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3281 && (!can_create_pseudo_p ()
3282 || !CONST_DOUBLE_P (operands[1])
3283 || ((optimize_function_for_size_p (cfun)
3284 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3285 && ((IS_STACK_MODE (DFmode)
3286 && standard_80387_constant_p (operands[1]) > 0)
3287 || (TARGET_SSE2 && TARGET_SSE_MATH
3288 && standard_sse_constant_p (operands[1], DFmode) == 1))
3289 && !memory_operand (operands[0], DFmode))
3290 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3291 && memory_operand (operands[0], DFmode))
3292 || !TARGET_HARD_DF_REGS)"
3294 switch (get_attr_type (insn))
3297 if (which_alternative == 2)
3298 return standard_80387_constant_opcode (operands[1]);
3299 return output_387_reg_move (insn, operands);
3305 if (get_attr_mode (insn) == MODE_SI)
3306 return "mov{l}\t{%1, %k0|%k0, %1}";
3307 else if (which_alternative == 11)
3308 return "movabs{q}\t{%1, %0|%0, %1}";
3310 return "mov{q}\t{%1, %0|%0, %1}";
3313 return standard_sse_constant_opcode (insn, operands[1]);
3316 switch (get_attr_mode (insn))
3319 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3320 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3321 return "%vmovsd\t{%1, %0|%0, %1}";
3324 return "%vmovaps\t{%1, %0|%0, %1}";
3326 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3328 return "%vmovapd\t{%1, %0|%0, %1}";
3331 gcc_assert (!TARGET_AVX);
3332 return "movlps\t{%1, %0|%0, %1}";
3334 gcc_assert (!TARGET_AVX);
3335 return "movlpd\t{%1, %0|%0, %1}";
3338 /* Handle broken assemblers that require movd instead of movq. */
3339 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3340 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3341 return "%vmovd\t{%1, %0|%0, %1}";
3342 return "%vmovq\t{%1, %0|%0, %1}";
3353 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3354 (const_string "nox64")
3355 (eq_attr "alternative" "8,9,10,11,20,21,24,25")
3356 (const_string "x64")
3357 (eq_attr "alternative" "12,13,14,15")
3358 (const_string "sse2")
3360 (const_string "*")))
3362 (cond [(eq_attr "alternative" "0,1,2")
3363 (const_string "fmov")
3364 (eq_attr "alternative" "3,4,5,6,7,22,23")
3365 (const_string "multi")
3366 (eq_attr "alternative" "8,9,10,11,24,25")
3367 (const_string "imov")
3368 (eq_attr "alternative" "12,16")
3369 (const_string "sselog1")
3371 (const_string "ssemov")))
3373 (if_then_else (eq_attr "alternative" "11")
3375 (const_string "*")))
3376 (set (attr "length_immediate")
3377 (if_then_else (eq_attr "alternative" "11")
3379 (const_string "*")))
3380 (set (attr "prefix")
3381 (if_then_else (eq_attr "type" "sselog1,ssemov")
3382 (const_string "maybe_vex")
3383 (const_string "orig")))
3384 (set (attr "prefix_data16")
3386 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3387 (eq_attr "mode" "V1DF"))
3389 (const_string "*")))
3391 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3393 (eq_attr "alternative" "8,9,11,20,21,24,25")
3396 /* xorps is one byte shorter for non-AVX targets. */
3397 (eq_attr "alternative" "12,16")
3398 (cond [(not (match_test "TARGET_SSE2"))
3399 (const_string "V4SF")
3400 (match_test "TARGET_AVX512F")
3402 (match_test "TARGET_AVX")
3403 (const_string "V2DF")
3404 (match_test "optimize_function_for_size_p (cfun)")
3405 (const_string "V4SF")
3406 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3409 (const_string "V2DF"))
3411 /* For architectures resolving dependencies on
3412 whole SSE registers use movapd to break dependency
3413 chains, otherwise use short move to avoid extra work. */
3415 /* movaps is one byte shorter for non-AVX targets. */
3416 (eq_attr "alternative" "13,17")
3417 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3418 (match_operand 1 "ext_sse_reg_operand"))
3419 (const_string "V8DF")
3420 (ior (not (match_test "TARGET_SSE2"))
3421 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3422 (const_string "V4SF")
3423 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3424 (const_string "V2DF")
3425 (match_test "TARGET_AVX")
3427 (match_test "optimize_function_for_size_p (cfun)")
3428 (const_string "V4SF")
3430 (const_string "DF"))
3432 /* For architectures resolving dependencies on register
3433 parts we may avoid extra work to zero out upper part
3435 (eq_attr "alternative" "14,18")
3436 (cond [(not (match_test "TARGET_SSE2"))
3437 (const_string "V2SF")
3438 (match_test "TARGET_AVX")
3440 (match_test "TARGET_SSE_SPLIT_REGS")
3441 (const_string "V1DF")
3443 (const_string "DF"))
3445 (and (eq_attr "alternative" "15,19")
3446 (not (match_test "TARGET_SSE2")))
3447 (const_string "V2SF")
3449 (const_string "DF")))
3450 (set (attr "preferred_for_size")
3451 (cond [(eq_attr "alternative" "3,4")
3452 (symbol_ref "false")]
3453 (symbol_ref "true")))
3454 (set (attr "preferred_for_speed")
3455 (cond [(eq_attr "alternative" "3,4")
3456 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3457 (symbol_ref "true")))
3458 (set (attr "enabled")
3459 (cond [(eq_attr "alternative" "22,23,24,25")
3461 (match_test "TARGET_HARD_DF_REGS")
3462 (symbol_ref "false")
3464 (not (match_test "TARGET_HARD_DF_REGS"))
3465 (symbol_ref "false")
3467 (const_string "*")))])
3470 [(set (match_operand:DF 0 "nonimmediate_operand")
3471 (match_operand:DF 1 "general_operand"))]
3472 "!TARGET_64BIT && reload_completed
3473 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3475 "ix86_split_long_move (operands); DONE;")
3477 (define_insn "*movsf_internal"
3478 [(set (match_operand:SF 0 "nonimmediate_operand"
3479 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym,r ,m")
3480 (match_operand:SF 1 "general_operand"
3481 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r ,rmF,rF"))]
3482 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3483 && (!can_create_pseudo_p ()
3484 || !CONST_DOUBLE_P (operands[1])
3485 || ((optimize_function_for_size_p (cfun)
3486 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3487 && ((IS_STACK_MODE (SFmode)
3488 && standard_80387_constant_p (operands[1]) > 0)
3489 || (TARGET_SSE && TARGET_SSE_MATH
3490 && standard_sse_constant_p (operands[1], SFmode) == 1)))
3491 || memory_operand (operands[0], SFmode)
3492 || !TARGET_HARD_SF_REGS)"
3494 switch (get_attr_type (insn))
3497 if (which_alternative == 2)
3498 return standard_80387_constant_opcode (operands[1]);
3499 return output_387_reg_move (insn, operands);
3502 return "mov{l}\t{%1, %0|%0, %1}";
3505 return standard_sse_constant_opcode (insn, operands[1]);
3508 switch (get_attr_mode (insn))
3511 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3512 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3513 return "%vmovss\t{%1, %0|%0, %1}";
3516 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3518 return "%vmovaps\t{%1, %0|%0, %1}";
3521 return "%vmovd\t{%1, %0|%0, %1}";
3528 switch (get_attr_mode (insn))
3531 return "movq\t{%1, %0|%0, %1}";
3533 return "movd\t{%1, %0|%0, %1}";
3544 (cond [(eq_attr "alternative" "0,1,2")
3545 (const_string "fmov")
3546 (eq_attr "alternative" "3,4,16,17")
3547 (const_string "imov")
3548 (eq_attr "alternative" "5")
3549 (const_string "sselog1")
3550 (eq_attr "alternative" "11,12,13,14,15")
3551 (const_string "mmxmov")
3553 (const_string "ssemov")))
3554 (set (attr "prefix")
3555 (if_then_else (eq_attr "type" "sselog1,ssemov")
3556 (const_string "maybe_vex")
3557 (const_string "orig")))
3558 (set (attr "prefix_data16")
3559 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3561 (const_string "*")))
3563 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3565 (eq_attr "alternative" "11")
3567 (eq_attr "alternative" "5")
3568 (cond [(not (match_test "TARGET_SSE2"))
3569 (const_string "V4SF")
3570 (match_test "TARGET_AVX512F")
3571 (const_string "V16SF")
3572 (match_test "TARGET_AVX")
3573 (const_string "V4SF")
3574 (match_test "optimize_function_for_size_p (cfun)")
3575 (const_string "V4SF")
3576 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3579 (const_string "V4SF"))
3581 /* For architectures resolving dependencies on
3582 whole SSE registers use APS move to break dependency
3583 chains, otherwise use short move to avoid extra work.
3585 Do the same for architectures resolving dependencies on
3586 the parts. While in DF mode it is better to always handle
3587 just register parts, the SF mode is different due to lack
3588 of instructions to load just part of the register. It is
3589 better to maintain the whole registers in single format
3590 to avoid problems on using packed logical operations. */
3591 (eq_attr "alternative" "6")
3592 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3593 (match_operand 1 "ext_sse_reg_operand"))
3594 (const_string "V16SF")
3595 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3596 (match_test "TARGET_SSE_SPLIT_REGS"))
3597 (const_string "V4SF")
3599 (const_string "SF"))
3601 (const_string "SF")))
3602 (set (attr "enabled")
3603 (cond [(eq_attr "alternative" "16,17")
3605 (match_test "TARGET_HARD_SF_REGS")
3606 (symbol_ref "false")
3608 (not (match_test "TARGET_HARD_SF_REGS"))
3609 (symbol_ref "false")
3611 (const_string "*")))])
3614 [(set (match_operand 0 "any_fp_register_operand")
3615 (match_operand 1 "memory_operand"))]
3617 && (GET_MODE (operands[0]) == TFmode
3618 || GET_MODE (operands[0]) == XFmode
3619 || GET_MODE (operands[0]) == DFmode
3620 || GET_MODE (operands[0]) == SFmode)
3621 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3622 [(set (match_dup 0) (match_dup 2))]
3623 "operands[2] = find_constant_src (curr_insn);")
3626 [(set (match_operand 0 "any_fp_register_operand")
3627 (float_extend (match_operand 1 "memory_operand")))]
3629 && (GET_MODE (operands[0]) == TFmode
3630 || GET_MODE (operands[0]) == XFmode
3631 || GET_MODE (operands[0]) == DFmode)
3632 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3633 [(set (match_dup 0) (match_dup 2))]
3634 "operands[2] = find_constant_src (curr_insn);")
3636 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3638 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3639 (match_operand:X87MODEF 1 "immediate_operand"))]
3641 && (standard_80387_constant_p (operands[1]) == 8
3642 || standard_80387_constant_p (operands[1]) == 9)"
3643 [(set (match_dup 0)(match_dup 1))
3645 (neg:X87MODEF (match_dup 0)))]
3647 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3648 operands[1] = CONST0_RTX (<MODE>mode);
3650 operands[1] = CONST1_RTX (<MODE>mode);
3653 (define_insn "swapxf"
3654 [(set (match_operand:XF 0 "register_operand" "+f")
3655 (match_operand:XF 1 "register_operand" "+f"))
3660 if (STACK_TOP_P (operands[0]))
3665 [(set_attr "type" "fxch")
3666 (set_attr "mode" "XF")])
3668 (define_insn "*swap<mode>"
3669 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3670 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3673 "TARGET_80387 || reload_completed"
3675 if (STACK_TOP_P (operands[0]))
3680 [(set_attr "type" "fxch")
3681 (set_attr "mode" "<MODE>")])
3683 ;; Zero extension instructions
3685 (define_expand "zero_extendsidi2"
3686 [(set (match_operand:DI 0 "nonimmediate_operand")
3687 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3689 (define_insn "*zero_extendsidi2"
3690 [(set (match_operand:DI 0 "nonimmediate_operand"
3691 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3693 (match_operand:SI 1 "x86_64_zext_operand"
3694 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))]
3697 switch (get_attr_type (insn))
3700 if (ix86_use_lea_for_mov (insn, operands))
3701 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3703 return "mov{l}\t{%1, %k0|%k0, %1}";
3709 return "movd\t{%1, %0|%0, %1}";
3712 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3715 if (GENERAL_REG_P (operands[0]))
3716 return "%vmovd\t{%1, %k0|%k0, %1}";
3718 return "%vmovd\t{%1, %0|%0, %1}";
3725 (cond [(eq_attr "alternative" "0,1,2")
3726 (const_string "nox64")
3727 (eq_attr "alternative" "3,7")
3728 (const_string "x64")
3729 (eq_attr "alternative" "8")
3730 (const_string "x64_sse4")
3731 (eq_attr "alternative" "10")
3732 (const_string "sse2")
3734 (const_string "*")))
3736 (cond [(eq_attr "alternative" "0,1,2,4")
3737 (const_string "multi")
3738 (eq_attr "alternative" "5,6")
3739 (const_string "mmxmov")
3740 (eq_attr "alternative" "7,9,10")
3741 (const_string "ssemov")
3742 (eq_attr "alternative" "8")
3743 (const_string "sselog1")
3745 (const_string "imovx")))
3746 (set (attr "prefix_extra")
3747 (if_then_else (eq_attr "alternative" "8")
3749 (const_string "*")))
3750 (set (attr "length_immediate")
3751 (if_then_else (eq_attr "alternative" "8")
3753 (const_string "*")))
3754 (set (attr "prefix")
3755 (if_then_else (eq_attr "type" "ssemov,sselog1")
3756 (const_string "maybe_vex")
3757 (const_string "orig")))
3758 (set (attr "prefix_0f")
3759 (if_then_else (eq_attr "type" "imovx")
3761 (const_string "*")))
3763 (cond [(eq_attr "alternative" "5,6")
3765 (eq_attr "alternative" "7,8,9")
3768 (const_string "SI")))])
3771 [(set (match_operand:DI 0 "memory_operand")
3772 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3774 [(set (match_dup 4) (const_int 0))]
3775 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3778 [(set (match_operand:DI 0 "general_reg_operand")
3779 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
3780 "!TARGET_64BIT && reload_completed
3781 && REGNO (operands[0]) == REGNO (operands[1])"
3782 [(set (match_dup 4) (const_int 0))]
3783 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3786 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
3787 (zero_extend:DI (match_operand:SI 1 "nonimmediate_gr_operand")))]
3788 "!TARGET_64BIT && reload_completed
3789 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3790 [(set (match_dup 3) (match_dup 1))
3791 (set (match_dup 4) (const_int 0))]
3792 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3794 (define_insn "zero_extend<mode>di2"
3795 [(set (match_operand:DI 0 "register_operand" "=r")
3797 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3799 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3800 [(set_attr "type" "imovx")
3801 (set_attr "mode" "SI")])
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")
3846 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3847 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3848 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3849 [(set_attr "type" "imovx")
3850 (set_attr "mode" "SI")])
3852 (define_expand "zero_extendqihi2"
3853 [(set (match_operand:HI 0 "register_operand")
3854 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3857 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3859 operands[1] = force_reg (QImode, operands[1]);
3860 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3865 (define_insn_and_split "zero_extendqihi2_and"
3866 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3867 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3868 (clobber (reg:CC FLAGS_REG))]
3869 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3871 "&& reload_completed"
3872 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3873 (clobber (reg:CC FLAGS_REG))])]
3875 if (!REG_P (operands[1])
3876 || REGNO (operands[0]) != REGNO (operands[1]))
3878 ix86_expand_clear (operands[0]);
3880 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3881 emit_insn (gen_movstrictqi
3882 (gen_lowpart (QImode, operands[0]), operands[1]));
3886 operands[0] = gen_lowpart (SImode, operands[0]);
3888 [(set_attr "type" "alu1")
3889 (set_attr "mode" "SI")])
3891 ; zero extend to SImode to avoid partial register stalls
3892 (define_insn "*zero_extendqihi2"
3893 [(set (match_operand:HI 0 "register_operand" "=r")
3894 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3895 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3896 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3897 [(set_attr "type" "imovx")
3898 (set_attr "mode" "SI")])
3900 (define_insn_and_split "*zext<mode>_doubleword_and"
3901 [(set (match_operand:DI 0 "register_operand" "=&<r>")
3902 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3903 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
3904 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3906 "&& reload_completed && GENERAL_REG_P (operands[0])"
3907 [(set (match_dup 2) (const_int 0))]
3909 split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);
3911 emit_move_insn (operands[0], const0_rtx);
3913 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3914 emit_insn (gen_movstrict<mode>
3915 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3918 (define_insn_and_split "*zext<mode>_doubleword"
3919 [(set (match_operand:DI 0 "register_operand" "=r")
3920 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3921 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
3922 && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3924 "&& reload_completed && GENERAL_REG_P (operands[0])"
3925 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
3926 (set (match_dup 2) (const_int 0))]
3927 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
3929 (define_insn_and_split "*zextsi_doubleword"
3930 [(set (match_operand:DI 0 "register_operand" "=r")
3931 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3932 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
3934 "&& reload_completed && GENERAL_REG_P (operands[0])"
3935 [(set (match_dup 0) (match_dup 1))
3936 (set (match_dup 2) (const_int 0))]
3937 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
3939 ;; Sign extension instructions
3941 (define_expand "extendsidi2"
3942 [(set (match_operand:DI 0 "register_operand")
3943 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3948 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3953 (define_insn "*extendsidi2_rex64"
3954 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3955 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3959 movs{lq|x}\t{%1, %0|%0, %1}"
3960 [(set_attr "type" "imovx")
3961 (set_attr "mode" "DI")
3962 (set_attr "prefix_0f" "0")
3963 (set_attr "modrm" "0,1")])
3965 (define_insn "extendsidi2_1"
3966 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3967 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3968 (clobber (reg:CC FLAGS_REG))
3969 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3973 ;; Split the memory case. If the source register doesn't die, it will stay
3974 ;; this way, if it does die, following peephole2s take care of it.
3976 [(set (match_operand:DI 0 "memory_operand")
3977 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3978 (clobber (reg:CC FLAGS_REG))
3979 (clobber (match_operand:SI 2 "register_operand"))]
3983 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3985 emit_move_insn (operands[3], operands[1]);
3987 /* Generate a cltd if possible and doing so it profitable. */
3988 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3989 && REGNO (operands[1]) == AX_REG
3990 && REGNO (operands[2]) == DX_REG)
3992 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3996 emit_move_insn (operands[2], operands[1]);
3997 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3999 emit_move_insn (operands[4], operands[2]);
4003 ;; Peepholes for the case where the source register does die, after
4004 ;; being split with the above splitter.
4006 [(set (match_operand:SI 0 "memory_operand")
4007 (match_operand:SI 1 "general_reg_operand"))
4008 (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4009 (parallel [(set (match_dup 2)
4010 (ashiftrt:SI (match_dup 2) (const_int 31)))
4011 (clobber (reg:CC FLAGS_REG))])
4012 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4013 "REGNO (operands[1]) != REGNO (operands[2])
4014 && peep2_reg_dead_p (2, operands[1])
4015 && peep2_reg_dead_p (4, operands[2])
4016 && !reg_mentioned_p (operands[2], operands[3])"
4017 [(set (match_dup 0) (match_dup 1))
4018 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4019 (clobber (reg:CC FLAGS_REG))])
4020 (set (match_dup 3) (match_dup 1))])
4023 [(set (match_operand:SI 0 "memory_operand")
4024 (match_operand:SI 1 "general_reg_operand"))
4025 (parallel [(set (match_operand:SI 2 "general_reg_operand")
4026 (ashiftrt:SI (match_dup 1) (const_int 31)))
4027 (clobber (reg:CC FLAGS_REG))])
4028 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4029 "/* cltd is shorter than sarl $31, %eax */
4030 !optimize_function_for_size_p (cfun)
4031 && REGNO (operands[1]) == AX_REG
4032 && REGNO (operands[2]) == DX_REG
4033 && peep2_reg_dead_p (2, operands[1])
4034 && peep2_reg_dead_p (3, operands[2])
4035 && !reg_mentioned_p (operands[2], operands[3])"
4036 [(set (match_dup 0) (match_dup 1))
4037 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4038 (clobber (reg:CC FLAGS_REG))])
4039 (set (match_dup 3) (match_dup 1))])
4041 ;; Extend to register case. Optimize case where source and destination
4042 ;; registers match and cases where we can use cltd.
4044 [(set (match_operand:DI 0 "register_operand")
4045 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4046 (clobber (reg:CC FLAGS_REG))
4047 (clobber (match_scratch:SI 2))]
4051 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4053 if (REGNO (operands[3]) != REGNO (operands[1]))
4054 emit_move_insn (operands[3], operands[1]);
4056 /* Generate a cltd if possible and doing so it profitable. */
4057 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4058 && REGNO (operands[3]) == AX_REG
4059 && REGNO (operands[4]) == DX_REG)
4061 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4065 if (REGNO (operands[4]) != REGNO (operands[1]))
4066 emit_move_insn (operands[4], operands[1]);
4068 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4072 (define_insn "extend<mode>di2"
4073 [(set (match_operand:DI 0 "register_operand" "=r")
4075 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4077 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4078 [(set_attr "type" "imovx")
4079 (set_attr "mode" "DI")])
4081 (define_insn "extendhisi2"
4082 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4083 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4086 switch (get_attr_prefix_0f (insn))
4089 return "{cwtl|cwde}";
4091 return "movs{wl|x}\t{%1, %0|%0, %1}";
4094 [(set_attr "type" "imovx")
4095 (set_attr "mode" "SI")
4096 (set (attr "prefix_0f")
4097 ;; movsx is short decodable while cwtl is vector decoded.
4098 (if_then_else (and (eq_attr "cpu" "!k6")
4099 (eq_attr "alternative" "0"))
4101 (const_string "1")))
4102 (set (attr "znver1_decode")
4103 (if_then_else (eq_attr "prefix_0f" "0")
4104 (const_string "double")
4105 (const_string "direct")))
4107 (if_then_else (eq_attr "prefix_0f" "0")
4109 (const_string "1")))])
4111 (define_insn "*extendhisi2_zext"
4112 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4115 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4118 switch (get_attr_prefix_0f (insn))
4121 return "{cwtl|cwde}";
4123 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4126 [(set_attr "type" "imovx")
4127 (set_attr "mode" "SI")
4128 (set (attr "prefix_0f")
4129 ;; movsx is short decodable while cwtl is vector decoded.
4130 (if_then_else (and (eq_attr "cpu" "!k6")
4131 (eq_attr "alternative" "0"))
4133 (const_string "1")))
4135 (if_then_else (eq_attr "prefix_0f" "0")
4137 (const_string "1")))])
4139 (define_insn "extendqisi2"
4140 [(set (match_operand:SI 0 "register_operand" "=r")
4141 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4143 "movs{bl|x}\t{%1, %0|%0, %1}"
4144 [(set_attr "type" "imovx")
4145 (set_attr "mode" "SI")])
4147 (define_insn "*extendqisi2_zext"
4148 [(set (match_operand:DI 0 "register_operand" "=r")
4150 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4152 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4153 [(set_attr "type" "imovx")
4154 (set_attr "mode" "SI")])
4156 (define_insn "extendqihi2"
4157 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4158 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4161 switch (get_attr_prefix_0f (insn))
4164 return "{cbtw|cbw}";
4166 return "movs{bw|x}\t{%1, %0|%0, %1}";
4169 [(set_attr "type" "imovx")
4170 (set_attr "mode" "HI")
4171 (set (attr "prefix_0f")
4172 ;; movsx is short decodable while cwtl is vector decoded.
4173 (if_then_else (and (eq_attr "cpu" "!k6")
4174 (eq_attr "alternative" "0"))
4176 (const_string "1")))
4178 (if_then_else (eq_attr "prefix_0f" "0")
4180 (const_string "1")))])
4182 ;; Conversions between float and double.
4184 ;; These are all no-ops in the model used for the 80387.
4185 ;; So just emit moves.
4187 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4189 [(set (match_operand:DF 0 "push_operand")
4190 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4192 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4193 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4196 [(set (match_operand:XF 0 "push_operand")
4197 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4199 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4200 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4201 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4203 (define_expand "extendsfdf2"
4204 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4205 (float_extend:DF (match_operand:SF 1 "general_operand")))]
4206 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4208 /* ??? Needed for compress_float_constant since all fp constants
4209 are TARGET_LEGITIMATE_CONSTANT_P. */
4210 if (CONST_DOUBLE_P (operands[1]))
4212 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4213 && standard_80387_constant_p (operands[1]) > 0)
4215 operands[1] = simplify_const_unary_operation
4216 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4217 emit_move_insn_1 (operands[0], operands[1]);
4220 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4224 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4226 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4228 We do the conversion post reload to avoid producing of 128bit spills
4229 that might lead to ICE on 32bit target. The sequence unlikely combine
4232 [(set (match_operand:DF 0 "sse_reg_operand")
4234 (match_operand:SF 1 "nonimmediate_operand")))]
4235 "TARGET_USE_VECTOR_FP_CONVERTS
4236 && optimize_insn_for_speed_p ()
4238 && (!EXT_REX_SSE_REG_P (operands[0])
4239 || TARGET_AVX512VL)"
4244 (parallel [(const_int 0) (const_int 1)]))))]
4246 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4247 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4248 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4249 Try to avoid move when unpacking can be done in source. */
4250 if (REG_P (operands[1]))
4252 /* If it is unsafe to overwrite upper half of source, we need
4253 to move to destination and unpack there. */
4254 if (REGNO (operands[0]) != REGNO (operands[1])
4255 || (EXT_REX_SSE_REG_P (operands[1])
4256 && !TARGET_AVX512VL))
4258 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4259 emit_move_insn (tmp, operands[1]);
4262 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4263 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4264 =v, v, then vbroadcastss will be only needed for AVX512F without
4266 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4267 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4271 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4272 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4276 emit_insn (gen_vec_setv4sf_0 (operands[3],
4277 CONST0_RTX (V4SFmode), operands[1]));
4280 ;; It's more profitable to split and then extend in the same register.
4282 [(set (match_operand:DF 0 "sse_reg_operand")
4284 (match_operand:SF 1 "memory_operand")))]
4285 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4286 && optimize_insn_for_speed_p ()"
4287 [(set (match_dup 2) (match_dup 1))
4288 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4289 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4291 (define_insn "*extendsfdf2"
4292 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v")
4294 (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4295 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4297 switch (which_alternative)
4301 return output_387_reg_move (insn, operands);
4304 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4310 [(set_attr "type" "fmov,fmov,ssecvt")
4311 (set_attr "prefix" "orig,orig,maybe_vex")
4312 (set_attr "mode" "SF,XF,DF")
4313 (set (attr "enabled")
4315 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4317 (eq_attr "alternative" "0,1")
4318 (symbol_ref "TARGET_MIX_SSE_I387")
4319 (symbol_ref "true"))
4321 (eq_attr "alternative" "0,1")
4323 (symbol_ref "false"))))])
4325 (define_expand "extend<mode>xf2"
4326 [(set (match_operand:XF 0 "nonimmediate_operand")
4327 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4330 /* ??? Needed for compress_float_constant since all fp constants
4331 are TARGET_LEGITIMATE_CONSTANT_P. */
4332 if (CONST_DOUBLE_P (operands[1]))
4334 if (standard_80387_constant_p (operands[1]) > 0)
4336 operands[1] = simplify_const_unary_operation
4337 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4338 emit_move_insn_1 (operands[0], operands[1]);
4341 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4345 (define_insn "*extend<mode>xf2_i387"
4346 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4348 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4350 "* return output_387_reg_move (insn, operands);"
4351 [(set_attr "type" "fmov")
4352 (set_attr "mode" "<MODE>,XF")])
4354 ;; %%% This seems like bad news.
4355 ;; This cannot output into an f-reg because there is no way to be sure
4356 ;; of truncating in that case. Otherwise this is just like a simple move
4357 ;; insn. So we pretend we can output to a reg in order to get better
4358 ;; register preferencing, but we really use a stack slot.
4360 ;; Conversion from DFmode to SFmode.
4362 (define_expand "truncdfsf2"
4363 [(set (match_operand:SF 0 "nonimmediate_operand")
4365 (match_operand:DF 1 "nonimmediate_operand")))]
4366 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4368 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4370 else if (flag_unsafe_math_optimizations)
4374 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4375 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4380 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4382 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4384 We do the conversion post reload to avoid producing of 128bit spills
4385 that might lead to ICE on 32bit target. The sequence unlikely combine
4388 [(set (match_operand:SF 0 "sse_reg_operand")
4390 (match_operand:DF 1 "nonimmediate_operand")))]
4391 "TARGET_USE_VECTOR_FP_CONVERTS
4392 && optimize_insn_for_speed_p ()
4394 && (!EXT_REX_SSE_REG_P (operands[0])
4395 || TARGET_AVX512VL)"
4398 (float_truncate:V2SF
4402 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4403 operands[3] = CONST0_RTX (V2SFmode);
4404 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4405 /* Use movsd for loading from memory, unpcklpd for registers.
4406 Try to avoid move when unpacking can be done in source, or SSE3
4407 movddup is available. */
4408 if (REG_P (operands[1]))
4411 && REGNO (operands[0]) != REGNO (operands[1]))
4413 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4414 emit_move_insn (tmp, operands[1]);
4417 else if (!TARGET_SSE3)
4418 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4419 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4422 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4423 CONST0_RTX (DFmode)));
4426 ;; It's more profitable to split and then extend in the same register.
4428 [(set (match_operand:SF 0 "sse_reg_operand")
4430 (match_operand:DF 1 "memory_operand")))]
4431 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4432 && optimize_insn_for_speed_p ()"
4433 [(set (match_dup 2) (match_dup 1))
4434 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4435 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4437 (define_expand "truncdfsf2_with_temp"
4438 [(parallel [(set (match_operand:SF 0)
4439 (float_truncate:SF (match_operand:DF 1)))
4440 (clobber (match_operand:SF 2))])])
4442 ;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
4443 ;; because nothing we do there is unsafe.
4444 (define_insn "*truncdfsf_fast_mixed"
4445 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,v")
4447 (match_operand:DF 1 "nonimmediate_operand" "f ,vm")))]
4448 "TARGET_SSE2 && TARGET_SSE_MATH"
4450 switch (which_alternative)
4453 return output_387_reg_move (insn, operands);
4455 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4460 [(set_attr "type" "fmov,ssecvt")
4461 (set_attr "prefix" "orig,maybe_vex")
4462 (set_attr "mode" "SF")
4463 (set (attr "enabled")
4464 (cond [(eq_attr "alternative" "0")
4465 (symbol_ref "TARGET_MIX_SSE_I387
4466 && flag_unsafe_math_optimizations")
4468 (symbol_ref "true")))])
4470 (define_insn "*truncdfsf_fast_i387"
4471 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4473 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4474 "TARGET_80387 && flag_unsafe_math_optimizations"
4475 "* return output_387_reg_move (insn, operands);"
4476 [(set_attr "type" "fmov")
4477 (set_attr "mode" "SF")])
4479 (define_insn "*truncdfsf_mixed"
4480 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,v ,?f,?v,?*r")
4482 (match_operand:DF 1 "nonimmediate_operand" "f ,vm,f ,f ,f")))
4483 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4484 "TARGET_MIX_SSE_I387"
4486 switch (which_alternative)
4489 return output_387_reg_move (insn, operands);
4491 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4497 [(set_attr "isa" "*,sse2,*,*,*")
4498 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4499 (set_attr "unit" "*,*,i387,i387,i387")
4500 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4501 (set_attr "mode" "SF")])
4503 (define_insn "*truncdfsf_i387"
4504 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4506 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4507 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4510 switch (which_alternative)
4513 return output_387_reg_move (insn, operands);
4519 [(set_attr "type" "fmov,multi,multi,multi")
4520 (set_attr "unit" "*,i387,i387,i387")
4521 (set_attr "mode" "SF")])
4523 (define_insn "*truncdfsf2_i387_1"
4524 [(set (match_operand:SF 0 "memory_operand" "=m")
4526 (match_operand:DF 1 "register_operand" "f")))]
4528 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4529 && !TARGET_MIX_SSE_I387"
4530 "* return output_387_reg_move (insn, operands);"
4531 [(set_attr "type" "fmov")
4532 (set_attr "mode" "SF")])
4535 [(set (match_operand:SF 0 "register_operand")
4537 (match_operand:DF 1 "fp_register_operand")))
4538 (clobber (match_operand 2))]
4540 [(set (match_dup 2) (match_dup 1))
4541 (set (match_dup 0) (match_dup 2))]
4542 "operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));")
4544 ;; Conversion from XFmode to {SF,DF}mode
4546 (define_expand "truncxf<mode>2"
4547 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4548 (float_truncate:MODEF
4549 (match_operand:XF 1 "register_operand")))
4550 (clobber (match_dup 2))])]
4553 if (flag_unsafe_math_optimizations)
4555 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4556 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4557 if (reg != operands[0])
4558 emit_move_insn (operands[0], reg);
4562 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4565 (define_insn "*truncxfsf2_mixed"
4566 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4568 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4569 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4572 gcc_assert (!which_alternative);
4573 return output_387_reg_move (insn, operands);
4575 [(set_attr "type" "fmov,multi,multi,multi")
4576 (set_attr "unit" "*,i387,i387,i387")
4577 (set_attr "mode" "SF")])
4579 (define_insn "*truncxfdf2_mixed"
4580 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4582 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4583 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4586 gcc_assert (!which_alternative);
4587 return output_387_reg_move (insn, operands);
4589 [(set_attr "isa" "*,*,sse2,*")
4590 (set_attr "type" "fmov,multi,multi,multi")
4591 (set_attr "unit" "*,i387,i387,i387")
4592 (set_attr "mode" "DF")])
4594 (define_insn "truncxf<mode>2_i387_noop"
4595 [(set (match_operand:MODEF 0 "register_operand" "=f")
4596 (float_truncate:MODEF
4597 (match_operand:XF 1 "register_operand" "f")))]
4598 "TARGET_80387 && flag_unsafe_math_optimizations"
4599 "* return output_387_reg_move (insn, operands);"
4600 [(set_attr "type" "fmov")
4601 (set_attr "mode" "<MODE>")])
4603 (define_insn "*truncxf<mode>2_i387"
4604 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4605 (float_truncate:MODEF
4606 (match_operand:XF 1 "register_operand" "f")))]
4608 "* return output_387_reg_move (insn, operands);"
4609 [(set_attr "type" "fmov")
4610 (set_attr "mode" "<MODE>")])
4613 [(set (match_operand:MODEF 0 "register_operand")
4614 (float_truncate:MODEF
4615 (match_operand:XF 1 "register_operand")))
4616 (clobber (match_operand:MODEF 2 "memory_operand"))]
4617 "TARGET_80387 && reload_completed"
4618 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4619 (set (match_dup 0) (match_dup 2))])
4622 [(set (match_operand:MODEF 0 "memory_operand")
4623 (float_truncate:MODEF
4624 (match_operand:XF 1 "register_operand")))
4625 (clobber (match_operand:MODEF 2 "memory_operand"))]
4627 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4629 ;; Signed conversion to DImode.
4631 (define_expand "fix_truncxfdi2"
4632 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4633 (fix:DI (match_operand:XF 1 "register_operand")))
4634 (clobber (reg:CC FLAGS_REG))])]
4639 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4644 (define_expand "fix_trunc<mode>di2"
4645 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4646 (fix:DI (match_operand:MODEF 1 "register_operand")))
4647 (clobber (reg:CC FLAGS_REG))])]
4648 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4651 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4653 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4656 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4658 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4659 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4660 if (out != operands[0])
4661 emit_move_insn (operands[0], out);
4666 ;; Signed conversion to SImode.
4668 (define_expand "fix_truncxfsi2"
4669 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4670 (fix:SI (match_operand:XF 1 "register_operand")))
4671 (clobber (reg:CC FLAGS_REG))])]
4676 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4681 (define_expand "fix_trunc<mode>si2"
4682 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4683 (fix:SI (match_operand:MODEF 1 "register_operand")))
4684 (clobber (reg:CC FLAGS_REG))])]
4685 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4688 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4690 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4693 if (SSE_FLOAT_MODE_P (<MODE>mode))
4695 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4696 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4697 if (out != operands[0])
4698 emit_move_insn (operands[0], out);
4703 ;; Signed conversion to HImode.
4705 (define_expand "fix_trunc<mode>hi2"
4706 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4707 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4708 (clobber (reg:CC FLAGS_REG))])]
4710 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4714 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4719 ;; Unsigned conversion to SImode.
4721 (define_expand "fixuns_trunc<mode>si2"
4723 [(set (match_operand:SI 0 "register_operand")
4725 (match_operand:MODEF 1 "nonimmediate_operand")))
4727 (clobber (match_scratch:<ssevecmode> 3))
4728 (clobber (match_scratch:<ssevecmode> 4))])]
4729 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4731 machine_mode mode = <MODE>mode;
4732 machine_mode vecmode = <ssevecmode>mode;
4733 REAL_VALUE_TYPE TWO31r;
4736 if (optimize_insn_for_size_p ())
4739 real_ldexp (&TWO31r, &dconst1, 31);
4740 two31 = const_double_from_real_value (TWO31r, mode);
4741 two31 = ix86_build_const_vector (vecmode, true, two31);
4742 operands[2] = force_reg (vecmode, two31);
4745 (define_insn_and_split "*fixuns_trunc<mode>_1"
4746 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4748 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4749 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4750 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4751 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4752 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4753 && optimize_function_for_speed_p (cfun)"
4755 "&& reload_completed"
4758 ix86_split_convert_uns_si_sse (operands);
4762 ;; Unsigned conversion to HImode.
4763 ;; Without these patterns, we'll try the unsigned SI conversion which
4764 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4766 (define_expand "fixuns_trunc<mode>hi2"
4768 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4769 (set (match_operand:HI 0 "nonimmediate_operand")
4770 (subreg:HI (match_dup 2) 0))]
4771 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4772 "operands[2] = gen_reg_rtx (SImode);")
4774 ;; When SSE is available, it is always faster to use it!
4775 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4776 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4777 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
4778 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4779 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4780 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4781 [(set_attr "type" "sseicvt")
4782 (set_attr "prefix" "maybe_vex")
4783 (set (attr "prefix_rex")
4785 (match_test "<SWI48:MODE>mode == DImode")
4787 (const_string "*")))
4788 (set_attr "mode" "<MODEF:MODE>")
4789 (set_attr "athlon_decode" "double,vector")
4790 (set_attr "amdfam10_decode" "double,double")
4791 (set_attr "bdver1_decode" "double,double")])
4793 ;; Avoid vector decoded forms of the instruction.
4795 [(match_scratch:MODEF 2 "x")
4796 (set (match_operand:SWI48 0 "register_operand")
4797 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4798 "TARGET_AVOID_VECTOR_DECODE
4799 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4800 && optimize_insn_for_speed_p ()"
4801 [(set (match_dup 2) (match_dup 1))
4802 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4804 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4805 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4806 (fix:SWI248x (match_operand 1 "register_operand")))]
4807 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4809 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4810 && (TARGET_64BIT || <MODE>mode != DImode))
4812 && can_create_pseudo_p ()"
4817 if (memory_operand (operands[0], VOIDmode))
4818 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4821 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4822 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4828 [(set_attr "type" "fisttp")
4829 (set_attr "mode" "<MODE>")])
4831 (define_insn "fix_trunc<mode>_i387_fisttp"
4832 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4833 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4834 (clobber (match_scratch:XF 2 "=&1f"))]
4835 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4837 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4838 && (TARGET_64BIT || <MODE>mode != DImode))
4839 && TARGET_SSE_MATH)"
4840 "* return output_fix_trunc (insn, operands, true);"
4841 [(set_attr "type" "fisttp")
4842 (set_attr "mode" "<MODE>")])
4844 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4845 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4846 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4847 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4848 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4849 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4851 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4852 && (TARGET_64BIT || <MODE>mode != DImode))
4853 && TARGET_SSE_MATH)"
4855 [(set_attr "type" "fisttp")
4856 (set_attr "mode" "<MODE>")])
4859 [(set (match_operand:SWI248x 0 "register_operand")
4860 (fix:SWI248x (match_operand 1 "register_operand")))
4861 (clobber (match_operand:SWI248x 2 "memory_operand"))
4862 (clobber (match_scratch 3))]
4864 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4865 (clobber (match_dup 3))])
4866 (set (match_dup 0) (match_dup 2))])
4869 [(set (match_operand:SWI248x 0 "memory_operand")
4870 (fix:SWI248x (match_operand 1 "register_operand")))
4871 (clobber (match_operand:SWI248x 2 "memory_operand"))
4872 (clobber (match_scratch 3))]
4874 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4875 (clobber (match_dup 3))])])
4877 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4878 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4879 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4880 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4881 ;; function in i386.c.
4882 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4883 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4884 (fix:SWI248x (match_operand 1 "register_operand")))
4885 (clobber (reg:CC FLAGS_REG))]
4886 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4888 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4889 && (TARGET_64BIT || <MODE>mode != DImode))
4890 && can_create_pseudo_p ()"
4895 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4897 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4898 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4899 if (memory_operand (operands[0], VOIDmode))
4900 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4901 operands[2], operands[3]));
4904 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4905 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4906 operands[2], operands[3],
4911 [(set_attr "type" "fistp")
4912 (set_attr "i387_cw" "trunc")
4913 (set_attr "mode" "<MODE>")])
4915 (define_insn "fix_truncdi_i387"
4916 [(set (match_operand:DI 0 "memory_operand" "=m")
4917 (fix:DI (match_operand 1 "register_operand" "f")))
4918 (use (match_operand:HI 2 "memory_operand" "m"))
4919 (use (match_operand:HI 3 "memory_operand" "m"))
4920 (clobber (match_scratch:XF 4 "=&1f"))]
4921 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4923 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4924 "* return output_fix_trunc (insn, operands, false);"
4925 [(set_attr "type" "fistp")
4926 (set_attr "i387_cw" "trunc")
4927 (set_attr "mode" "DI")])
4929 (define_insn "fix_truncdi_i387_with_temp"
4930 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4931 (fix:DI (match_operand 1 "register_operand" "f,f")))
4932 (use (match_operand:HI 2 "memory_operand" "m,m"))
4933 (use (match_operand:HI 3 "memory_operand" "m,m"))
4934 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4935 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4936 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4938 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4940 [(set_attr "type" "fistp")
4941 (set_attr "i387_cw" "trunc")
4942 (set_attr "mode" "DI")])
4945 [(set (match_operand:DI 0 "register_operand")
4946 (fix:DI (match_operand 1 "register_operand")))
4947 (use (match_operand:HI 2 "memory_operand"))
4948 (use (match_operand:HI 3 "memory_operand"))
4949 (clobber (match_operand:DI 4 "memory_operand"))
4950 (clobber (match_scratch 5))]
4952 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4955 (clobber (match_dup 5))])
4956 (set (match_dup 0) (match_dup 4))])
4959 [(set (match_operand:DI 0 "memory_operand")
4960 (fix:DI (match_operand 1 "register_operand")))
4961 (use (match_operand:HI 2 "memory_operand"))
4962 (use (match_operand:HI 3 "memory_operand"))
4963 (clobber (match_operand:DI 4 "memory_operand"))
4964 (clobber (match_scratch 5))]
4966 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4969 (clobber (match_dup 5))])])
4971 (define_insn "fix_trunc<mode>_i387"
4972 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4973 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4974 (use (match_operand:HI 2 "memory_operand" "m"))
4975 (use (match_operand:HI 3 "memory_operand" "m"))]
4976 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4978 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4979 "* return output_fix_trunc (insn, operands, false);"
4980 [(set_attr "type" "fistp")
4981 (set_attr "i387_cw" "trunc")
4982 (set_attr "mode" "<MODE>")])
4984 (define_insn "fix_trunc<mode>_i387_with_temp"
4985 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4986 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4987 (use (match_operand:HI 2 "memory_operand" "m,m"))
4988 (use (match_operand:HI 3 "memory_operand" "m,m"))
4989 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4990 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4992 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4994 [(set_attr "type" "fistp")
4995 (set_attr "i387_cw" "trunc")
4996 (set_attr "mode" "<MODE>")])
4999 [(set (match_operand:SWI24 0 "register_operand")
5000 (fix:SWI24 (match_operand 1 "register_operand")))
5001 (use (match_operand:HI 2 "memory_operand"))
5002 (use (match_operand:HI 3 "memory_operand"))
5003 (clobber (match_operand:SWI24 4 "memory_operand"))]
5005 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
5007 (use (match_dup 3))])
5008 (set (match_dup 0) (match_dup 4))])
5011 [(set (match_operand:SWI24 0 "memory_operand")
5012 (fix:SWI24 (match_operand 1 "register_operand")))
5013 (use (match_operand:HI 2 "memory_operand"))
5014 (use (match_operand:HI 3 "memory_operand"))
5015 (clobber (match_operand:SWI24 4 "memory_operand"))]
5017 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
5019 (use (match_dup 3))])])
5021 (define_insn "x86_fnstcw_1"
5022 [(set (match_operand:HI 0 "memory_operand" "=m")
5023 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5026 [(set (attr "length")
5027 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5028 (set_attr "mode" "HI")
5029 (set_attr "unit" "i387")
5030 (set_attr "bdver1_decode" "vector")])
5032 (define_insn "x86_fldcw_1"
5033 [(set (reg:HI FPCR_REG)
5034 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5037 [(set (attr "length")
5038 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5039 (set_attr "mode" "HI")
5040 (set_attr "unit" "i387")
5041 (set_attr "athlon_decode" "vector")
5042 (set_attr "amdfam10_decode" "vector")
5043 (set_attr "bdver1_decode" "vector")])
5045 ;; Conversion between fixed point and floating point.
5047 ;; Even though we only accept memory inputs, the backend _really_
5048 ;; wants to be able to do this between registers. Thankfully, LRA
5049 ;; will fix this up for us during register allocation.
5051 (define_insn "floathi<mode>2"
5052 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5053 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5055 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5056 || TARGET_MIX_SSE_I387)"
5058 [(set_attr "type" "fmov")
5059 (set_attr "mode" "<MODE>")
5060 (set_attr "znver1_decode" "double")
5061 (set_attr "fp_int_src" "true")])
5063 (define_insn "float<SWI48x:mode>xf2"
5064 [(set (match_operand:XF 0 "register_operand" "=f")
5065 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5068 [(set_attr "type" "fmov")
5069 (set_attr "mode" "XF")
5070 (set_attr "znver1_decode" "double")
5071 (set_attr "fp_int_src" "true")])
5073 (define_expand "float<SWI48:mode><MODEF:mode>2"
5074 [(set (match_operand:MODEF 0 "register_operand")
5075 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5076 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5078 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
5079 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5081 rtx reg = gen_reg_rtx (XFmode);
5082 rtx (*insn)(rtx, rtx);
5084 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
5086 if (<MODEF:MODE>mode == SFmode)
5087 insn = gen_truncxfsf2;
5088 else if (<MODEF:MODE>mode == DFmode)
5089 insn = gen_truncxfdf2;
5093 emit_insn (insn (operands[0], reg));
5098 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed"
5099 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5101 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5102 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5105 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5106 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5107 [(set_attr "type" "fmov,sseicvt,sseicvt")
5108 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5109 (set_attr "mode" "<MODEF:MODE>")
5110 (set (attr "prefix_rex")
5112 (and (eq_attr "prefix" "maybe_vex")
5113 (match_test "<SWI48:MODE>mode == DImode"))
5115 (const_string "*")))
5116 (set_attr "unit" "i387,*,*")
5117 (set_attr "athlon_decode" "*,double,direct")
5118 (set_attr "amdfam10_decode" "*,vector,double")
5119 (set_attr "bdver1_decode" "*,double,direct")
5120 (set_attr "znver1_decode" "double,*,*")
5121 (set_attr "fp_int_src" "true")
5122 (set (attr "enabled")
5123 (cond [(eq_attr "alternative" "0")
5124 (symbol_ref "TARGET_MIX_SSE_I387
5125 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5128 (symbol_ref "true")))
5129 (set (attr "preferred_for_speed")
5130 (cond [(eq_attr "alternative" "1")
5131 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5132 (symbol_ref "true")))])
5134 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
5135 [(set (match_operand:MODEF 0 "register_operand" "=f")
5136 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5137 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
5139 [(set_attr "type" "fmov")
5140 (set_attr "mode" "<MODEF:MODE>")
5141 (set_attr "znver1_decode" "double")
5142 (set_attr "fp_int_src" "true")])
5144 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5145 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5146 ;; alternative in sse2_loadld.
5148 [(set (match_operand:MODEF 0 "sse_reg_operand")
5149 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5150 "TARGET_USE_VECTOR_CONVERTS
5151 && optimize_function_for_speed_p (cfun)
5153 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5154 && (!EXT_REX_SSE_REG_P (operands[0])
5155 || TARGET_AVX512VL)"
5158 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5159 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5161 emit_insn (gen_sse2_loadld (operands[4],
5162 CONST0_RTX (V4SImode), operands[1]));
5164 if (<ssevecmode>mode == V4SFmode)
5165 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5167 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5171 ;; Avoid partial SSE register dependency stalls. This splitter should split
5172 ;; late in the pass sequence (after register rename pass), so allocated
5173 ;; registers won't change anymore
5176 [(set (match_operand:MODEF 0 "sse_reg_operand")
5177 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5178 "TARGET_SSE_PARTIAL_REG_DEPENDENCY
5179 && optimize_function_for_speed_p (cfun)
5180 && epilogue_completed
5181 && (!EXT_REX_SSE_REG_P (operands[0])
5182 || TARGET_AVX512VL)"
5184 (vec_merge:<MODEF:ssevecmode>
5185 (vec_duplicate:<MODEF:ssevecmode>
5191 const machine_mode vmode = <MODEF:ssevecmode>mode;
5193 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5194 emit_move_insn (operands[0], CONST0_RTX (vmode));
5197 ;; Break partial reg stall for cvtsd2ss. This splitter should split
5198 ;; late in the pass sequence (after register rename pass),
5199 ;; so allocated registers won't change anymore.
5202 [(set (match_operand:SF 0 "sse_reg_operand")
5204 (match_operand:DF 1 "nonimmediate_operand")))]
5205 "TARGET_SSE_PARTIAL_REG_DEPENDENCY
5206 && optimize_function_for_speed_p (cfun)
5207 && epilogue_completed
5208 && (!REG_P (operands[1])
5209 || REGNO (operands[0]) != REGNO (operands[1]))
5210 && (!EXT_REX_SSE_REG_P (operands[0])
5211 || TARGET_AVX512VL)"
5220 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5221 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5224 ;; Break partial reg stall for cvtss2sd. This splitter should split
5225 ;; late in the pass sequence (after register rename pass),
5226 ;; so allocated registers won't change anymore.
5229 [(set (match_operand:DF 0 "sse_reg_operand")
5231 (match_operand:SF 1 "nonimmediate_operand")))]
5232 "TARGET_SSE_PARTIAL_REG_DEPENDENCY
5233 && optimize_function_for_speed_p (cfun)
5234 && epilogue_completed
5235 && (!REG_P (operands[1])
5236 || REGNO (operands[0]) != REGNO (operands[1]))
5237 && (!EXT_REX_SSE_REG_P (operands[0])
5238 || TARGET_AVX512VL)"
5247 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5248 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5251 ;; Avoid store forwarding (partial memory) stall penalty
5252 ;; by passing DImode value through XMM registers. */
5254 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5255 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5257 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5258 (clobber (match_scratch:V4SI 3 "=X,x"))
5259 (clobber (match_scratch:V4SI 4 "=X,x"))
5260 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5261 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5262 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5263 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5265 [(set_attr "type" "multi")
5266 (set_attr "mode" "<X87MODEF:MODE>")
5267 (set_attr "unit" "i387")
5268 (set_attr "fp_int_src" "true")])
5271 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5272 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5273 (clobber (match_scratch:V4SI 3))
5274 (clobber (match_scratch:V4SI 4))
5275 (clobber (match_operand:DI 2 "memory_operand"))]
5276 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5277 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5278 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5279 && reload_completed"
5280 [(set (match_dup 2) (match_dup 3))
5281 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5283 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5284 Assemble the 64-bit DImode value in an xmm register. */
5285 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5286 gen_lowpart (SImode, operands[1])));
5287 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5288 gen_highpart (SImode, operands[1])));
5289 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5292 operands[3] = gen_lowpart (DImode, operands[3]);
5296 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5297 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5298 (clobber (match_scratch:V4SI 3))
5299 (clobber (match_scratch:V4SI 4))
5300 (clobber (match_operand:DI 2 "memory_operand"))]
5301 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5302 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5303 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5304 && reload_completed"
5305 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5307 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5308 [(set (match_operand:MODEF 0 "register_operand")
5309 (unsigned_float:MODEF
5310 (match_operand:SWI12 1 "nonimmediate_operand")))]
5312 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5314 operands[1] = convert_to_mode (SImode, operands[1], 1);
5315 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5319 ;; Avoid store forwarding (partial memory) stall penalty by extending
5320 ;; SImode value to DImode through XMM register instead of pushing two
5321 ;; SImode values to stack. Also note that fild loads from memory only.
5323 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5324 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5325 (unsigned_float:X87MODEF
5326 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5327 (clobber (match_scratch:DI 3 "=x"))
5328 (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5330 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5331 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5333 "&& reload_completed"
5334 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5335 (set (match_dup 2) (match_dup 3))
5337 (float:X87MODEF (match_dup 2)))]
5339 [(set_attr "type" "multi")
5340 (set_attr "mode" "<MODE>")])
5342 (define_expand "floatunssi<mode>2"
5344 [(set (match_operand:X87MODEF 0 "register_operand")
5345 (unsigned_float:X87MODEF
5346 (match_operand:SI 1 "nonimmediate_operand")))
5347 (clobber (match_scratch:DI 3))
5348 (clobber (match_dup 2))])]
5350 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5351 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5352 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5354 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5356 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5360 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5363 (define_expand "floatunsdisf2"
5364 [(use (match_operand:SF 0 "register_operand"))
5365 (use (match_operand:DI 1 "nonimmediate_operand"))]
5366 "TARGET_64BIT && TARGET_SSE_MATH"
5367 "x86_emit_floatuns (operands); DONE;")
5369 (define_expand "floatunsdidf2"
5370 [(use (match_operand:DF 0 "register_operand"))
5371 (use (match_operand:DI 1 "nonimmediate_operand"))]
5372 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5373 && TARGET_SSE2 && TARGET_SSE_MATH"
5376 x86_emit_floatuns (operands);
5378 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5382 ;; Load effective address instructions
5384 (define_insn_and_split "*lea<mode>"
5385 [(set (match_operand:SWI48 0 "register_operand" "=r")
5386 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5389 if (SImode_address_operand (operands[1], VOIDmode))
5391 gcc_assert (TARGET_64BIT);
5392 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5395 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5397 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5400 machine_mode mode = <MODE>mode;
5403 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5404 change operands[] array behind our back. */
5405 pat = PATTERN (curr_insn);
5407 operands[0] = SET_DEST (pat);
5408 operands[1] = SET_SRC (pat);
5410 /* Emit all operations in SImode for zero-extended addresses. */
5411 if (SImode_address_operand (operands[1], VOIDmode))
5414 ix86_split_lea_for_addr (curr_insn, operands, mode);
5416 /* Zero-extend return register to DImode for zero-extended addresses. */
5417 if (mode != <MODE>mode)
5418 emit_insn (gen_zero_extendsidi2
5419 (operands[0], gen_lowpart (mode, operands[0])));
5423 [(set_attr "type" "lea")
5426 (match_operand 1 "SImode_address_operand")
5428 (const_string "<MODE>")))])
5432 (define_expand "add<mode>3"
5433 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5434 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5435 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5437 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5439 (define_insn_and_split "*add<dwi>3_doubleword"
5440 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5442 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5443 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
5445 (clobber (reg:CC FLAGS_REG))]
5446 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5449 [(parallel [(set (reg:CCC FLAGS_REG)
5451 (plus:DWIH (match_dup 1) (match_dup 2))
5454 (plus:DWIH (match_dup 1) (match_dup 2)))])
5455 (parallel [(set (match_dup 3)
5458 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5461 (clobber (reg:CC FLAGS_REG))])]
5463 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5464 if (operands[2] == const0_rtx)
5466 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5471 (define_insn "*add<mode>_1"
5472 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5474 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5475 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5476 (clobber (reg:CC FLAGS_REG))]
5477 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5479 switch (get_attr_type (insn))
5485 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5486 if (operands[2] == const1_rtx)
5487 return "inc{<imodesuffix>}\t%0";
5490 gcc_assert (operands[2] == constm1_rtx);
5491 return "dec{<imodesuffix>}\t%0";
5495 /* For most processors, ADD is faster than LEA. This alternative
5496 was added to use ADD as much as possible. */
5497 if (which_alternative == 2)
5498 std::swap (operands[1], operands[2]);
5500 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5501 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5502 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5504 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5508 (cond [(eq_attr "alternative" "3")
5509 (const_string "lea")
5510 (match_operand:SWI48 2 "incdec_operand")
5511 (const_string "incdec")
5513 (const_string "alu")))
5514 (set (attr "length_immediate")
5516 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5518 (const_string "*")))
5519 (set_attr "mode" "<MODE>")])
5521 ;; It may seem that nonimmediate operand is proper one for operand 1.
5522 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5523 ;; we take care in ix86_binary_operator_ok to not allow two memory
5524 ;; operands so proper swapping will be done in reload. This allow
5525 ;; patterns constructed from addsi_1 to match.
5527 (define_insn "addsi_1_zext"
5528 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5530 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5531 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5532 (clobber (reg:CC FLAGS_REG))]
5533 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5535 switch (get_attr_type (insn))
5541 if (operands[2] == const1_rtx)
5542 return "inc{l}\t%k0";
5545 gcc_assert (operands[2] == constm1_rtx);
5546 return "dec{l}\t%k0";
5550 /* For most processors, ADD is faster than LEA. This alternative
5551 was added to use ADD as much as possible. */
5552 if (which_alternative == 1)
5553 std::swap (operands[1], operands[2]);
5555 if (x86_maybe_negate_const_int (&operands[2], SImode))
5556 return "sub{l}\t{%2, %k0|%k0, %2}";
5558 return "add{l}\t{%2, %k0|%k0, %2}";
5562 (cond [(eq_attr "alternative" "2")
5563 (const_string "lea")
5564 (match_operand:SI 2 "incdec_operand")
5565 (const_string "incdec")
5567 (const_string "alu")))
5568 (set (attr "length_immediate")
5570 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5572 (const_string "*")))
5573 (set_attr "mode" "SI")])
5575 (define_insn "*addhi_1"
5576 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5577 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5578 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5579 (clobber (reg:CC FLAGS_REG))]
5580 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5582 switch (get_attr_type (insn))
5588 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5589 if (operands[2] == const1_rtx)
5590 return "inc{w}\t%0";
5593 gcc_assert (operands[2] == constm1_rtx);
5594 return "dec{w}\t%0";
5598 /* For most processors, ADD is faster than LEA. This alternative
5599 was added to use ADD as much as possible. */
5600 if (which_alternative == 2)
5601 std::swap (operands[1], operands[2]);
5603 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5604 if (x86_maybe_negate_const_int (&operands[2], HImode))
5605 return "sub{w}\t{%2, %0|%0, %2}";
5607 return "add{w}\t{%2, %0|%0, %2}";
5611 (cond [(eq_attr "alternative" "3")
5612 (const_string "lea")
5613 (match_operand:HI 2 "incdec_operand")
5614 (const_string "incdec")
5616 (const_string "alu")))
5617 (set (attr "length_immediate")
5619 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5621 (const_string "*")))
5622 (set_attr "mode" "HI,HI,HI,SI")])
5624 (define_insn "*addqi_1"
5625 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5626 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5627 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5628 (clobber (reg:CC FLAGS_REG))]
5629 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5631 bool widen = (get_attr_mode (insn) != MODE_QI);
5633 switch (get_attr_type (insn))
5639 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5640 if (operands[2] == const1_rtx)
5641 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5644 gcc_assert (operands[2] == constm1_rtx);
5645 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5649 /* For most processors, ADD is faster than LEA. These alternatives
5650 were added to use ADD as much as possible. */
5651 if (which_alternative == 2 || which_alternative == 4)
5652 std::swap (operands[1], operands[2]);
5654 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5655 if (x86_maybe_negate_const_int (&operands[2], QImode))
5658 return "sub{l}\t{%2, %k0|%k0, %2}";
5660 return "sub{b}\t{%2, %0|%0, %2}";
5663 return "add{l}\t{%k2, %k0|%k0, %k2}";
5665 return "add{b}\t{%2, %0|%0, %2}";
5669 (cond [(eq_attr "alternative" "5")
5670 (const_string "lea")
5671 (match_operand:QI 2 "incdec_operand")
5672 (const_string "incdec")
5674 (const_string "alu")))
5675 (set (attr "length_immediate")
5677 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5679 (const_string "*")))
5680 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
5681 ;; Potential partial reg stall on alternatives 3 and 4.
5682 (set (attr "preferred_for_speed")
5683 (cond [(eq_attr "alternative" "3,4")
5684 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
5685 (symbol_ref "true")))])
5687 (define_insn "*addqi_1_slp"
5688 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5689 (plus:QI (match_dup 0)
5690 (match_operand:QI 1 "general_operand" "qn,qm")))
5691 (clobber (reg:CC FLAGS_REG))]
5692 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5693 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5695 switch (get_attr_type (insn))
5698 if (operands[1] == const1_rtx)
5699 return "inc{b}\t%0";
5702 gcc_assert (operands[1] == constm1_rtx);
5703 return "dec{b}\t%0";
5707 if (x86_maybe_negate_const_int (&operands[1], QImode))
5708 return "sub{b}\t{%1, %0|%0, %1}";
5710 return "add{b}\t{%1, %0|%0, %1}";
5714 (if_then_else (match_operand:QI 1 "incdec_operand")
5715 (const_string "incdec")
5716 (const_string "alu1")))
5717 (set (attr "memory")
5718 (if_then_else (match_operand 1 "memory_operand")
5719 (const_string "load")
5720 (const_string "none")))
5721 (set_attr "mode" "QI")])
5723 ;; Split non destructive adds if we cannot use lea.
5725 [(set (match_operand:SWI48 0 "register_operand")
5726 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5727 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5728 (clobber (reg:CC FLAGS_REG))]
5729 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5730 [(set (match_dup 0) (match_dup 1))
5731 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5732 (clobber (reg:CC FLAGS_REG))])])
5734 ;; Split non destructive adds if we cannot use lea.
5736 [(set (match_operand:DI 0 "register_operand")
5738 (plus:SI (match_operand:SI 1 "register_operand")
5739 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5740 (clobber (reg:CC FLAGS_REG))]
5742 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5743 [(set (match_dup 3) (match_dup 1))
5744 (parallel [(set (match_dup 0)
5745 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5746 (clobber (reg:CC FLAGS_REG))])]
5747 "operands[3] = gen_lowpart (SImode, operands[0]);")
5749 ;; Convert add to the lea pattern to avoid flags dependency.
5751 [(set (match_operand:SWI 0 "register_operand")
5752 (plus:SWI (match_operand:SWI 1 "register_operand")
5753 (match_operand:SWI 2 "<nonmemory_operand>")))
5754 (clobber (reg:CC FLAGS_REG))]
5755 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5757 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
5759 if (<MODE>mode != <LEAMODE>mode)
5761 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
5762 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
5763 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
5767 ;; Convert add to the lea pattern to avoid flags dependency.
5769 [(set (match_operand:DI 0 "register_operand")
5771 (plus:SI (match_operand:SI 1 "register_operand")
5772 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5773 (clobber (reg:CC FLAGS_REG))]
5774 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5776 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5778 (define_insn "*add<mode>_2"
5779 [(set (reg FLAGS_REG)
5782 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5783 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5785 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5786 (plus:SWI (match_dup 1) (match_dup 2)))]
5787 "ix86_match_ccmode (insn, CCGOCmode)
5788 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5790 switch (get_attr_type (insn))
5793 if (operands[2] == const1_rtx)
5794 return "inc{<imodesuffix>}\t%0";
5797 gcc_assert (operands[2] == constm1_rtx);
5798 return "dec{<imodesuffix>}\t%0";
5802 if (which_alternative == 2)
5803 std::swap (operands[1], operands[2]);
5805 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5806 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5807 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5809 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5813 (if_then_else (match_operand:SWI 2 "incdec_operand")
5814 (const_string "incdec")
5815 (const_string "alu")))
5816 (set (attr "length_immediate")
5818 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5820 (const_string "*")))
5821 (set_attr "mode" "<MODE>")])
5823 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5824 (define_insn "*addsi_2_zext"
5825 [(set (reg FLAGS_REG)
5827 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5828 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5830 (set (match_operand:DI 0 "register_operand" "=r,r")
5831 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5832 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5833 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5835 switch (get_attr_type (insn))
5838 if (operands[2] == const1_rtx)
5839 return "inc{l}\t%k0";
5842 gcc_assert (operands[2] == constm1_rtx);
5843 return "dec{l}\t%k0";
5847 if (which_alternative == 1)
5848 std::swap (operands[1], operands[2]);
5850 if (x86_maybe_negate_const_int (&operands[2], SImode))
5851 return "sub{l}\t{%2, %k0|%k0, %2}";
5853 return "add{l}\t{%2, %k0|%k0, %2}";
5857 (if_then_else (match_operand:SI 2 "incdec_operand")
5858 (const_string "incdec")
5859 (const_string "alu")))
5860 (set (attr "length_immediate")
5862 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5864 (const_string "*")))
5865 (set_attr "mode" "SI")])
5867 (define_insn "*add<mode>_3"
5868 [(set (reg FLAGS_REG)
5870 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5871 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5872 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5873 "ix86_match_ccmode (insn, CCZmode)
5874 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5876 switch (get_attr_type (insn))
5879 if (operands[2] == const1_rtx)
5880 return "inc{<imodesuffix>}\t%0";
5883 gcc_assert (operands[2] == constm1_rtx);
5884 return "dec{<imodesuffix>}\t%0";
5888 if (which_alternative == 1)
5889 std::swap (operands[1], operands[2]);
5891 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5892 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5893 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5895 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5899 (if_then_else (match_operand:SWI 2 "incdec_operand")
5900 (const_string "incdec")
5901 (const_string "alu")))
5902 (set (attr "length_immediate")
5904 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5906 (const_string "*")))
5907 (set_attr "mode" "<MODE>")])
5909 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5910 (define_insn "*addsi_3_zext"
5911 [(set (reg FLAGS_REG)
5913 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5914 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5915 (set (match_operand:DI 0 "register_operand" "=r,r")
5916 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5917 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5918 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5920 switch (get_attr_type (insn))
5923 if (operands[2] == const1_rtx)
5924 return "inc{l}\t%k0";
5927 gcc_assert (operands[2] == constm1_rtx);
5928 return "dec{l}\t%k0";
5932 if (which_alternative == 1)
5933 std::swap (operands[1], operands[2]);
5935 if (x86_maybe_negate_const_int (&operands[2], SImode))
5936 return "sub{l}\t{%2, %k0|%k0, %2}";
5938 return "add{l}\t{%2, %k0|%k0, %2}";
5942 (if_then_else (match_operand:SI 2 "incdec_operand")
5943 (const_string "incdec")
5944 (const_string "alu")))
5945 (set (attr "length_immediate")
5947 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5949 (const_string "*")))
5950 (set_attr "mode" "SI")])
5952 ; For comparisons against 1, -1 and 128, we may generate better code
5953 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5954 ; is matched then. We can't accept general immediate, because for
5955 ; case of overflows, the result is messed up.
5956 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5957 ; only for comparisons not depending on it.
5959 (define_insn "*adddi_4"
5960 [(set (reg FLAGS_REG)
5962 (match_operand:DI 1 "nonimmediate_operand" "0")
5963 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5964 (clobber (match_scratch:DI 0 "=rm"))]
5966 && ix86_match_ccmode (insn, CCGCmode)"
5968 switch (get_attr_type (insn))
5971 if (operands[2] == constm1_rtx)
5972 return "inc{q}\t%0";
5975 gcc_assert (operands[2] == const1_rtx);
5976 return "dec{q}\t%0";
5980 if (x86_maybe_negate_const_int (&operands[2], DImode))
5981 return "add{q}\t{%2, %0|%0, %2}";
5983 return "sub{q}\t{%2, %0|%0, %2}";
5987 (if_then_else (match_operand:DI 2 "incdec_operand")
5988 (const_string "incdec")
5989 (const_string "alu")))
5990 (set (attr "length_immediate")
5992 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5994 (const_string "*")))
5995 (set_attr "mode" "DI")])
5997 ; For comparisons against 1, -1 and 128, we may generate better code
5998 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5999 ; is matched then. We can't accept general immediate, because for
6000 ; case of overflows, the result is messed up.
6001 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6002 ; only for comparisons not depending on it.
6004 (define_insn "*add<mode>_4"
6005 [(set (reg FLAGS_REG)
6007 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6008 (match_operand:SWI124 2 "const_int_operand" "n")))
6009 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6010 "ix86_match_ccmode (insn, CCGCmode)"
6012 switch (get_attr_type (insn))
6015 if (operands[2] == constm1_rtx)
6016 return "inc{<imodesuffix>}\t%0";
6019 gcc_assert (operands[2] == const1_rtx);
6020 return "dec{<imodesuffix>}\t%0";
6024 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6025 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6027 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6031 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6032 (const_string "incdec")
6033 (const_string "alu")))
6034 (set (attr "length_immediate")
6036 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6038 (const_string "*")))
6039 (set_attr "mode" "<MODE>")])
6041 (define_insn "*add<mode>_5"
6042 [(set (reg FLAGS_REG)
6045 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6046 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6048 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6049 "ix86_match_ccmode (insn, CCGOCmode)
6050 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6052 switch (get_attr_type (insn))
6055 if (operands[2] == const1_rtx)
6056 return "inc{<imodesuffix>}\t%0";
6059 gcc_assert (operands[2] == constm1_rtx);
6060 return "dec{<imodesuffix>}\t%0";
6064 if (which_alternative == 1)
6065 std::swap (operands[1], operands[2]);
6067 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6068 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6069 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6071 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6075 (if_then_else (match_operand:SWI 2 "incdec_operand")
6076 (const_string "incdec")
6077 (const_string "alu")))
6078 (set (attr "length_immediate")
6080 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6082 (const_string "*")))
6083 (set_attr "mode" "<MODE>")])
6085 (define_insn "addqi_ext_1"
6086 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
6091 (match_operand 1 "ext_register_operand" "0,0")
6094 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
6095 (clobber (reg:CC FLAGS_REG))]
6098 switch (get_attr_type (insn))
6101 if (operands[2] == const1_rtx)
6102 return "inc{b}\t%h0";
6105 gcc_assert (operands[2] == constm1_rtx);
6106 return "dec{b}\t%h0";
6110 return "add{b}\t{%2, %h0|%h0, %2}";
6113 [(set_attr "isa" "*,nox64")
6115 (if_then_else (match_operand:QI 2 "incdec_operand")
6116 (const_string "incdec")
6117 (const_string "alu")))
6118 (set_attr "modrm" "1")
6119 (set_attr "mode" "QI")])
6121 (define_insn "*addqi_ext_2"
6122 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6127 (match_operand 1 "ext_register_operand" "%0")
6131 (match_operand 2 "ext_register_operand" "Q")
6134 (clobber (reg:CC FLAGS_REG))]
6136 "add{b}\t{%h2, %h0|%h0, %h2}"
6137 [(set_attr "type" "alu")
6138 (set_attr "mode" "QI")])
6140 ;; Add with jump on overflow.
6141 (define_expand "addv<mode>4"
6142 [(parallel [(set (reg:CCO FLAGS_REG)
6145 (match_operand:SWI 1 "nonimmediate_operand"))
6148 (plus:SWI (match_dup 1)
6149 (match_operand:SWI 2
6150 "<general_operand>")))))
6151 (set (match_operand:SWI 0 "register_operand")
6152 (plus:SWI (match_dup 1) (match_dup 2)))])
6153 (set (pc) (if_then_else
6154 (eq (reg:CCO FLAGS_REG) (const_int 0))
6155 (label_ref (match_operand 3))
6159 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6160 if (CONST_INT_P (operands[2]))
6161 operands[4] = operands[2];
6163 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6166 (define_insn "*addv<mode>4"
6167 [(set (reg:CCO FLAGS_REG)
6170 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6172 (match_operand:SWI 2 "<general_sext_operand>"
6175 (plus:SWI (match_dup 1) (match_dup 2)))))
6176 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6177 (plus:SWI (match_dup 1) (match_dup 2)))]
6178 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6179 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6180 [(set_attr "type" "alu")
6181 (set_attr "mode" "<MODE>")])
6183 (define_insn "*addv<mode>4_1"
6184 [(set (reg:CCO FLAGS_REG)
6187 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6188 (match_operand:<DWI> 3 "const_int_operand" "i"))
6190 (plus:SWI (match_dup 1)
6191 (match_operand:SWI 2 "x86_64_immediate_operand"
6193 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6194 (plus:SWI (match_dup 1) (match_dup 2)))]
6195 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6196 && CONST_INT_P (operands[2])
6197 && INTVAL (operands[2]) == INTVAL (operands[3])"
6198 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6199 [(set_attr "type" "alu")
6200 (set_attr "mode" "<MODE>")
6201 (set (attr "length_immediate")
6202 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6204 (match_test "<MODE_SIZE> == 8")
6206 (const_string "<MODE_SIZE>")))])
6208 (define_expand "uaddv<mode>4"
6209 [(parallel [(set (reg:CCC FLAGS_REG)
6212 (match_operand:SWI 1 "nonimmediate_operand")
6213 (match_operand:SWI 2 "<general_operand>"))
6215 (set (match_operand:SWI 0 "register_operand")
6216 (plus:SWI (match_dup 1) (match_dup 2)))])
6217 (set (pc) (if_then_else
6218 (ltu (reg:CCC FLAGS_REG) (const_int 0))
6219 (label_ref (match_operand 3))
6222 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6224 ;; The lea patterns for modes less than 32 bits need to be matched by
6225 ;; several insns converted to real lea by splitters.
6227 (define_insn_and_split "*lea<mode>_general_1"
6228 [(set (match_operand:SWI12 0 "register_operand" "=r")
6230 (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6231 (match_operand:SWI12 2 "register_operand" "r"))
6232 (match_operand:SWI12 3 "immediate_operand" "i")))]
6233 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6235 "&& reload_completed"
6238 (plus:SI (match_dup 1) (match_dup 2))
6241 operands[0] = gen_lowpart (SImode, operands[0]);
6242 operands[1] = gen_lowpart (SImode, operands[1]);
6243 operands[2] = gen_lowpart (SImode, operands[2]);
6244 operands[3] = gen_lowpart (SImode, operands[3]);
6246 [(set_attr "type" "lea")
6247 (set_attr "mode" "SI")])
6249 (define_insn_and_split "*lea<mode>_general_2"
6250 [(set (match_operand:SWI12 0 "register_operand" "=r")
6252 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6253 (match_operand 2 "const248_operand" "n"))
6254 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6255 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6257 "&& reload_completed"
6260 (mult:SI (match_dup 1) (match_dup 2))
6263 operands[0] = gen_lowpart (SImode, operands[0]);
6264 operands[1] = gen_lowpart (SImode, operands[1]);
6265 operands[3] = gen_lowpart (SImode, operands[3]);
6267 [(set_attr "type" "lea")
6268 (set_attr "mode" "SI")])
6270 (define_insn_and_split "*lea<mode>_general_3"
6271 [(set (match_operand:SWI12 0 "register_operand" "=r")
6274 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6275 (match_operand 2 "const248_operand" "n"))
6276 (match_operand:SWI12 3 "register_operand" "r"))
6277 (match_operand:SWI12 4 "immediate_operand" "i")))]
6278 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6280 "&& reload_completed"
6284 (mult: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]);
6291 operands[4] = gen_lowpart (SImode, operands[4]);
6293 [(set_attr "type" "lea")
6294 (set_attr "mode" "SI")])
6296 (define_insn_and_split "*lea<mode>_general_4"
6297 [(set (match_operand:SWI12 0 "register_operand" "=r")
6300 (match_operand:SWI12 1 "index_register_operand" "l")
6301 (match_operand 2 "const_0_to_3_operand" "n"))
6302 (match_operand 3 "const_int_operand" "n")))]
6303 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6304 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6305 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6307 "&& reload_completed"
6310 (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[2] = GEN_INT (1 << INTVAL (operands[2]));
6317 [(set_attr "type" "lea")
6318 (set_attr "mode" "SI")])
6320 (define_insn_and_split "*lea<mode>_general_4"
6321 [(set (match_operand:SWI48 0 "register_operand" "=r")
6324 (match_operand:SWI48 1 "index_register_operand" "l")
6325 (match_operand 2 "const_0_to_3_operand" "n"))
6326 (match_operand 3 "const_int_operand" "n")))]
6327 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6328 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6330 "&& reload_completed"
6333 (mult:SWI48 (match_dup 1) (match_dup 2))
6335 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6336 [(set_attr "type" "lea")
6337 (set_attr "mode" "<MODE>")])
6339 ;; Subtract instructions
6341 (define_expand "sub<mode>3"
6342 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6343 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6344 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6346 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6348 (define_insn_and_split "*sub<dwi>3_doubleword"
6349 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6351 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6352 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
6354 (clobber (reg:CC FLAGS_REG))]
6355 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6358 [(parallel [(set (reg:CC FLAGS_REG)
6359 (compare:CC (match_dup 1) (match_dup 2)))
6361 (minus:DWIH (match_dup 1) (match_dup 2)))])
6362 (parallel [(set (match_dup 3)
6366 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6368 (clobber (reg:CC FLAGS_REG))])]
6370 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6371 if (operands[2] == const0_rtx)
6373 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6378 (define_insn "*sub<mode>_1"
6379 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6381 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6382 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6383 (clobber (reg:CC FLAGS_REG))]
6384 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6385 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6386 [(set_attr "type" "alu")
6387 (set_attr "mode" "<MODE>")])
6389 (define_insn "*subsi_1_zext"
6390 [(set (match_operand:DI 0 "register_operand" "=r")
6392 (minus:SI (match_operand:SI 1 "register_operand" "0")
6393 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6394 (clobber (reg:CC FLAGS_REG))]
6395 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6396 "sub{l}\t{%2, %k0|%k0, %2}"
6397 [(set_attr "type" "alu")
6398 (set_attr "mode" "SI")])
6400 (define_insn "*subqi_1_slp"
6401 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6402 (minus:QI (match_dup 0)
6403 (match_operand:QI 1 "general_operand" "qn,qm")))
6404 (clobber (reg:CC FLAGS_REG))]
6405 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6406 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6407 "sub{b}\t{%1, %0|%0, %1}"
6408 [(set_attr "type" "alu1")
6409 (set_attr "mode" "QI")])
6411 (define_insn "*sub<mode>_2"
6412 [(set (reg FLAGS_REG)
6415 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6416 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6418 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6419 (minus:SWI (match_dup 1) (match_dup 2)))]
6420 "ix86_match_ccmode (insn, CCGOCmode)
6421 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6422 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6423 [(set_attr "type" "alu")
6424 (set_attr "mode" "<MODE>")])
6426 (define_insn "*subsi_2_zext"
6427 [(set (reg FLAGS_REG)
6429 (minus:SI (match_operand:SI 1 "register_operand" "0")
6430 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6432 (set (match_operand:DI 0 "register_operand" "=r")
6434 (minus:SI (match_dup 1)
6436 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6437 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6438 "sub{l}\t{%2, %k0|%k0, %2}"
6439 [(set_attr "type" "alu")
6440 (set_attr "mode" "SI")])
6442 ;; Subtract with jump on overflow.
6443 (define_expand "subv<mode>4"
6444 [(parallel [(set (reg:CCO FLAGS_REG)
6445 (eq:CCO (minus:<DWI>
6447 (match_operand:SWI 1 "nonimmediate_operand"))
6450 (minus:SWI (match_dup 1)
6451 (match_operand:SWI 2
6452 "<general_operand>")))))
6453 (set (match_operand:SWI 0 "register_operand")
6454 (minus:SWI (match_dup 1) (match_dup 2)))])
6455 (set (pc) (if_then_else
6456 (eq (reg:CCO FLAGS_REG) (const_int 0))
6457 (label_ref (match_operand 3))
6461 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6462 if (CONST_INT_P (operands[2]))
6463 operands[4] = operands[2];
6465 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6468 (define_insn "*subv<mode>4"
6469 [(set (reg:CCO FLAGS_REG)
6470 (eq:CCO (minus:<DWI>
6472 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6474 (match_operand:SWI 2 "<general_sext_operand>"
6477 (minus:SWI (match_dup 1) (match_dup 2)))))
6478 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6479 (minus:SWI (match_dup 1) (match_dup 2)))]
6480 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6481 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6482 [(set_attr "type" "alu")
6483 (set_attr "mode" "<MODE>")])
6485 (define_insn "*subv<mode>4_1"
6486 [(set (reg:CCO FLAGS_REG)
6487 (eq:CCO (minus:<DWI>
6489 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6490 (match_operand:<DWI> 3 "const_int_operand" "i"))
6492 (minus:SWI (match_dup 1)
6493 (match_operand:SWI 2 "x86_64_immediate_operand"
6495 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6496 (minus:SWI (match_dup 1) (match_dup 2)))]
6497 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6498 && CONST_INT_P (operands[2])
6499 && INTVAL (operands[2]) == INTVAL (operands[3])"
6500 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6501 [(set_attr "type" "alu")
6502 (set_attr "mode" "<MODE>")
6503 (set (attr "length_immediate")
6504 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6506 (match_test "<MODE_SIZE> == 8")
6508 (const_string "<MODE_SIZE>")))])
6510 (define_expand "usubv<mode>4"
6511 [(parallel [(set (reg:CC FLAGS_REG)
6513 (match_operand:SWI 1 "nonimmediate_operand")
6514 (match_operand:SWI 2 "<general_operand>")))
6515 (set (match_operand:SWI 0 "register_operand")
6516 (minus:SWI (match_dup 1) (match_dup 2)))])
6517 (set (pc) (if_then_else
6518 (ltu (reg:CC FLAGS_REG) (const_int 0))
6519 (label_ref (match_operand 3))
6522 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6524 (define_insn "*sub<mode>_3"
6525 [(set (reg FLAGS_REG)
6526 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6527 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6528 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6529 (minus:SWI (match_dup 1) (match_dup 2)))]
6530 "ix86_match_ccmode (insn, CCmode)
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 "*subsi_3_zext"
6537 [(set (reg FLAGS_REG)
6538 (compare (match_operand:SI 1 "register_operand" "0")
6539 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6540 (set (match_operand:DI 0 "register_operand" "=r")
6542 (minus:SI (match_dup 1)
6544 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6545 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6546 "sub{l}\t{%2, %1|%1, %2}"
6547 [(set_attr "type" "alu")
6548 (set_attr "mode" "SI")])
6550 ;; Add with carry and subtract with borrow
6552 (define_insn "add<mode>3_carry"
6553 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6556 (match_operator:SWI 4 "ix86_carry_flag_operator"
6557 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6558 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6559 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6560 (clobber (reg:CC FLAGS_REG))]
6561 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6562 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6563 [(set_attr "type" "alu")
6564 (set_attr "use_carry" "1")
6565 (set_attr "pent_pair" "pu")
6566 (set_attr "mode" "<MODE>")])
6568 (define_insn "*addsi3_carry_zext"
6569 [(set (match_operand:DI 0 "register_operand" "=r")
6572 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6573 [(reg FLAGS_REG) (const_int 0)])
6574 (match_operand:SI 1 "register_operand" "%0"))
6575 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6576 (clobber (reg:CC FLAGS_REG))]
6577 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6578 "adc{l}\t{%2, %k0|%k0, %2}"
6579 [(set_attr "type" "alu")
6580 (set_attr "use_carry" "1")
6581 (set_attr "pent_pair" "pu")
6582 (set_attr "mode" "SI")])
6584 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6586 (define_insn "addcarry<mode>"
6587 [(set (reg:CCC FLAGS_REG)
6591 (match_operator:SWI48 4 "ix86_carry_flag_operator"
6592 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6593 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6594 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))
6596 (set (match_operand:SWI48 0 "register_operand" "=r")
6597 (plus:SWI48 (plus:SWI48 (match_op_dup 4
6598 [(match_dup 3) (const_int 0)])
6601 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6602 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6603 [(set_attr "type" "alu")
6604 (set_attr "use_carry" "1")
6605 (set_attr "pent_pair" "pu")
6606 (set_attr "mode" "<MODE>")])
6608 (define_insn "sub<mode>3_carry"
6609 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6612 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6613 (match_operator:SWI 4 "ix86_carry_flag_operator"
6614 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6615 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6616 (clobber (reg:CC FLAGS_REG))]
6617 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6618 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6619 [(set_attr "type" "alu")
6620 (set_attr "use_carry" "1")
6621 (set_attr "pent_pair" "pu")
6622 (set_attr "mode" "<MODE>")])
6624 (define_insn "*subsi3_carry_zext"
6625 [(set (match_operand:DI 0 "register_operand" "=r")
6629 (match_operand:SI 1 "register_operand" "0")
6630 (match_operator:SI 3 "ix86_carry_flag_operator"
6631 [(reg FLAGS_REG) (const_int 0)]))
6632 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6633 (clobber (reg:CC FLAGS_REG))]
6634 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6635 "sbb{l}\t{%2, %k0|%k0, %2}"
6636 [(set_attr "type" "alu")
6637 (set_attr "use_carry" "1")
6638 (set_attr "pent_pair" "pu")
6639 (set_attr "mode" "SI")])
6641 (define_insn "subborrow<mode>"
6642 [(set (reg:CCC FLAGS_REG)
6644 (match_operand:SWI48 1 "nonimmediate_operand" "0")
6646 (match_operator:SWI48 4 "ix86_carry_flag_operator"
6647 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6648 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
6649 (set (match_operand:SWI48 0 "register_operand" "=r")
6650 (minus:SWI48 (minus:SWI48 (match_dup 1)
6652 [(match_dup 3) (const_int 0)]))
6654 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6655 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6656 [(set_attr "type" "alu")
6657 (set_attr "use_carry" "1")
6658 (set_attr "pent_pair" "pu")
6659 (set_attr "mode" "<MODE>")])
6661 ;; Overflow setting add instructions
6663 (define_expand "addqi3_cconly_overflow"
6665 [(set (reg:CCC FLAGS_REG)
6668 (match_operand:QI 0 "nonimmediate_operand")
6669 (match_operand:QI 1 "general_operand"))
6671 (clobber (match_scratch:QI 2))])]
6672 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
6674 (define_insn "*add<mode>3_cconly_overflow_1"
6675 [(set (reg:CCC FLAGS_REG)
6678 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6679 (match_operand:SWI 2 "<general_operand>" "<g>"))
6681 (clobber (match_scratch:SWI 0 "=<r>"))]
6682 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6683 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6684 [(set_attr "type" "alu")
6685 (set_attr "mode" "<MODE>")])
6687 (define_insn "*add<mode>3_cconly_overflow_2"
6688 [(set (reg:CCC FLAGS_REG)
6691 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6692 (match_operand:SWI 2 "<general_operand>" "<g>"))
6694 (clobber (match_scratch:SWI 0 "=<r>"))]
6695 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6696 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6697 [(set_attr "type" "alu")
6698 (set_attr "mode" "<MODE>")])
6700 (define_insn "*add<mode>3_cc_overflow_1"
6701 [(set (reg:CCC FLAGS_REG)
6704 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6705 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6707 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6708 (plus:SWI (match_dup 1) (match_dup 2)))]
6709 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6710 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6711 [(set_attr "type" "alu")
6712 (set_attr "mode" "<MODE>")])
6714 (define_insn "*add<mode>3_cc_overflow_2"
6715 [(set (reg:CCC FLAGS_REG)
6718 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6719 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6721 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6722 (plus:SWI (match_dup 1) (match_dup 2)))]
6723 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6724 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6725 [(set_attr "type" "alu")
6726 (set_attr "mode" "<MODE>")])
6728 (define_insn "*addsi3_zext_cc_overflow_1"
6729 [(set (reg:CCC FLAGS_REG)
6732 (match_operand:SI 1 "nonimmediate_operand" "%0")
6733 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6735 (set (match_operand:DI 0 "register_operand" "=r")
6736 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6737 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6738 "add{l}\t{%2, %k0|%k0, %2}"
6739 [(set_attr "type" "alu")
6740 (set_attr "mode" "SI")])
6742 (define_insn "*addsi3_zext_cc_overflow_2"
6743 [(set (reg:CCC FLAGS_REG)
6746 (match_operand:SI 1 "nonimmediate_operand" "%0")
6747 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6749 (set (match_operand:DI 0 "register_operand" "=r")
6750 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6751 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6752 "add{l}\t{%2, %k0|%k0, %2}"
6753 [(set_attr "type" "alu")
6754 (set_attr "mode" "SI")])
6756 ;; The patterns that match these are at the end of this file.
6758 (define_expand "<plusminus_insn>xf3"
6759 [(set (match_operand:XF 0 "register_operand")
6761 (match_operand:XF 1 "register_operand")
6762 (match_operand:XF 2 "register_operand")))]
6765 (define_expand "<plusminus_insn><mode>3"
6766 [(set (match_operand:MODEF 0 "register_operand")
6768 (match_operand:MODEF 1 "register_operand")
6769 (match_operand:MODEF 2 "nonimmediate_operand")))]
6770 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6771 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6773 ;; Multiply instructions
6775 (define_expand "mul<mode>3"
6776 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6778 (match_operand:SWIM248 1 "register_operand")
6779 (match_operand:SWIM248 2 "<general_operand>")))
6780 (clobber (reg:CC FLAGS_REG))])])
6782 (define_expand "mulqi3"
6783 [(parallel [(set (match_operand:QI 0 "register_operand")
6785 (match_operand:QI 1 "register_operand")
6786 (match_operand:QI 2 "nonimmediate_operand")))
6787 (clobber (reg:CC FLAGS_REG))])]
6788 "TARGET_QIMODE_MATH")
6791 ;; IMUL reg32/64, reg32/64, imm8 Direct
6792 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6793 ;; IMUL reg32/64, reg32/64, imm32 Direct
6794 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6795 ;; IMUL reg32/64, reg32/64 Direct
6796 ;; IMUL reg32/64, mem32/64 Direct
6798 ;; On BDVER1, all above IMULs use DirectPath
6801 ;; IMUL reg16, reg16, imm8 VectorPath
6802 ;; IMUL reg16, mem16, imm8 VectorPath
6803 ;; IMUL reg16, reg16, imm16 VectorPath
6804 ;; IMUL reg16, mem16, imm16 VectorPath
6805 ;; IMUL reg16, reg16 Direct
6806 ;; IMUL reg16, mem16 Direct
6808 ;; On BDVER1, all HI MULs use DoublePath
6810 (define_insn "*mul<mode>3_1"
6811 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
6813 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
6814 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
6815 (clobber (reg:CC FLAGS_REG))]
6816 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6818 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6819 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6820 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6821 [(set_attr "type" "imul")
6822 (set_attr "prefix_0f" "0,0,1")
6823 (set (attr "athlon_decode")
6824 (cond [(eq_attr "cpu" "athlon")
6825 (const_string "vector")
6826 (eq_attr "alternative" "1")
6827 (const_string "vector")
6828 (and (eq_attr "alternative" "2")
6829 (ior (match_test "<MODE>mode == HImode")
6830 (match_operand 1 "memory_operand")))
6831 (const_string "vector")]
6832 (const_string "direct")))
6833 (set (attr "amdfam10_decode")
6834 (cond [(and (eq_attr "alternative" "0,1")
6835 (ior (match_test "<MODE>mode == HImode")
6836 (match_operand 1 "memory_operand")))
6837 (const_string "vector")]
6838 (const_string "direct")))
6839 (set (attr "bdver1_decode")
6841 (match_test "<MODE>mode == HImode")
6842 (const_string "double")
6843 (const_string "direct")))
6844 (set_attr "mode" "<MODE>")])
6846 (define_insn "*mulsi3_1_zext"
6847 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6849 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6850 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6851 (clobber (reg:CC FLAGS_REG))]
6853 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6855 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6856 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6857 imul{l}\t{%2, %k0|%k0, %2}"
6858 [(set_attr "type" "imul")
6859 (set_attr "prefix_0f" "0,0,1")
6860 (set (attr "athlon_decode")
6861 (cond [(eq_attr "cpu" "athlon")
6862 (const_string "vector")
6863 (eq_attr "alternative" "1")
6864 (const_string "vector")
6865 (and (eq_attr "alternative" "2")
6866 (match_operand 1 "memory_operand"))
6867 (const_string "vector")]
6868 (const_string "direct")))
6869 (set (attr "amdfam10_decode")
6870 (cond [(and (eq_attr "alternative" "0,1")
6871 (match_operand 1 "memory_operand"))
6872 (const_string "vector")]
6873 (const_string "direct")))
6874 (set_attr "bdver1_decode" "direct")
6875 (set_attr "mode" "SI")])
6877 ;;On AMDFAM10 and BDVER1
6881 (define_insn "*mulqi3_1"
6882 [(set (match_operand:QI 0 "register_operand" "=a")
6883 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6884 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6885 (clobber (reg:CC FLAGS_REG))]
6887 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6889 [(set_attr "type" "imul")
6890 (set_attr "length_immediate" "0")
6891 (set (attr "athlon_decode")
6892 (if_then_else (eq_attr "cpu" "athlon")
6893 (const_string "vector")
6894 (const_string "direct")))
6895 (set_attr "amdfam10_decode" "direct")
6896 (set_attr "bdver1_decode" "direct")
6897 (set_attr "mode" "QI")])
6899 ;; Multiply with jump on overflow.
6900 (define_expand "mulv<mode>4"
6901 [(parallel [(set (reg:CCO FLAGS_REG)
6904 (match_operand:SWI248 1 "register_operand"))
6907 (mult:SWI248 (match_dup 1)
6908 (match_operand:SWI248 2
6909 "<general_operand>")))))
6910 (set (match_operand:SWI248 0 "register_operand")
6911 (mult:SWI248 (match_dup 1) (match_dup 2)))])
6912 (set (pc) (if_then_else
6913 (eq (reg:CCO FLAGS_REG) (const_int 0))
6914 (label_ref (match_operand 3))
6918 if (CONST_INT_P (operands[2]))
6919 operands[4] = operands[2];
6921 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6924 (define_insn "*mulv<mode>4"
6925 [(set (reg:CCO FLAGS_REG)
6928 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6930 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
6932 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6933 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6934 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6935 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6937 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6938 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6939 [(set_attr "type" "imul")
6940 (set_attr "prefix_0f" "0,1")
6941 (set (attr "athlon_decode")
6942 (cond [(eq_attr "cpu" "athlon")
6943 (const_string "vector")
6944 (eq_attr "alternative" "0")
6945 (const_string "vector")
6946 (and (eq_attr "alternative" "1")
6947 (match_operand 1 "memory_operand"))
6948 (const_string "vector")]
6949 (const_string "direct")))
6950 (set (attr "amdfam10_decode")
6951 (cond [(and (eq_attr "alternative" "1")
6952 (match_operand 1 "memory_operand"))
6953 (const_string "vector")]
6954 (const_string "direct")))
6955 (set_attr "bdver1_decode" "direct")
6956 (set_attr "mode" "<MODE>")])
6958 (define_insn "*mulvhi4"
6959 [(set (reg:CCO FLAGS_REG)
6962 (match_operand:HI 1 "nonimmediate_operand" "%0"))
6964 (match_operand:HI 2 "nonimmediate_operand" "mr")))
6966 (mult:HI (match_dup 1) (match_dup 2)))))
6967 (set (match_operand:HI 0 "register_operand" "=r")
6968 (mult:HI (match_dup 1) (match_dup 2)))]
6969 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6970 "imul{w}\t{%2, %0|%0, %2}"
6971 [(set_attr "type" "imul")
6972 (set_attr "prefix_0f" "1")
6973 (set_attr "athlon_decode" "vector")
6974 (set_attr "amdfam10_decode" "direct")
6975 (set_attr "bdver1_decode" "double")
6976 (set_attr "mode" "HI")])
6978 (define_insn "*mulv<mode>4_1"
6979 [(set (reg:CCO FLAGS_REG)
6982 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
6983 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
6985 (mult:SWI248 (match_dup 1)
6986 (match_operand:SWI248 2
6987 "<immediate_operand>" "K,<i>")))))
6988 (set (match_operand:SWI248 0 "register_operand" "=r,r")
6989 (mult:SWI248 (match_dup 1) (match_dup 2)))]
6990 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
6991 && CONST_INT_P (operands[2])
6992 && INTVAL (operands[2]) == INTVAL (operands[3])"
6993 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6994 [(set_attr "type" "imul")
6995 (set (attr "prefix_0f")
6997 (match_test "<MODE>mode == HImode")
6999 (const_string "*")))
7000 (set (attr "athlon_decode")
7001 (cond [(eq_attr "cpu" "athlon")
7002 (const_string "vector")
7003 (eq_attr "alternative" "1")
7004 (const_string "vector")]
7005 (const_string "direct")))
7006 (set (attr "amdfam10_decode")
7007 (cond [(ior (match_test "<MODE>mode == HImode")
7008 (match_operand 1 "memory_operand"))
7009 (const_string "vector")]
7010 (const_string "direct")))
7011 (set (attr "bdver1_decode")
7013 (match_test "<MODE>mode == HImode")
7014 (const_string "double")
7015 (const_string "direct")))
7016 (set_attr "mode" "<MODE>")
7017 (set (attr "length_immediate")
7018 (cond [(eq_attr "alternative" "0")
7020 (match_test "<MODE_SIZE> == 8")
7022 (const_string "<MODE_SIZE>")))])
7024 (define_expand "umulv<mode>4"
7025 [(parallel [(set (reg:CCO FLAGS_REG)
7028 (match_operand:SWI248 1
7029 "nonimmediate_operand"))
7031 (match_operand:SWI248 2
7032 "nonimmediate_operand")))
7034 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7035 (set (match_operand:SWI248 0 "register_operand")
7036 (mult:SWI248 (match_dup 1) (match_dup 2)))
7037 (clobber (match_scratch:SWI248 4))])
7038 (set (pc) (if_then_else
7039 (eq (reg:CCO FLAGS_REG) (const_int 0))
7040 (label_ref (match_operand 3))
7044 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7045 operands[1] = force_reg (<MODE>mode, operands[1]);
7048 (define_insn "*umulv<mode>4"
7049 [(set (reg:CCO FLAGS_REG)
7052 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7054 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7056 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7057 (set (match_operand:SWI248 0 "register_operand" "=a")
7058 (mult:SWI248 (match_dup 1) (match_dup 2)))
7059 (clobber (match_scratch:SWI248 3 "=d"))]
7060 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7061 "mul{<imodesuffix>}\t%2"
7062 [(set_attr "type" "imul")
7063 (set_attr "length_immediate" "0")
7064 (set (attr "athlon_decode")
7065 (if_then_else (eq_attr "cpu" "athlon")
7066 (const_string "vector")
7067 (const_string "double")))
7068 (set_attr "amdfam10_decode" "double")
7069 (set_attr "bdver1_decode" "direct")
7070 (set_attr "mode" "<MODE>")])
7072 (define_expand "<u>mulvqi4"
7073 [(parallel [(set (reg:CCO FLAGS_REG)
7076 (match_operand:QI 1 "nonimmediate_operand"))
7078 (match_operand:QI 2 "nonimmediate_operand")))
7080 (mult:QI (match_dup 1) (match_dup 2)))))
7081 (set (match_operand:QI 0 "register_operand")
7082 (mult:QI (match_dup 1) (match_dup 2)))])
7083 (set (pc) (if_then_else
7084 (eq (reg:CCO FLAGS_REG) (const_int 0))
7085 (label_ref (match_operand 3))
7087 "TARGET_QIMODE_MATH"
7089 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7090 operands[1] = force_reg (QImode, operands[1]);
7093 (define_insn "*<u>mulvqi4"
7094 [(set (reg:CCO FLAGS_REG)
7097 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7099 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7101 (mult:QI (match_dup 1) (match_dup 2)))))
7102 (set (match_operand:QI 0 "register_operand" "=a")
7103 (mult:QI (match_dup 1) (match_dup 2)))]
7105 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7106 "<sgnprefix>mul{b}\t%2"
7107 [(set_attr "type" "imul")
7108 (set_attr "length_immediate" "0")
7109 (set (attr "athlon_decode")
7110 (if_then_else (eq_attr "cpu" "athlon")
7111 (const_string "vector")
7112 (const_string "direct")))
7113 (set_attr "amdfam10_decode" "direct")
7114 (set_attr "bdver1_decode" "direct")
7115 (set_attr "mode" "QI")])
7117 (define_expand "<u>mul<mode><dwi>3"
7118 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7121 (match_operand:DWIH 1 "nonimmediate_operand"))
7123 (match_operand:DWIH 2 "register_operand"))))
7124 (clobber (reg:CC FLAGS_REG))])])
7126 (define_expand "<u>mulqihi3"
7127 [(parallel [(set (match_operand:HI 0 "register_operand")
7130 (match_operand:QI 1 "nonimmediate_operand"))
7132 (match_operand:QI 2 "register_operand"))))
7133 (clobber (reg:CC FLAGS_REG))])]
7134 "TARGET_QIMODE_MATH")
7136 (define_insn "*bmi2_umul<mode><dwi>3_1"
7137 [(set (match_operand:DWIH 0 "register_operand" "=r")
7139 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7140 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7141 (set (match_operand:DWIH 1 "register_operand" "=r")
7144 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7145 (zero_extend:<DWI> (match_dup 3)))
7146 (match_operand:QI 4 "const_int_operand" "n"))))]
7147 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7148 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7149 "mulx\t{%3, %0, %1|%1, %0, %3}"
7150 [(set_attr "type" "imulx")
7151 (set_attr "prefix" "vex")
7152 (set_attr "mode" "<MODE>")])
7154 (define_insn "*umul<mode><dwi>3_1"
7155 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7158 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7160 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7161 (clobber (reg:CC FLAGS_REG))]
7162 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7165 mul{<imodesuffix>}\t%2"
7166 [(set_attr "isa" "bmi2,*")
7167 (set_attr "type" "imulx,imul")
7168 (set_attr "length_immediate" "*,0")
7169 (set (attr "athlon_decode")
7170 (cond [(eq_attr "alternative" "1")
7171 (if_then_else (eq_attr "cpu" "athlon")
7172 (const_string "vector")
7173 (const_string "double"))]
7174 (const_string "*")))
7175 (set_attr "amdfam10_decode" "*,double")
7176 (set_attr "bdver1_decode" "*,direct")
7177 (set_attr "prefix" "vex,orig")
7178 (set_attr "mode" "<MODE>")])
7180 ;; Convert mul to the mulx pattern to avoid flags dependency.
7182 [(set (match_operand:<DWI> 0 "register_operand")
7185 (match_operand:DWIH 1 "register_operand"))
7187 (match_operand:DWIH 2 "nonimmediate_operand"))))
7188 (clobber (reg:CC FLAGS_REG))]
7189 "TARGET_BMI2 && reload_completed
7190 && REGNO (operands[1]) == DX_REG"
7191 [(parallel [(set (match_dup 3)
7192 (mult:DWIH (match_dup 1) (match_dup 2)))
7196 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7197 (zero_extend:<DWI> (match_dup 2)))
7200 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7202 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7205 (define_insn "*mul<mode><dwi>3_1"
7206 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7209 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7211 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7212 (clobber (reg:CC FLAGS_REG))]
7213 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7214 "imul{<imodesuffix>}\t%2"
7215 [(set_attr "type" "imul")
7216 (set_attr "length_immediate" "0")
7217 (set (attr "athlon_decode")
7218 (if_then_else (eq_attr "cpu" "athlon")
7219 (const_string "vector")
7220 (const_string "double")))
7221 (set_attr "amdfam10_decode" "double")
7222 (set_attr "bdver1_decode" "direct")
7223 (set_attr "mode" "<MODE>")])
7225 (define_insn "*<u>mulqihi3_1"
7226 [(set (match_operand:HI 0 "register_operand" "=a")
7229 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7231 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7232 (clobber (reg:CC FLAGS_REG))]
7234 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7235 "<sgnprefix>mul{b}\t%2"
7236 [(set_attr "type" "imul")
7237 (set_attr "length_immediate" "0")
7238 (set (attr "athlon_decode")
7239 (if_then_else (eq_attr "cpu" "athlon")
7240 (const_string "vector")
7241 (const_string "direct")))
7242 (set_attr "amdfam10_decode" "direct")
7243 (set_attr "bdver1_decode" "direct")
7244 (set_attr "mode" "QI")])
7246 (define_expand "<s>mul<mode>3_highpart"
7247 [(parallel [(set (match_operand:SWI48 0 "register_operand")
7252 (match_operand:SWI48 1 "nonimmediate_operand"))
7254 (match_operand:SWI48 2 "register_operand")))
7256 (clobber (match_scratch:SWI48 3))
7257 (clobber (reg:CC FLAGS_REG))])]
7259 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7261 (define_insn "*<s>muldi3_highpart_1"
7262 [(set (match_operand:DI 0 "register_operand" "=d")
7267 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7269 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7271 (clobber (match_scratch:DI 3 "=1"))
7272 (clobber (reg:CC FLAGS_REG))]
7274 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7275 "<sgnprefix>mul{q}\t%2"
7276 [(set_attr "type" "imul")
7277 (set_attr "length_immediate" "0")
7278 (set (attr "athlon_decode")
7279 (if_then_else (eq_attr "cpu" "athlon")
7280 (const_string "vector")
7281 (const_string "double")))
7282 (set_attr "amdfam10_decode" "double")
7283 (set_attr "bdver1_decode" "direct")
7284 (set_attr "mode" "DI")])
7286 (define_insn "*<s>mulsi3_highpart_1"
7287 [(set (match_operand:SI 0 "register_operand" "=d")
7292 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7294 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7296 (clobber (match_scratch:SI 3 "=1"))
7297 (clobber (reg:CC FLAGS_REG))]
7298 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7299 "<sgnprefix>mul{l}\t%2"
7300 [(set_attr "type" "imul")
7301 (set_attr "length_immediate" "0")
7302 (set (attr "athlon_decode")
7303 (if_then_else (eq_attr "cpu" "athlon")
7304 (const_string "vector")
7305 (const_string "double")))
7306 (set_attr "amdfam10_decode" "double")
7307 (set_attr "bdver1_decode" "direct")
7308 (set_attr "mode" "SI")])
7310 (define_insn "*<s>mulsi3_highpart_zext"
7311 [(set (match_operand:DI 0 "register_operand" "=d")
7312 (zero_extend:DI (truncate:SI
7314 (mult:DI (any_extend:DI
7315 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7317 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7319 (clobber (match_scratch:SI 3 "=1"))
7320 (clobber (reg:CC FLAGS_REG))]
7322 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7323 "<sgnprefix>mul{l}\t%2"
7324 [(set_attr "type" "imul")
7325 (set_attr "length_immediate" "0")
7326 (set (attr "athlon_decode")
7327 (if_then_else (eq_attr "cpu" "athlon")
7328 (const_string "vector")
7329 (const_string "double")))
7330 (set_attr "amdfam10_decode" "double")
7331 (set_attr "bdver1_decode" "direct")
7332 (set_attr "mode" "SI")])
7334 ;; The patterns that match these are at the end of this file.
7336 (define_expand "mulxf3"
7337 [(set (match_operand:XF 0 "register_operand")
7338 (mult:XF (match_operand:XF 1 "register_operand")
7339 (match_operand:XF 2 "register_operand")))]
7342 (define_expand "mul<mode>3"
7343 [(set (match_operand:MODEF 0 "register_operand")
7344 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7345 (match_operand:MODEF 2 "nonimmediate_operand")))]
7346 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7347 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7349 ;; Divide instructions
7351 ;; The patterns that match these are at the end of this file.
7353 (define_expand "divxf3"
7354 [(set (match_operand:XF 0 "register_operand")
7355 (div:XF (match_operand:XF 1 "register_operand")
7356 (match_operand:XF 2 "register_operand")))]
7359 (define_expand "divdf3"
7360 [(set (match_operand:DF 0 "register_operand")
7361 (div:DF (match_operand:DF 1 "register_operand")
7362 (match_operand:DF 2 "nonimmediate_operand")))]
7363 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7364 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7366 (define_expand "divsf3"
7367 [(set (match_operand:SF 0 "register_operand")
7368 (div:SF (match_operand:SF 1 "register_operand")
7369 (match_operand:SF 2 "nonimmediate_operand")))]
7370 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7375 && optimize_insn_for_speed_p ()
7376 && flag_finite_math_only && !flag_trapping_math
7377 && flag_unsafe_math_optimizations)
7379 ix86_emit_swdivsf (operands[0], operands[1],
7380 operands[2], SFmode);
7385 ;; Divmod instructions.
7387 (define_expand "divmod<mode>4"
7388 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7390 (match_operand:SWIM248 1 "register_operand")
7391 (match_operand:SWIM248 2 "nonimmediate_operand")))
7392 (set (match_operand:SWIM248 3 "register_operand")
7393 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7394 (clobber (reg:CC FLAGS_REG))])])
7396 ;; Split with 8bit unsigned divide:
7397 ;; if (dividend an divisor are in [0-255])
7398 ;; use 8bit unsigned integer divide
7400 ;; use original integer divide
7402 [(set (match_operand:SWI48 0 "register_operand")
7403 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7404 (match_operand:SWI48 3 "nonimmediate_operand")))
7405 (set (match_operand:SWI48 1 "register_operand")
7406 (mod:SWI48 (match_dup 2) (match_dup 3)))
7407 (clobber (reg:CC FLAGS_REG))]
7408 "TARGET_USE_8BIT_IDIV
7409 && TARGET_QIMODE_MATH
7410 && can_create_pseudo_p ()
7411 && !optimize_insn_for_size_p ()"
7413 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7415 (define_insn_and_split "divmod<mode>4_1"
7416 [(set (match_operand:SWI48 0 "register_operand" "=a")
7417 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7418 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7419 (set (match_operand:SWI48 1 "register_operand" "=&d")
7420 (mod:SWI48 (match_dup 2) (match_dup 3)))
7421 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7422 (clobber (reg:CC FLAGS_REG))]
7426 [(parallel [(set (match_dup 1)
7427 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7428 (clobber (reg:CC FLAGS_REG))])
7429 (parallel [(set (match_dup 0)
7430 (div:SWI48 (match_dup 2) (match_dup 3)))
7432 (mod:SWI48 (match_dup 2) (match_dup 3)))
7434 (clobber (reg:CC FLAGS_REG))])]
7436 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7438 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7439 operands[4] = operands[2];
7442 /* Avoid use of cltd in favor of a mov+shift. */
7443 emit_move_insn (operands[1], operands[2]);
7444 operands[4] = operands[1];
7447 [(set_attr "type" "multi")
7448 (set_attr "mode" "<MODE>")])
7450 (define_insn_and_split "*divmod<mode>4"
7451 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7452 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7453 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7454 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7455 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7456 (clobber (reg:CC FLAGS_REG))]
7460 [(parallel [(set (match_dup 1)
7461 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7462 (clobber (reg:CC FLAGS_REG))])
7463 (parallel [(set (match_dup 0)
7464 (div:SWIM248 (match_dup 2) (match_dup 3)))
7466 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7468 (clobber (reg:CC FLAGS_REG))])]
7470 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7472 if (<MODE>mode != HImode
7473 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7474 operands[4] = operands[2];
7477 /* Avoid use of cltd in favor of a mov+shift. */
7478 emit_move_insn (operands[1], operands[2]);
7479 operands[4] = operands[1];
7482 [(set_attr "type" "multi")
7483 (set_attr "mode" "<MODE>")])
7485 (define_insn "*divmod<mode>4_noext"
7486 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7487 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7488 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7489 (set (match_operand:SWIM248 1 "register_operand" "=d")
7490 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7491 (use (match_operand:SWIM248 4 "register_operand" "1"))
7492 (clobber (reg:CC FLAGS_REG))]
7494 "idiv{<imodesuffix>}\t%3"
7495 [(set_attr "type" "idiv")
7496 (set_attr "mode" "<MODE>")])
7498 (define_expand "divmodqi4"
7499 [(parallel [(set (match_operand:QI 0 "register_operand")
7501 (match_operand:QI 1 "register_operand")
7502 (match_operand:QI 2 "nonimmediate_operand")))
7503 (set (match_operand:QI 3 "register_operand")
7504 (mod:QI (match_dup 1) (match_dup 2)))
7505 (clobber (reg:CC FLAGS_REG))])]
7506 "TARGET_QIMODE_MATH"
7511 tmp0 = gen_reg_rtx (HImode);
7512 tmp1 = gen_reg_rtx (HImode);
7514 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7516 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7517 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7519 /* Extract remainder from AH. */
7520 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7521 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7523 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7524 set_unique_reg_note (insn, REG_EQUAL, mod);
7526 /* Extract quotient from AL. */
7527 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7529 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7530 set_unique_reg_note (insn, REG_EQUAL, div);
7535 ;; Divide AX by r/m8, with result stored in
7538 ;; Change div/mod to HImode and extend the second argument to HImode
7539 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7540 ;; combine may fail.
7541 (define_insn "divmodhiqi3"
7542 [(set (match_operand:HI 0 "register_operand" "=a")
7547 (mod:HI (match_operand:HI 1 "register_operand" "0")
7549 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7553 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7554 (clobber (reg:CC FLAGS_REG))]
7555 "TARGET_QIMODE_MATH"
7557 [(set_attr "type" "idiv")
7558 (set_attr "mode" "QI")])
7560 (define_expand "udivmod<mode>4"
7561 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7563 (match_operand:SWIM248 1 "register_operand")
7564 (match_operand:SWIM248 2 "nonimmediate_operand")))
7565 (set (match_operand:SWIM248 3 "register_operand")
7566 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7567 (clobber (reg:CC FLAGS_REG))])])
7569 ;; Split with 8bit unsigned divide:
7570 ;; if (dividend an divisor are in [0-255])
7571 ;; use 8bit unsigned integer divide
7573 ;; use original integer divide
7575 [(set (match_operand:SWI48 0 "register_operand")
7576 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7577 (match_operand:SWI48 3 "nonimmediate_operand")))
7578 (set (match_operand:SWI48 1 "register_operand")
7579 (umod:SWI48 (match_dup 2) (match_dup 3)))
7580 (clobber (reg:CC FLAGS_REG))]
7581 "TARGET_USE_8BIT_IDIV
7582 && TARGET_QIMODE_MATH
7583 && can_create_pseudo_p ()
7584 && !optimize_insn_for_size_p ()"
7586 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7588 (define_insn_and_split "udivmod<mode>4_1"
7589 [(set (match_operand:SWI48 0 "register_operand" "=a")
7590 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7591 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7592 (set (match_operand:SWI48 1 "register_operand" "=&d")
7593 (umod:SWI48 (match_dup 2) (match_dup 3)))
7594 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7595 (clobber (reg:CC FLAGS_REG))]
7599 [(set (match_dup 1) (const_int 0))
7600 (parallel [(set (match_dup 0)
7601 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7603 (umod:SWI48 (match_dup 2) (match_dup 3)))
7605 (clobber (reg:CC FLAGS_REG))])]
7607 [(set_attr "type" "multi")
7608 (set_attr "mode" "<MODE>")])
7610 (define_insn_and_split "*udivmod<mode>4"
7611 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7612 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7613 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7614 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7615 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7616 (clobber (reg:CC FLAGS_REG))]
7620 [(set (match_dup 1) (const_int 0))
7621 (parallel [(set (match_dup 0)
7622 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7624 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7626 (clobber (reg:CC FLAGS_REG))])]
7628 [(set_attr "type" "multi")
7629 (set_attr "mode" "<MODE>")])
7631 ;; Optimize division or modulo by constant power of 2, if the constant
7632 ;; materializes only after expansion.
7633 (define_insn_and_split "*udivmod<mode>4_pow2"
7634 [(set (match_operand:SWI48 0 "register_operand" "=r")
7635 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7636 (match_operand:SWI48 3 "const_int_operand" "n")))
7637 (set (match_operand:SWI48 1 "register_operand" "=r")
7638 (umod:SWI48 (match_dup 2) (match_dup 3)))
7639 (clobber (reg:CC FLAGS_REG))]
7640 "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
7641 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
7644 [(set (match_dup 1) (match_dup 2))
7645 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7646 (clobber (reg:CC FLAGS_REG))])
7647 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7648 (clobber (reg:CC FLAGS_REG))])]
7650 int v = exact_log2 (UINTVAL (operands[3]));
7651 operands[4] = GEN_INT (v);
7652 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7654 [(set_attr "type" "multi")
7655 (set_attr "mode" "<MODE>")])
7657 (define_insn "*udivmod<mode>4_noext"
7658 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7659 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7660 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7661 (set (match_operand:SWIM248 1 "register_operand" "=d")
7662 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7663 (use (match_operand:SWIM248 4 "register_operand" "1"))
7664 (clobber (reg:CC FLAGS_REG))]
7666 "div{<imodesuffix>}\t%3"
7667 [(set_attr "type" "idiv")
7668 (set_attr "mode" "<MODE>")])
7670 (define_expand "udivmodqi4"
7671 [(parallel [(set (match_operand:QI 0 "register_operand")
7673 (match_operand:QI 1 "register_operand")
7674 (match_operand:QI 2 "nonimmediate_operand")))
7675 (set (match_operand:QI 3 "register_operand")
7676 (umod:QI (match_dup 1) (match_dup 2)))
7677 (clobber (reg:CC FLAGS_REG))])]
7678 "TARGET_QIMODE_MATH"
7683 tmp0 = gen_reg_rtx (HImode);
7684 tmp1 = gen_reg_rtx (HImode);
7686 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
7687 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7688 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7690 /* Extract remainder from AH. */
7691 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7692 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
7693 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7695 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7696 set_unique_reg_note (insn, REG_EQUAL, mod);
7698 /* Extract quotient from AL. */
7699 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7701 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7702 set_unique_reg_note (insn, REG_EQUAL, div);
7707 (define_insn "udivmodhiqi3"
7708 [(set (match_operand:HI 0 "register_operand" "=a")
7713 (mod:HI (match_operand:HI 1 "register_operand" "0")
7715 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7719 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7720 (clobber (reg:CC FLAGS_REG))]
7721 "TARGET_QIMODE_MATH"
7723 [(set_attr "type" "idiv")
7724 (set_attr "mode" "QI")])
7726 ;; We cannot use div/idiv for double division, because it causes
7727 ;; "division by zero" on the overflow and that's not what we expect
7728 ;; from truncate. Because true (non truncating) double division is
7729 ;; never generated, we can't create this insn anyway.
7732 ; [(set (match_operand:SI 0 "register_operand" "=a")
7734 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7736 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7737 ; (set (match_operand:SI 3 "register_operand" "=d")
7739 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7740 ; (clobber (reg:CC FLAGS_REG))]
7742 ; "div{l}\t{%2, %0|%0, %2}"
7743 ; [(set_attr "type" "idiv")])
7745 ;;- Logical AND instructions
7747 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7748 ;; Note that this excludes ah.
7750 (define_expand "testsi_ccno_1"
7751 [(set (reg:CCNO FLAGS_REG)
7753 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7754 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7757 (define_expand "testqi_ccz_1"
7758 [(set (reg:CCZ FLAGS_REG)
7759 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7760 (match_operand:QI 1 "nonmemory_operand"))
7763 (define_expand "testdi_ccno_1"
7764 [(set (reg:CCNO FLAGS_REG)
7766 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7767 (match_operand:DI 1 "x86_64_szext_general_operand"))
7769 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7771 (define_insn "*testdi_1"
7772 [(set (reg FLAGS_REG)
7775 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7776 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7778 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7779 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7781 test{l}\t{%k1, %k0|%k0, %k1}
7782 test{l}\t{%k1, %k0|%k0, %k1}
7783 test{q}\t{%1, %0|%0, %1}
7784 test{q}\t{%1, %0|%0, %1}
7785 test{q}\t{%1, %0|%0, %1}"
7786 [(set_attr "type" "test")
7787 (set_attr "modrm" "0,1,0,1,1")
7788 (set_attr "mode" "SI,SI,DI,DI,DI")])
7790 (define_insn "*testqi_1_maybe_si"
7791 [(set (reg FLAGS_REG)
7794 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7795 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7797 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7798 && ix86_match_ccmode (insn,
7799 CONST_INT_P (operands[1])
7800 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7802 if (which_alternative == 3)
7804 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7805 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7806 return "test{l}\t{%1, %k0|%k0, %1}";
7808 return "test{b}\t{%1, %0|%0, %1}";
7810 [(set_attr "type" "test")
7811 (set_attr "modrm" "0,1,1,1")
7812 (set_attr "mode" "QI,QI,QI,SI")
7813 (set_attr "pent_pair" "uv,np,uv,np")])
7815 (define_insn "*test<mode>_1"
7816 [(set (reg FLAGS_REG)
7819 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7820 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7822 "ix86_match_ccmode (insn, CCNOmode)
7823 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7824 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7825 [(set_attr "type" "test")
7826 (set_attr "modrm" "0,1,1")
7827 (set_attr "mode" "<MODE>")
7828 (set_attr "pent_pair" "uv,np,uv")])
7830 (define_expand "testqi_ext_ccno_0"
7831 [(set (reg:CCNO FLAGS_REG)
7835 (match_operand 0 "ext_register_operand")
7838 (match_operand 1 "const_int_operand"))
7841 (define_insn "*testqi_ext_0"
7842 [(set (reg FLAGS_REG)
7846 (match_operand 0 "ext_register_operand" "Q")
7849 (match_operand 1 "const_int_operand" "n"))
7851 "ix86_match_ccmode (insn, CCNOmode)"
7852 "test{b}\t{%1, %h0|%h0, %1}"
7853 [(set_attr "type" "test")
7854 (set_attr "mode" "QI")
7855 (set_attr "length_immediate" "1")
7856 (set_attr "modrm" "1")
7857 (set_attr "pent_pair" "np")])
7859 (define_insn "*testqi_ext_1"
7860 [(set (reg FLAGS_REG)
7864 (match_operand 0 "ext_register_operand" "Q,Q")
7868 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7870 "ix86_match_ccmode (insn, CCNOmode)"
7871 "test{b}\t{%1, %h0|%h0, %1}"
7872 [(set_attr "isa" "*,nox64")
7873 (set_attr "type" "test")
7874 (set_attr "mode" "QI")])
7876 (define_insn "*testqi_ext_2"
7877 [(set (reg FLAGS_REG)
7881 (match_operand 0 "ext_register_operand" "Q")
7885 (match_operand 1 "ext_register_operand" "Q")
7889 "ix86_match_ccmode (insn, CCNOmode)"
7890 "test{b}\t{%h1, %h0|%h0, %h1}"
7891 [(set_attr "type" "test")
7892 (set_attr "mode" "QI")])
7894 ;; Combine likes to form bit extractions for some tests. Humor it.
7895 (define_insn "*testqi_ext_3"
7896 [(set (reg FLAGS_REG)
7897 (compare (zero_extract:SWI248
7898 (match_operand 0 "nonimmediate_operand" "rm")
7899 (match_operand 1 "const_int_operand" "n")
7900 (match_operand 2 "const_int_operand" "n"))
7902 "ix86_match_ccmode (insn, CCNOmode)
7903 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7904 || GET_MODE (operands[0]) == SImode
7905 || GET_MODE (operands[0]) == HImode
7906 || GET_MODE (operands[0]) == QImode)
7907 /* Ensure that resulting mask is zero or sign extended operand. */
7908 && INTVAL (operands[2]) >= 0
7909 && ((INTVAL (operands[1]) > 0
7910 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7911 || (<MODE>mode == DImode
7912 && INTVAL (operands[1]) > 32
7913 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7917 [(set (match_operand 0 "flags_reg_operand")
7918 (match_operator 1 "compare_operator"
7920 (match_operand 2 "nonimmediate_operand")
7921 (match_operand 3 "const_int_operand")
7922 (match_operand 4 "const_int_operand"))
7924 "ix86_match_ccmode (insn, CCNOmode)"
7925 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7927 rtx val = operands[2];
7928 HOST_WIDE_INT len = INTVAL (operands[3]);
7929 HOST_WIDE_INT pos = INTVAL (operands[4]);
7931 machine_mode mode, submode;
7933 mode = GET_MODE (val);
7936 /* ??? Combine likes to put non-volatile mem extractions in QImode
7937 no matter the size of the test. So find a mode that works. */
7938 if (! MEM_VOLATILE_P (val))
7940 mode = smallest_mode_for_size (pos + len, MODE_INT);
7941 val = adjust_address (val, mode, 0);
7944 else if (SUBREG_P (val)
7945 && (submode = GET_MODE (SUBREG_REG (val)),
7946 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7947 && pos + len <= GET_MODE_BITSIZE (submode)
7948 && GET_MODE_CLASS (submode) == MODE_INT)
7950 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7952 val = SUBREG_REG (val);
7954 else if (mode == HImode && pos + len <= 8)
7956 /* Small HImode tests can be converted to QImode. */
7958 val = gen_lowpart (QImode, val);
7961 if (len == HOST_BITS_PER_WIDE_INT)
7964 mask = (HOST_WIDE_INT_1 << len) - 1;
7967 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7970 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7971 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7972 ;; this is relatively important trick.
7973 ;; Do the conversion only post-reload to avoid limiting of the register class
7976 [(set (match_operand 0 "flags_reg_operand")
7977 (match_operator 1 "compare_operator"
7978 [(and (match_operand 2 "QIreg_operand")
7979 (match_operand 3 "const_int_operand"))
7982 && GET_MODE (operands[2]) != QImode
7983 && ((ix86_match_ccmode (insn, CCZmode)
7984 && !(INTVAL (operands[3]) & ~(255 << 8)))
7985 || (ix86_match_ccmode (insn, CCNOmode)
7986 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7989 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7993 operands[2] = gen_lowpart (SImode, operands[2]);
7994 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7998 [(set (match_operand 0 "flags_reg_operand")
7999 (match_operator 1 "compare_operator"
8000 [(and (match_operand 2 "nonimmediate_operand")
8001 (match_operand 3 "const_int_operand"))
8004 && GET_MODE (operands[2]) != QImode
8005 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8006 && ((ix86_match_ccmode (insn, CCZmode)
8007 && !(INTVAL (operands[3]) & ~255))
8008 || (ix86_match_ccmode (insn, CCNOmode)
8009 && !(INTVAL (operands[3]) & ~127)))"
8011 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8014 operands[2] = gen_lowpart (QImode, operands[2]);
8015 operands[3] = gen_lowpart (QImode, operands[3]);
8019 [(set (match_operand:SWI1248x 0 "mask_reg_operand")
8020 (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
8021 (match_operand:SWI1248x 2 "mask_reg_operand")))
8022 (clobber (reg:CC FLAGS_REG))]
8023 "TARGET_AVX512F && reload_completed"
8025 (any_logic:SWI1248x (match_dup 1)
8028 (define_mode_iterator SWI1248_AVX512BW
8029 [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
8031 (define_insn "*k<logic><mode>"
8032 [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
8033 (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
8034 (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
8037 if (!TARGET_AVX512DQ && <MODE>mode == QImode)
8038 return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
8040 return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
8042 [(set_attr "mode" "<MODE>")
8043 (set_attr "type" "msklog")
8044 (set_attr "prefix" "vex")])
8046 ;; %%% This used to optimize known byte-wide and operations to memory,
8047 ;; and sometimes to QImode registers. If this is considered useful,
8048 ;; it should be done with splitters.
8050 (define_expand "and<mode>3"
8051 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8052 (and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8053 (match_operand:SWIM1248x 2 "<general_szext_operand>")))]
8056 machine_mode mode = <MODE>mode;
8057 rtx (*insn) (rtx, rtx);
8059 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
8061 HOST_WIDE_INT ival = INTVAL (operands[2]);
8063 if (ival == (HOST_WIDE_INT) 0xffffffff)
8065 else if (ival == 0xffff)
8067 else if (ival == 0xff)
8071 if (mode == <MODE>mode)
8073 ix86_expand_binary_operator (AND, <MODE>mode, operands);
8077 if (<MODE>mode == DImode)
8078 insn = (mode == SImode)
8079 ? gen_zero_extendsidi2
8081 ? gen_zero_extendhidi2
8082 : gen_zero_extendqidi2;
8083 else if (<MODE>mode == SImode)
8084 insn = (mode == HImode)
8085 ? gen_zero_extendhisi2
8086 : gen_zero_extendqisi2;
8087 else if (<MODE>mode == HImode)
8088 insn = gen_zero_extendqihi2;
8092 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8096 (define_insn "*anddi_1"
8097 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
8099 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
8100 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
8101 (clobber (reg:CC FLAGS_REG))]
8102 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8104 switch (get_attr_type (insn))
8110 return "kandq\t{%2, %1, %0|%0, %1, %2}";
8113 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8114 if (get_attr_mode (insn) == MODE_SI)
8115 return "and{l}\t{%k2, %k0|%k0, %k2}";
8117 return "and{q}\t{%2, %0|%0, %2}";
8120 [(set_attr "type" "alu,alu,alu,imovx,msklog")
8121 (set_attr "length_immediate" "*,*,*,0,0")
8122 (set (attr "prefix_rex")
8124 (and (eq_attr "type" "imovx")
8125 (and (match_test "INTVAL (operands[2]) == 0xff")
8126 (match_operand 1 "ext_QIreg_operand")))
8128 (const_string "*")))
8129 (set_attr "mode" "SI,DI,DI,SI,DI")])
8131 (define_insn_and_split "*anddi3_doubleword"
8132 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8134 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8135 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8136 (clobber (reg:CC FLAGS_REG))]
8137 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8138 && ix86_binary_operator_ok (AND, DImode, operands)"
8140 "&& reload_completed"
8143 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8144 if (operands[2] == const0_rtx)
8146 operands[1] = const0_rtx;
8147 ix86_expand_move (SImode, &operands[0]);
8149 else if (operands[2] != constm1_rtx)
8150 ix86_expand_binary_operator (AND, SImode, &operands[0]);
8151 else if (operands[5] == constm1_rtx)
8152 emit_note (NOTE_INSN_DELETED);
8153 if (operands[5] == const0_rtx)
8155 operands[4] = const0_rtx;
8156 ix86_expand_move (SImode, &operands[3]);
8158 else if (operands[5] != constm1_rtx)
8159 ix86_expand_binary_operator (AND, SImode, &operands[3]);
8163 (define_insn "*andsi_1"
8164 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
8165 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
8166 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
8167 (clobber (reg:CC FLAGS_REG))]
8168 "ix86_binary_operator_ok (AND, SImode, operands)"
8170 switch (get_attr_type (insn))
8176 return "kandd\t{%2, %1, %0|%0, %1, %2}";
8179 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8180 return "and{l}\t{%2, %0|%0, %2}";
8183 [(set_attr "type" "alu,alu,imovx,msklog")
8184 (set (attr "prefix_rex")
8186 (and (eq_attr "type" "imovx")
8187 (and (match_test "INTVAL (operands[2]) == 0xff")
8188 (match_operand 1 "ext_QIreg_operand")))
8190 (const_string "*")))
8191 (set_attr "length_immediate" "*,*,0,0")
8192 (set_attr "mode" "SI")])
8194 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8195 (define_insn "*andsi_1_zext"
8196 [(set (match_operand:DI 0 "register_operand" "=r")
8198 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8199 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8200 (clobber (reg:CC FLAGS_REG))]
8201 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8202 "and{l}\t{%2, %k0|%k0, %2}"
8203 [(set_attr "type" "alu")
8204 (set_attr "mode" "SI")])
8206 (define_insn "*andhi_1"
8207 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
8208 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
8209 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
8210 (clobber (reg:CC FLAGS_REG))]
8211 "ix86_binary_operator_ok (AND, HImode, operands)"
8213 switch (get_attr_type (insn))
8219 return "kandw\t{%2, %1, %0|%0, %1, %2}";
8222 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8223 return "and{w}\t{%2, %0|%0, %2}";
8226 [(set_attr "type" "alu,alu,imovx,msklog")
8227 (set_attr "length_immediate" "*,*,0,*")
8228 (set (attr "prefix_rex")
8230 (and (eq_attr "type" "imovx")
8231 (match_operand 1 "ext_QIreg_operand"))
8233 (const_string "*")))
8234 (set_attr "mode" "HI,HI,SI,HI")])
8236 (define_insn "*andqi_1"
8237 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
8238 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8239 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
8240 (clobber (reg:CC FLAGS_REG))]
8241 "ix86_binary_operator_ok (AND, QImode, operands)"
8243 switch (which_alternative)
8247 return "and{b}\t{%2, %0|%0, %2}";
8249 return "and{l}\t{%k2, %k0|%k0, %k2}";
8251 return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
8252 : "kandw\t{%2, %1, %0|%0, %1, %2}";
8257 [(set_attr "type" "alu,alu,alu,msklog")
8258 (set_attr "mode" "QI,QI,SI,HI")
8259 ;; Potential partial reg stall on alternative 2.
8260 (set (attr "preferred_for_speed")
8261 (cond [(eq_attr "alternative" "2")
8262 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8263 (symbol_ref "true")))])
8265 (define_insn "*andqi_1_slp"
8266 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8267 (and:QI (match_dup 0)
8268 (match_operand:QI 1 "general_operand" "qn,qmn")))
8269 (clobber (reg:CC FLAGS_REG))]
8270 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8271 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8272 "and{b}\t{%1, %0|%0, %1}"
8273 [(set_attr "type" "alu1")
8274 (set_attr "mode" "QI")])
8276 (define_insn "kandn<mode>"
8277 [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
8280 (match_operand:SWI12 1 "register_operand" "r,0,k"))
8281 (match_operand:SWI12 2 "register_operand" "r,r,k")))
8282 (clobber (reg:CC FLAGS_REG))]
8285 switch (which_alternative)
8288 return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
8292 if (TARGET_AVX512DQ && <MODE>mode == QImode)
8293 return "kandnb\t{%2, %1, %0|%0, %1, %2}";
8295 return "kandnw\t{%2, %1, %0|%0, %1, %2}";
8300 [(set_attr "isa" "bmi,*,avx512f")
8301 (set_attr "type" "bitmanip,*,msklog")
8302 (set_attr "prefix" "*,*,vex")
8303 (set_attr "btver2_decode" "direct,*,*")
8304 (set_attr "mode" "<MODE>")])
8307 [(set (match_operand:SWI12 0 "general_reg_operand")
8311 (match_operand:SWI12 1 "general_reg_operand")))
8312 (clobber (reg:CC FLAGS_REG))]
8313 "TARGET_AVX512F && !TARGET_BMI && reload_completed"
8315 (not:SWI12 (match_dup 0)))
8316 (parallel [(set (match_dup 0)
8317 (and:SWI12 (match_dup 0)
8319 (clobber (reg:CC FLAGS_REG))])])
8321 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8323 [(set (match_operand:DI 0 "register_operand")
8324 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8325 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8326 (clobber (reg:CC FLAGS_REG))]
8328 [(parallel [(set (match_dup 0)
8329 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8330 (clobber (reg:CC FLAGS_REG))])]
8331 "operands[2] = gen_lowpart (SImode, operands[2]);")
8334 [(set (match_operand:SWI248 0 "register_operand")
8335 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8336 (match_operand:SWI248 2 "const_int_operand")))
8337 (clobber (reg:CC FLAGS_REG))]
8339 && (!REG_P (operands[1])
8340 || REGNO (operands[0]) != REGNO (operands[1]))"
8343 HOST_WIDE_INT ival = INTVAL (operands[2]);
8345 rtx (*insn) (rtx, rtx);
8347 if (ival == (HOST_WIDE_INT) 0xffffffff)
8349 else if (ival == 0xffff)
8353 gcc_assert (ival == 0xff);
8357 if (<MODE>mode == DImode)
8358 insn = (mode == SImode)
8359 ? gen_zero_extendsidi2
8361 ? gen_zero_extendhidi2
8362 : gen_zero_extendqidi2;
8365 if (<MODE>mode != SImode)
8366 /* Zero extend to SImode to avoid partial register stalls. */
8367 operands[0] = gen_lowpart (SImode, operands[0]);
8369 insn = (mode == HImode)
8370 ? gen_zero_extendhisi2
8371 : gen_zero_extendqisi2;
8373 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8378 [(set (match_operand:SWI48 0 "register_operand")
8379 (and:SWI48 (match_dup 0)
8380 (const_int -65536)))
8381 (clobber (reg:CC FLAGS_REG))]
8382 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8383 || optimize_function_for_size_p (cfun)"
8384 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8385 "operands[1] = gen_lowpart (HImode, operands[0]);")
8388 [(set (match_operand:SWI248 0 "any_QIreg_operand")
8389 (and:SWI248 (match_dup 0)
8391 (clobber (reg:CC FLAGS_REG))]
8392 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8393 && reload_completed"
8394 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8395 "operands[1] = gen_lowpart (QImode, operands[0]);")
8398 [(set (match_operand:SWI248 0 "QIreg_operand")
8399 (and:SWI248 (match_dup 0)
8400 (const_int -65281)))
8401 (clobber (reg:CC FLAGS_REG))]
8402 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8403 && reload_completed"
8404 [(parallel [(set (zero_extract:SI (match_dup 0)
8408 (zero_extract:SI (match_dup 0)
8411 (zero_extract:SI (match_dup 0)
8414 (clobber (reg:CC FLAGS_REG))])]
8415 "operands[0] = gen_lowpart (SImode, operands[0]);")
8417 (define_insn "*anddi_2"
8418 [(set (reg FLAGS_REG)
8421 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8422 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8424 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8425 (and:DI (match_dup 1) (match_dup 2)))]
8427 && ix86_match_ccmode
8429 /* If we are going to emit andl instead of andq, and the operands[2]
8430 constant might have the SImode sign bit set, make sure the sign
8431 flag isn't tested, because the instruction will set the sign flag
8432 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8433 conservatively assume it might have bit 31 set. */
8434 (satisfies_constraint_Z (operands[2])
8435 && (!CONST_INT_P (operands[2])
8436 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8437 ? CCZmode : CCNOmode)
8438 && ix86_binary_operator_ok (AND, DImode, operands)"
8440 and{l}\t{%k2, %k0|%k0, %k2}
8441 and{q}\t{%2, %0|%0, %2}
8442 and{q}\t{%2, %0|%0, %2}"
8443 [(set_attr "type" "alu")
8444 (set_attr "mode" "SI,DI,DI")])
8446 (define_insn "*andqi_2_maybe_si"
8447 [(set (reg FLAGS_REG)
8449 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8450 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8452 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8453 (and:QI (match_dup 1) (match_dup 2)))]
8454 "ix86_binary_operator_ok (AND, QImode, operands)
8455 && ix86_match_ccmode (insn,
8456 CONST_INT_P (operands[2])
8457 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8459 if (which_alternative == 2)
8461 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8462 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8463 return "and{l}\t{%2, %k0|%k0, %2}";
8465 return "and{b}\t{%2, %0|%0, %2}";
8467 [(set_attr "type" "alu")
8468 (set_attr "mode" "QI,QI,SI")])
8470 (define_insn "*and<mode>_2"
8471 [(set (reg FLAGS_REG)
8472 (compare (and:SWI124
8473 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8474 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8476 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8477 (and:SWI124 (match_dup 1) (match_dup 2)))]
8478 "ix86_match_ccmode (insn, CCNOmode)
8479 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8480 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8481 [(set_attr "type" "alu")
8482 (set_attr "mode" "<MODE>")])
8484 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8485 (define_insn "*andsi_2_zext"
8486 [(set (reg FLAGS_REG)
8488 (match_operand:SI 1 "nonimmediate_operand" "%0")
8489 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8491 (set (match_operand:DI 0 "register_operand" "=r")
8492 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8493 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8494 && ix86_binary_operator_ok (AND, SImode, operands)"
8495 "and{l}\t{%2, %k0|%k0, %2}"
8496 [(set_attr "type" "alu")
8497 (set_attr "mode" "SI")])
8499 (define_insn "*andqi_2_slp"
8500 [(set (reg FLAGS_REG)
8502 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8503 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8505 (set (strict_low_part (match_dup 0))
8506 (and:QI (match_dup 0) (match_dup 1)))]
8507 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8508 && ix86_match_ccmode (insn, CCNOmode)
8509 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8510 "and{b}\t{%1, %0|%0, %1}"
8511 [(set_attr "type" "alu1")
8512 (set_attr "mode" "QI")])
8514 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8515 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8516 ;; for a QImode operand, which of course failed.
8517 (define_insn "andqi_ext_0"
8518 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8523 (match_operand 1 "ext_register_operand" "0")
8526 (match_operand 2 "const_int_operand" "n")))
8527 (clobber (reg:CC FLAGS_REG))]
8529 "and{b}\t{%2, %h0|%h0, %2}"
8530 [(set_attr "type" "alu")
8531 (set_attr "length_immediate" "1")
8532 (set_attr "modrm" "1")
8533 (set_attr "mode" "QI")])
8535 ;; Generated by peephole translating test to and. This shows up
8536 ;; often in fp comparisons.
8537 (define_insn "*andqi_ext_0_cc"
8538 [(set (reg FLAGS_REG)
8542 (match_operand 1 "ext_register_operand" "0")
8545 (match_operand 2 "const_int_operand" "n"))
8547 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8556 "ix86_match_ccmode (insn, CCNOmode)"
8557 "and{b}\t{%2, %h0|%h0, %2}"
8558 [(set_attr "type" "alu")
8559 (set_attr "length_immediate" "1")
8560 (set_attr "modrm" "1")
8561 (set_attr "mode" "QI")])
8563 (define_insn "*andqi_ext_1"
8564 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8569 (match_operand 1 "ext_register_operand" "0,0")
8573 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8574 (clobber (reg:CC FLAGS_REG))]
8576 "and{b}\t{%2, %h0|%h0, %2}"
8577 [(set_attr "isa" "*,nox64")
8578 (set_attr "type" "alu")
8579 (set_attr "length_immediate" "0")
8580 (set_attr "mode" "QI")])
8582 (define_insn "*andqi_ext_2"
8583 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8588 (match_operand 1 "ext_register_operand" "%0")
8592 (match_operand 2 "ext_register_operand" "Q")
8595 (clobber (reg:CC FLAGS_REG))]
8597 "and{b}\t{%h2, %h0|%h0, %h2}"
8598 [(set_attr "type" "alu")
8599 (set_attr "length_immediate" "0")
8600 (set_attr "mode" "QI")])
8602 ;; Convert wide AND instructions with immediate operand to shorter QImode
8603 ;; equivalents when possible.
8604 ;; Don't do the splitting with memory operands, since it introduces risk
8605 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8606 ;; for size, but that can (should?) be handled by generic code instead.
8608 [(set (match_operand 0 "QIreg_operand")
8609 (and (match_operand 1 "register_operand")
8610 (match_operand 2 "const_int_operand")))
8611 (clobber (reg:CC FLAGS_REG))]
8613 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8614 && !(~INTVAL (operands[2]) & ~(255 << 8))
8615 && GET_MODE (operands[0]) != QImode"
8616 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8617 (and:SI (zero_extract:SI (match_dup 1)
8618 (const_int 8) (const_int 8))
8620 (clobber (reg:CC FLAGS_REG))])]
8622 operands[0] = gen_lowpart (SImode, operands[0]);
8623 operands[1] = gen_lowpart (SImode, operands[1]);
8624 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8627 ;; Since AND can be encoded with sign extended immediate, this is only
8628 ;; profitable when 7th bit is not set.
8630 [(set (match_operand 0 "any_QIreg_operand")
8631 (and (match_operand 1 "general_operand")
8632 (match_operand 2 "const_int_operand")))
8633 (clobber (reg:CC FLAGS_REG))]
8635 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8636 && !(~INTVAL (operands[2]) & ~255)
8637 && !(INTVAL (operands[2]) & 128)
8638 && GET_MODE (operands[0]) != QImode"
8639 [(parallel [(set (strict_low_part (match_dup 0))
8640 (and:QI (match_dup 1)
8642 (clobber (reg:CC FLAGS_REG))])]
8644 operands[0] = gen_lowpart (QImode, operands[0]);
8645 operands[1] = gen_lowpart (QImode, operands[1]);
8646 operands[2] = gen_lowpart (QImode, operands[2]);
8649 ;; Logical inclusive and exclusive OR instructions
8651 ;; %%% This used to optimize known byte-wide and operations to memory.
8652 ;; If this is considered useful, it should be done with splitters.
8654 (define_expand "<code><mode>3"
8655 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8656 (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8657 (match_operand:SWIM1248x 2 "<general_operand>")))]
8659 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8661 (define_insn "*<code><mode>_1"
8662 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8664 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8665 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8666 (clobber (reg:CC FLAGS_REG))]
8667 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8669 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8670 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8671 k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8672 [(set_attr "type" "alu,alu,msklog")
8673 (set_attr "mode" "<MODE>")])
8675 (define_insn_and_split "*<code>di3_doubleword"
8676 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8678 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8679 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8680 (clobber (reg:CC FLAGS_REG))]
8681 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8682 && ix86_binary_operator_ok (<CODE>, DImode, operands)"
8684 "&& reload_completed"
8687 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8688 if (operands[2] == constm1_rtx)
8692 operands[1] = constm1_rtx;
8693 ix86_expand_move (SImode, &operands[0]);
8696 ix86_expand_unary_operator (NOT, SImode, &operands[0]);
8698 else if (operands[2] != const0_rtx)
8699 ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
8700 else if (operands[5] == const0_rtx)
8701 emit_note (NOTE_INSN_DELETED);
8702 if (operands[5] == constm1_rtx)
8706 operands[4] = constm1_rtx;
8707 ix86_expand_move (SImode, &operands[3]);
8710 ix86_expand_unary_operator (NOT, SImode, &operands[3]);
8712 else if (operands[5] != const0_rtx)
8713 ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
8717 (define_insn_and_split "*andndi3_doubleword"
8718 [(set (match_operand:DI 0 "register_operand" "=r,r")
8720 (not:DI (match_operand:DI 1 "register_operand" "r,r"))
8721 (match_operand:DI 2 "nonimmediate_operand" "r,m")))
8722 (clobber (reg:CC FLAGS_REG))]
8723 "TARGET_BMI && !TARGET_64BIT && TARGET_STV && TARGET_SSE"
8725 "&& reload_completed"
8726 [(parallel [(set (match_dup 0)
8727 (and:SI (not:SI (match_dup 1)) (match_dup 2)))
8728 (clobber (reg:CC FLAGS_REG))])
8729 (parallel [(set (match_dup 3)
8730 (and:SI (not:SI (match_dup 4)) (match_dup 5)))
8731 (clobber (reg:CC FLAGS_REG))])]
8732 "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
8734 (define_insn "*<code>hi_1"
8735 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8737 (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8738 (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8739 (clobber (reg:CC FLAGS_REG))]
8740 "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8742 <logic>{w}\t{%2, %0|%0, %2}
8743 <logic>{w}\t{%2, %0|%0, %2}
8744 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8745 [(set_attr "type" "alu,alu,msklog")
8746 (set_attr "mode" "HI")])
8748 (define_insn "*<code>qi_1"
8749 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8750 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8751 (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8752 (clobber (reg:CC FLAGS_REG))]
8753 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8755 <logic>{b}\t{%2, %0|%0, %2}
8756 <logic>{b}\t{%2, %0|%0, %2}
8757 <logic>{l}\t{%k2, %k0|%k0, %k2}
8758 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8759 [(set_attr "type" "alu,alu,alu,msklog")
8760 (set_attr "mode" "QI,QI,SI,HI")
8761 ;; Potential partial reg stall on alternative 2.
8762 (set (attr "preferred_for_speed")
8763 (cond [(eq_attr "alternative" "2")
8764 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8765 (symbol_ref "true")))])
8767 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8768 (define_insn "*<code>si_1_zext"
8769 [(set (match_operand:DI 0 "register_operand" "=r")
8771 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8772 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8773 (clobber (reg:CC FLAGS_REG))]
8774 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8775 "<logic>{l}\t{%2, %k0|%k0, %2}"
8776 [(set_attr "type" "alu")
8777 (set_attr "mode" "SI")])
8779 (define_insn "*<code>si_1_zext_imm"
8780 [(set (match_operand:DI 0 "register_operand" "=r")
8782 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8783 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8784 (clobber (reg:CC FLAGS_REG))]
8785 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8786 "<logic>{l}\t{%2, %k0|%k0, %2}"
8787 [(set_attr "type" "alu")
8788 (set_attr "mode" "SI")])
8790 (define_insn "*<code>qi_1_slp"
8791 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8792 (any_or:QI (match_dup 0)
8793 (match_operand:QI 1 "general_operand" "qmn,qn")))
8794 (clobber (reg:CC FLAGS_REG))]
8795 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8796 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8797 "<logic>{b}\t{%1, %0|%0, %1}"
8798 [(set_attr "type" "alu1")
8799 (set_attr "mode" "QI")])
8801 (define_insn "*<code><mode>_2"
8802 [(set (reg FLAGS_REG)
8803 (compare (any_or:SWI
8804 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8805 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8807 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8808 (any_or:SWI (match_dup 1) (match_dup 2)))]
8809 "ix86_match_ccmode (insn, CCNOmode)
8810 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8811 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8812 [(set_attr "type" "alu")
8813 (set_attr "mode" "<MODE>")])
8815 (define_insn "kxnor<mode>"
8816 [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8819 (match_operand:SWI12 1 "register_operand" "0,k")
8820 (match_operand:SWI12 2 "register_operand" "r,k"))))
8821 (clobber (reg:CC FLAGS_REG))]
8824 if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8825 return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8826 return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8828 [(set_attr "type" "*,msklog")
8829 (set_attr "prefix" "*,vex")
8830 (set_attr "mode" "<MODE>")])
8832 (define_insn "kxnor<mode>"
8833 [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8836 (match_operand:SWI48x 1 "register_operand" "0,k")
8837 (match_operand:SWI48x 2 "register_operand" "r,k"))))
8838 (clobber (reg:CC FLAGS_REG))]
8842 kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8843 [(set_attr "type" "*,msklog")
8844 (set_attr "prefix" "*,vex")
8845 (set_attr "mode" "<MODE>")])
8848 [(set (match_operand:SWI1248x 0 "general_reg_operand")
8852 (match_operand:SWI1248x 1 "general_reg_operand"))))
8853 (clobber (reg:CC FLAGS_REG))]
8854 "TARGET_AVX512F && reload_completed"
8855 [(parallel [(set (match_dup 0)
8856 (xor:SWI1248x (match_dup 0)
8858 (clobber (reg:CC FLAGS_REG))])
8860 (not:SWI1248x (match_dup 0)))])
8862 ;;There are kortrest[bdq] but no intrinsics for them.
8863 ;;We probably don't need to implement them.
8864 (define_insn "kortestzhi"
8865 [(set (reg:CCZ FLAGS_REG)
8868 (match_operand:HI 0 "register_operand" "k")
8869 (match_operand:HI 1 "register_operand" "k"))
8871 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8872 "kortestw\t{%1, %0|%0, %1}"
8873 [(set_attr "mode" "HI")
8874 (set_attr "type" "msklog")
8875 (set_attr "prefix" "vex")])
8877 (define_insn "kortestchi"
8878 [(set (reg:CCC FLAGS_REG)
8881 (match_operand:HI 0 "register_operand" "k")
8882 (match_operand:HI 1 "register_operand" "k"))
8884 "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8885 "kortestw\t{%1, %0|%0, %1}"
8886 [(set_attr "mode" "HI")
8887 (set_attr "type" "msklog")
8888 (set_attr "prefix" "vex")])
8890 (define_insn "kunpckhi"
8891 [(set (match_operand:HI 0 "register_operand" "=k")
8894 (zero_extend:HI (match_operand:QI 1 "register_operand" "k"))
8896 (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8898 "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8899 [(set_attr "mode" "HI")
8900 (set_attr "type" "msklog")
8901 (set_attr "prefix" "vex")])
8903 (define_insn "kunpcksi"
8904 [(set (match_operand:SI 0 "register_operand" "=k")
8907 (zero_extend:SI (match_operand:HI 1 "register_operand" "k"))
8909 (zero_extend:SI (match_operand:HI 2 "register_operand" "k"))))]
8911 "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8912 [(set_attr "mode" "SI")])
8914 (define_insn "kunpckdi"
8915 [(set (match_operand:DI 0 "register_operand" "=k")
8918 (zero_extend:DI (match_operand:SI 1 "register_operand" "k"))
8920 (zero_extend:DI (match_operand:SI 2 "register_operand" "k"))))]
8922 "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8923 [(set_attr "mode" "DI")])
8925 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8926 ;; ??? Special case for immediate operand is missing - it is tricky.
8927 (define_insn "*<code>si_2_zext"
8928 [(set (reg FLAGS_REG)
8929 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8930 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8932 (set (match_operand:DI 0 "register_operand" "=r")
8933 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8934 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8935 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8936 "<logic>{l}\t{%2, %k0|%k0, %2}"
8937 [(set_attr "type" "alu")
8938 (set_attr "mode" "SI")])
8940 (define_insn "*<code>si_2_zext_imm"
8941 [(set (reg FLAGS_REG)
8943 (match_operand:SI 1 "nonimmediate_operand" "%0")
8944 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8946 (set (match_operand:DI 0 "register_operand" "=r")
8947 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8948 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8949 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8950 "<logic>{l}\t{%2, %k0|%k0, %2}"
8951 [(set_attr "type" "alu")
8952 (set_attr "mode" "SI")])
8954 (define_insn "*<code>qi_2_slp"
8955 [(set (reg FLAGS_REG)
8956 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8957 (match_operand:QI 1 "general_operand" "qmn,qn"))
8959 (set (strict_low_part (match_dup 0))
8960 (any_or:QI (match_dup 0) (match_dup 1)))]
8961 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8962 && ix86_match_ccmode (insn, CCNOmode)
8963 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8964 "<logic>{b}\t{%1, %0|%0, %1}"
8965 [(set_attr "type" "alu1")
8966 (set_attr "mode" "QI")])
8968 (define_insn "*<code><mode>_3"
8969 [(set (reg FLAGS_REG)
8970 (compare (any_or:SWI
8971 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8972 (match_operand:SWI 2 "<general_operand>" "<g>"))
8974 (clobber (match_scratch:SWI 0 "=<r>"))]
8975 "ix86_match_ccmode (insn, CCNOmode)
8976 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8977 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8978 [(set_attr "type" "alu")
8979 (set_attr "mode" "<MODE>")])
8981 (define_insn "*<code>qi_ext_0"
8982 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8987 (match_operand 1 "ext_register_operand" "0")
8990 (match_operand 2 "const_int_operand" "n")))
8991 (clobber (reg:CC FLAGS_REG))]
8992 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8993 "<logic>{b}\t{%2, %h0|%h0, %2}"
8994 [(set_attr "type" "alu")
8995 (set_attr "length_immediate" "1")
8996 (set_attr "modrm" "1")
8997 (set_attr "mode" "QI")])
8999 (define_insn "*<code>qi_ext_1"
9000 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
9005 (match_operand 1 "ext_register_operand" "0,0")
9009 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
9010 (clobber (reg:CC FLAGS_REG))]
9011 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9012 "<logic>{b}\t{%2, %h0|%h0, %2}"
9013 [(set_attr "isa" "*,nox64")
9014 (set_attr "type" "alu")
9015 (set_attr "length_immediate" "0")
9016 (set_attr "mode" "QI")])
9018 (define_insn "*<code>qi_ext_2"
9019 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9023 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9026 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9029 (clobber (reg:CC FLAGS_REG))]
9030 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9031 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9032 [(set_attr "type" "alu")
9033 (set_attr "length_immediate" "0")
9034 (set_attr "mode" "QI")])
9037 [(set (match_operand 0 "QIreg_operand")
9038 (any_or (match_operand 1 "register_operand")
9039 (match_operand 2 "const_int_operand")))
9040 (clobber (reg:CC FLAGS_REG))]
9042 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9043 && !(INTVAL (operands[2]) & ~(255 << 8))
9044 && GET_MODE (operands[0]) != QImode"
9045 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9046 (any_or:SI (zero_extract:SI (match_dup 1)
9047 (const_int 8) (const_int 8))
9049 (clobber (reg:CC FLAGS_REG))])]
9051 operands[0] = gen_lowpart (SImode, operands[0]);
9052 operands[1] = gen_lowpart (SImode, operands[1]);
9053 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
9056 ;; Since OR can be encoded with sign extended immediate, this is only
9057 ;; profitable when 7th bit is set.
9059 [(set (match_operand 0 "any_QIreg_operand")
9060 (any_or (match_operand 1 "general_operand")
9061 (match_operand 2 "const_int_operand")))
9062 (clobber (reg:CC FLAGS_REG))]
9064 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9065 && !(INTVAL (operands[2]) & ~255)
9066 && (INTVAL (operands[2]) & 128)
9067 && GET_MODE (operands[0]) != QImode"
9068 [(parallel [(set (strict_low_part (match_dup 0))
9069 (any_or:QI (match_dup 1)
9071 (clobber (reg:CC FLAGS_REG))])]
9073 operands[0] = gen_lowpart (QImode, operands[0]);
9074 operands[1] = gen_lowpart (QImode, operands[1]);
9075 operands[2] = gen_lowpart (QImode, operands[2]);
9078 (define_expand "xorqi_cc_ext_1"
9080 (set (reg:CCNO FLAGS_REG)
9084 (match_operand 1 "ext_register_operand")
9087 (match_operand:QI 2 "const_int_operand"))
9089 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9099 (define_insn "*xorqi_cc_ext_1"
9100 [(set (reg FLAGS_REG)
9104 (match_operand 1 "ext_register_operand" "0,0")
9107 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
9109 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
9118 "ix86_match_ccmode (insn, CCNOmode)"
9119 "xor{b}\t{%2, %h0|%h0, %2}"
9120 [(set_attr "isa" "*,nox64")
9121 (set_attr "type" "alu")
9122 (set_attr "modrm" "1")
9123 (set_attr "mode" "QI")])
9125 ;; Negation instructions
9127 (define_expand "neg<mode>2"
9128 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
9129 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
9131 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9133 (define_insn_and_split "*neg<dwi>2_doubleword"
9134 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9135 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9136 (clobber (reg:CC FLAGS_REG))]
9137 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9141 [(set (reg:CCZ FLAGS_REG)
9142 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9143 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9146 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9149 (clobber (reg:CC FLAGS_REG))])
9152 (neg:DWIH (match_dup 2)))
9153 (clobber (reg:CC FLAGS_REG))])]
9154 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
9156 (define_insn "*neg<mode>2_1"
9157 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9158 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9159 (clobber (reg:CC FLAGS_REG))]
9160 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9161 "neg{<imodesuffix>}\t%0"
9162 [(set_attr "type" "negnot")
9163 (set_attr "mode" "<MODE>")])
9165 ;; Combine is quite creative about this pattern.
9166 (define_insn "*negsi2_1_zext"
9167 [(set (match_operand:DI 0 "register_operand" "=r")
9169 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9172 (clobber (reg:CC FLAGS_REG))]
9173 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9175 [(set_attr "type" "negnot")
9176 (set_attr "mode" "SI")])
9178 ;; The problem with neg is that it does not perform (compare x 0),
9179 ;; it really performs (compare 0 x), which leaves us with the zero
9180 ;; flag being the only useful item.
9182 (define_insn "*neg<mode>2_cmpz"
9183 [(set (reg:CCZ FLAGS_REG)
9185 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9187 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9188 (neg:SWI (match_dup 1)))]
9189 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9190 "neg{<imodesuffix>}\t%0"
9191 [(set_attr "type" "negnot")
9192 (set_attr "mode" "<MODE>")])
9194 (define_insn "*negsi2_cmpz_zext"
9195 [(set (reg:CCZ FLAGS_REG)
9199 (match_operand:DI 1 "register_operand" "0")
9203 (set (match_operand:DI 0 "register_operand" "=r")
9204 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9207 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9209 [(set_attr "type" "negnot")
9210 (set_attr "mode" "SI")])
9212 ;; Negate with jump on overflow.
9213 (define_expand "negv<mode>3"
9214 [(parallel [(set (reg:CCO FLAGS_REG)
9215 (ne:CCO (match_operand:SWI 1 "register_operand")
9217 (set (match_operand:SWI 0 "register_operand")
9218 (neg:SWI (match_dup 1)))])
9219 (set (pc) (if_then_else
9220 (eq (reg:CCO FLAGS_REG) (const_int 0))
9221 (label_ref (match_operand 2))
9226 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
9230 (define_insn "*negv<mode>3"
9231 [(set (reg:CCO FLAGS_REG)
9232 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
9233 (match_operand:SWI 2 "const_int_operand")))
9234 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9235 (neg:SWI (match_dup 1)))]
9236 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
9237 && mode_signbit_p (<MODE>mode, operands[2])"
9238 "neg{<imodesuffix>}\t%0"
9239 [(set_attr "type" "negnot")
9240 (set_attr "mode" "<MODE>")])
9242 ;; Changing of sign for FP values is doable using integer unit too.
9244 (define_expand "<code><mode>2"
9245 [(set (match_operand:X87MODEF 0 "register_operand")
9246 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
9247 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9248 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9250 (define_insn "*absneg<mode>2"
9251 [(set (match_operand:MODEF 0 "register_operand" "=Yv,Yv,f,!r")
9252 (match_operator:MODEF 3 "absneg_operator"
9253 [(match_operand:MODEF 1 "register_operand" "0,Yv,0,0")]))
9254 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "Yvm,0,X,X"))
9255 (clobber (reg:CC FLAGS_REG))]
9256 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9258 [(set (attr "enabled")
9260 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
9262 (eq_attr "alternative" "2")
9263 (symbol_ref "TARGET_MIX_SSE_I387")
9264 (symbol_ref "true"))
9266 (eq_attr "alternative" "2,3")
9268 (symbol_ref "false"))))])
9270 (define_insn "*absnegxf2_i387"
9271 [(set (match_operand:XF 0 "register_operand" "=f,!r")
9272 (match_operator:XF 3 "absneg_operator"
9273 [(match_operand:XF 1 "register_operand" "0,0")]))
9274 (use (match_operand 2))
9275 (clobber (reg:CC FLAGS_REG))]
9279 (define_expand "<code>tf2"
9280 [(set (match_operand:TF 0 "register_operand")
9281 (absneg:TF (match_operand:TF 1 "register_operand")))]
9283 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9285 (define_insn "*absnegtf2_sse"
9286 [(set (match_operand:TF 0 "register_operand" "=Yv,Yv")
9287 (match_operator:TF 3 "absneg_operator"
9288 [(match_operand:TF 1 "register_operand" "0,Yv")]))
9289 (use (match_operand:TF 2 "nonimmediate_operand" "Yvm,0"))
9290 (clobber (reg:CC FLAGS_REG))]
9294 ;; Splitters for fp abs and neg.
9297 [(set (match_operand 0 "fp_register_operand")
9298 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9299 (use (match_operand 2))
9300 (clobber (reg:CC FLAGS_REG))]
9302 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9305 [(set (match_operand 0 "sse_reg_operand")
9306 (match_operator 3 "absneg_operator"
9307 [(match_operand 1 "register_operand")]))
9308 (use (match_operand 2 "nonimmediate_operand"))
9309 (clobber (reg:CC FLAGS_REG))]
9311 [(set (match_dup 0) (match_dup 3))]
9313 machine_mode mode = GET_MODE (operands[0]);
9314 machine_mode vmode = GET_MODE (operands[2]);
9317 operands[0] = lowpart_subreg (vmode, operands[0], mode);
9318 operands[1] = lowpart_subreg (vmode, operands[1], mode);
9319 if (operands_match_p (operands[0], operands[2]))
9320 std::swap (operands[1], operands[2]);
9321 if (GET_CODE (operands[3]) == ABS)
9322 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9324 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9329 [(set (match_operand:SF 0 "general_reg_operand")
9330 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9331 (use (match_operand:V4SF 2))
9332 (clobber (reg:CC FLAGS_REG))]
9334 [(parallel [(set (match_dup 0) (match_dup 1))
9335 (clobber (reg:CC FLAGS_REG))])]
9338 operands[0] = gen_lowpart (SImode, operands[0]);
9339 if (GET_CODE (operands[1]) == ABS)
9341 tmp = gen_int_mode (0x7fffffff, SImode);
9342 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9346 tmp = gen_int_mode (0x80000000, SImode);
9347 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9353 [(set (match_operand:DF 0 "general_reg_operand")
9354 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9355 (use (match_operand 2))
9356 (clobber (reg:CC FLAGS_REG))]
9358 [(parallel [(set (match_dup 0) (match_dup 1))
9359 (clobber (reg:CC FLAGS_REG))])]
9364 tmp = gen_lowpart (DImode, operands[0]);
9365 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9368 if (GET_CODE (operands[1]) == ABS)
9371 tmp = gen_rtx_NOT (DImode, tmp);
9375 operands[0] = gen_highpart (SImode, operands[0]);
9376 if (GET_CODE (operands[1]) == ABS)
9378 tmp = gen_int_mode (0x7fffffff, SImode);
9379 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9383 tmp = gen_int_mode (0x80000000, SImode);
9384 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9391 [(set (match_operand:XF 0 "general_reg_operand")
9392 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9393 (use (match_operand 2))
9394 (clobber (reg:CC FLAGS_REG))]
9396 [(parallel [(set (match_dup 0) (match_dup 1))
9397 (clobber (reg:CC FLAGS_REG))])]
9400 operands[0] = gen_rtx_REG (SImode,
9401 REGNO (operands[0]) + (TARGET_64BIT ? 1 : 2));
9402 if (GET_CODE (operands[1]) == ABS)
9404 tmp = GEN_INT (0x7fff);
9405 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9409 tmp = GEN_INT (0x8000);
9410 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9415 ;; Conditionalize these after reload. If they match before reload, we
9416 ;; lose the clobber and ability to use integer instructions.
9418 (define_insn "*<code><mode>2_1"
9419 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9420 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9422 && (reload_completed
9423 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9424 "f<absneg_mnemonic>"
9425 [(set_attr "type" "fsgn")
9426 (set_attr "mode" "<MODE>")])
9428 (define_insn "*<code>extendsfdf2"
9429 [(set (match_operand:DF 0 "register_operand" "=f")
9430 (absneg:DF (float_extend:DF
9431 (match_operand:SF 1 "register_operand" "0"))))]
9432 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9433 "f<absneg_mnemonic>"
9434 [(set_attr "type" "fsgn")
9435 (set_attr "mode" "DF")])
9437 (define_insn "*<code>extendsfxf2"
9438 [(set (match_operand:XF 0 "register_operand" "=f")
9439 (absneg:XF (float_extend:XF
9440 (match_operand:SF 1 "register_operand" "0"))))]
9442 "f<absneg_mnemonic>"
9443 [(set_attr "type" "fsgn")
9444 (set_attr "mode" "XF")])
9446 (define_insn "*<code>extenddfxf2"
9447 [(set (match_operand:XF 0 "register_operand" "=f")
9448 (absneg:XF (float_extend:XF
9449 (match_operand:DF 1 "register_operand" "0"))))]
9451 "f<absneg_mnemonic>"
9452 [(set_attr "type" "fsgn")
9453 (set_attr "mode" "XF")])
9455 ;; Copysign instructions
9457 (define_mode_iterator CSGNMODE [SF DF TF])
9458 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9460 (define_expand "copysign<mode>3"
9461 [(match_operand:CSGNMODE 0 "register_operand")
9462 (match_operand:CSGNMODE 1 "nonmemory_operand")
9463 (match_operand:CSGNMODE 2 "register_operand")]
9464 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9465 || (TARGET_SSE && (<MODE>mode == TFmode))"
9466 "ix86_expand_copysign (operands); DONE;")
9468 (define_insn_and_split "copysign<mode>3_const"
9469 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv")
9471 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "YvmC")
9472 (match_operand:CSGNMODE 2 "register_operand" "0")
9473 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "Yvm")]
9475 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9476 || (TARGET_SSE && (<MODE>mode == TFmode))"
9478 "&& reload_completed"
9480 "ix86_split_copysign_const (operands); DONE;")
9482 (define_insn "copysign<mode>3_var"
9483 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
9485 [(match_operand:CSGNMODE 2 "register_operand" "Yv,0,0,Yv,Yv")
9486 (match_operand:CSGNMODE 3 "register_operand" "1,1,Yv,1,Yv")
9487 (match_operand:<CSGNVMODE> 4
9488 "nonimmediate_operand" "X,Yvm,Yvm,0,0")
9489 (match_operand:<CSGNVMODE> 5
9490 "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
9492 (clobber (match_scratch:<CSGNVMODE> 1 "=Yv,Yv,Yv,Yv,Yv"))]
9493 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9494 || (TARGET_SSE && (<MODE>mode == TFmode))"
9498 [(set (match_operand:CSGNMODE 0 "register_operand")
9500 [(match_operand:CSGNMODE 2 "register_operand")
9501 (match_operand:CSGNMODE 3 "register_operand")
9502 (match_operand:<CSGNVMODE> 4)
9503 (match_operand:<CSGNVMODE> 5)]
9505 (clobber (match_scratch:<CSGNVMODE> 1))]
9506 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9507 || (TARGET_SSE && (<MODE>mode == TFmode)))
9508 && reload_completed"
9510 "ix86_split_copysign_var (operands); DONE;")
9512 ;; One complement instructions
9514 (define_expand "one_cmpl<mode>2"
9515 [(set (match_operand:SWIM 0 "nonimmediate_operand")
9516 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9518 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9520 (define_insn "*one_cmpl<mode>2_1"
9521 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
9522 (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
9523 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9525 not{<imodesuffix>}\t%0
9526 knot<mskmodesuffix>\t{%1, %0|%0, %1}"
9527 [(set_attr "isa" "*,avx512bw")
9528 (set_attr "type" "negnot,msklog")
9529 (set_attr "prefix" "*,vex")
9530 (set_attr "mode" "<MODE>")])
9532 (define_insn "*one_cmplhi2_1"
9533 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
9534 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
9535 "ix86_unary_operator_ok (NOT, HImode, operands)"
9538 knotw\t{%1, %0|%0, %1}"
9539 [(set_attr "isa" "*,avx512f")
9540 (set_attr "type" "negnot,msklog")
9541 (set_attr "prefix" "*,vex")
9542 (set_attr "mode" "HI")])
9544 (define_insn "*one_cmplqi2_1"
9545 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
9546 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
9547 "ix86_unary_operator_ok (NOT, QImode, operands)"
9549 switch (which_alternative)
9552 return "not{b}\t%0";
9554 return "not{l}\t%k0";
9556 if (TARGET_AVX512DQ)
9557 return "knotb\t{%1, %0|%0, %1}";
9558 return "knotw\t{%1, %0|%0, %1}";
9563 [(set_attr "isa" "*,*,avx512f")
9564 (set_attr "type" "negnot,negnot,msklog")
9565 (set_attr "prefix" "*,*,vex")
9566 (set_attr "mode" "QI,SI,QI")
9567 ;; Potential partial reg stall on alternative 1.
9568 (set (attr "preferred_for_speed")
9569 (cond [(eq_attr "alternative" "1")
9570 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9571 (symbol_ref "true")))])
9573 ;; ??? Currently never generated - xor is used instead.
9574 (define_insn "*one_cmplsi2_1_zext"
9575 [(set (match_operand:DI 0 "register_operand" "=r")
9577 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9578 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9580 [(set_attr "type" "negnot")
9581 (set_attr "mode" "SI")])
9583 (define_insn "*one_cmpl<mode>2_2"
9584 [(set (reg FLAGS_REG)
9585 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9587 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9588 (not:SWI (match_dup 1)))]
9589 "ix86_match_ccmode (insn, CCNOmode)
9590 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9592 [(set_attr "type" "alu1")
9593 (set_attr "mode" "<MODE>")])
9596 [(set (match_operand 0 "flags_reg_operand")
9597 (match_operator 2 "compare_operator"
9598 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9600 (set (match_operand:SWI 1 "nonimmediate_operand")
9601 (not:SWI (match_dup 3)))]
9602 "ix86_match_ccmode (insn, CCNOmode)"
9603 [(parallel [(set (match_dup 0)
9604 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9607 (xor:SWI (match_dup 3) (const_int -1)))])])
9609 ;; ??? Currently never generated - xor is used instead.
9610 (define_insn "*one_cmplsi2_2_zext"
9611 [(set (reg FLAGS_REG)
9612 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9614 (set (match_operand:DI 0 "register_operand" "=r")
9615 (zero_extend:DI (not:SI (match_dup 1))))]
9616 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9617 && ix86_unary_operator_ok (NOT, SImode, operands)"
9619 [(set_attr "type" "alu1")
9620 (set_attr "mode" "SI")])
9623 [(set (match_operand 0 "flags_reg_operand")
9624 (match_operator 2 "compare_operator"
9625 [(not:SI (match_operand:SI 3 "register_operand"))
9627 (set (match_operand:DI 1 "register_operand")
9628 (zero_extend:DI (not:SI (match_dup 3))))]
9629 "ix86_match_ccmode (insn, CCNOmode)"
9630 [(parallel [(set (match_dup 0)
9631 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9634 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9636 ;; Shift instructions
9638 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9639 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9640 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9641 ;; from the assembler input.
9643 ;; This instruction shifts the target reg/mem as usual, but instead of
9644 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9645 ;; is a left shift double, bits are taken from the high order bits of
9646 ;; reg, else if the insn is a shift right double, bits are taken from the
9647 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9648 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9650 ;; Since sh[lr]d does not change the `reg' operand, that is done
9651 ;; separately, making all shifts emit pairs of shift double and normal
9652 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9653 ;; support a 63 bit shift, each shift where the count is in a reg expands
9654 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9656 ;; If the shift count is a constant, we need never emit more than one
9657 ;; shift pair, instead using moves and sign extension for counts greater
9660 (define_insn "*<mshift><mode>3"
9661 [(set (match_operand:SWI1248_AVX512BWDQ 0 "register_operand" "=k")
9662 (any_lshift:SWI1248_AVX512BWDQ (match_operand:SWI1248_AVX512BWDQ 1 "register_operand" "k")
9663 (match_operand:QI 2 "immediate_operand" "i")))]
9665 "k<mshift><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
9666 [(set_attr "type" "msklog")
9667 (set_attr "prefix" "vex")])
9669 (define_expand "ashl<mode>3"
9670 [(set (match_operand:SDWIM 0 "<shift_operand>")
9671 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9672 (match_operand:QI 2 "nonmemory_operand")))]
9674 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9676 (define_insn "*ashl<mode>3_doubleword"
9677 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9678 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9679 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9680 (clobber (reg:CC FLAGS_REG))]
9683 [(set_attr "type" "multi")])
9686 [(set (match_operand:DWI 0 "register_operand")
9687 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9688 (match_operand:QI 2 "nonmemory_operand")))
9689 (clobber (reg:CC FLAGS_REG))]
9690 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9692 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9694 ;; By default we don't ask for a scratch register, because when DWImode
9695 ;; values are manipulated, registers are already at a premium. But if
9696 ;; we have one handy, we won't turn it away.
9699 [(match_scratch:DWIH 3 "r")
9700 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9702 (match_operand:<DWI> 1 "nonmemory_operand")
9703 (match_operand:QI 2 "nonmemory_operand")))
9704 (clobber (reg:CC FLAGS_REG))])
9708 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9710 (define_insn "x86_64_shld"
9711 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9712 (ior:DI (ashift:DI (match_dup 0)
9713 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9714 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9715 (minus:QI (const_int 64) (match_dup 2)))))
9716 (clobber (reg:CC FLAGS_REG))]
9718 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9719 [(set_attr "type" "ishift")
9720 (set_attr "prefix_0f" "1")
9721 (set_attr "mode" "DI")
9722 (set_attr "athlon_decode" "vector")
9723 (set_attr "amdfam10_decode" "vector")
9724 (set_attr "bdver1_decode" "vector")])
9726 (define_insn "x86_shld"
9727 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9728 (ior:SI (ashift:SI (match_dup 0)
9729 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9730 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9731 (minus:QI (const_int 32) (match_dup 2)))))
9732 (clobber (reg:CC FLAGS_REG))]
9734 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9735 [(set_attr "type" "ishift")
9736 (set_attr "prefix_0f" "1")
9737 (set_attr "mode" "SI")
9738 (set_attr "pent_pair" "np")
9739 (set_attr "athlon_decode" "vector")
9740 (set_attr "amdfam10_decode" "vector")
9741 (set_attr "bdver1_decode" "vector")])
9743 (define_expand "x86_shift<mode>_adj_1"
9744 [(set (reg:CCZ FLAGS_REG)
9745 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9748 (set (match_operand:SWI48 0 "register_operand")
9749 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9750 (match_operand:SWI48 1 "register_operand")
9753 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9754 (match_operand:SWI48 3 "register_operand")
9757 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9759 (define_expand "x86_shift<mode>_adj_2"
9760 [(use (match_operand:SWI48 0 "register_operand"))
9761 (use (match_operand:SWI48 1 "register_operand"))
9762 (use (match_operand:QI 2 "register_operand"))]
9765 rtx_code_label *label = gen_label_rtx ();
9768 emit_insn (gen_testqi_ccz_1 (operands[2],
9769 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9771 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9772 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9773 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9774 gen_rtx_LABEL_REF (VOIDmode, label),
9776 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
9777 JUMP_LABEL (tmp) = label;
9779 emit_move_insn (operands[0], operands[1]);
9780 ix86_expand_clear (operands[1]);
9783 LABEL_NUSES (label) = 1;
9788 ;; Avoid useless masking of count operand.
9789 (define_insn "*ashl<mode>3_mask"
9790 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9792 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9795 (match_operand:SI 2 "register_operand" "c")
9796 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9797 (clobber (reg:CC FLAGS_REG))]
9798 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9799 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9800 == GET_MODE_BITSIZE (<MODE>mode)-1"
9802 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9804 [(set_attr "type" "ishift")
9805 (set_attr "mode" "<MODE>")])
9807 (define_insn "*bmi2_ashl<mode>3_1"
9808 [(set (match_operand:SWI48 0 "register_operand" "=r")
9809 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9810 (match_operand:SWI48 2 "register_operand" "r")))]
9812 "shlx\t{%2, %1, %0|%0, %1, %2}"
9813 [(set_attr "type" "ishiftx")
9814 (set_attr "mode" "<MODE>")])
9816 (define_insn "*ashl<mode>3_1"
9817 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9818 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9819 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9820 (clobber (reg:CC FLAGS_REG))]
9821 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9823 switch (get_attr_type (insn))
9830 gcc_assert (operands[2] == const1_rtx);
9831 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9832 return "add{<imodesuffix>}\t%0, %0";
9835 if (operands[2] == const1_rtx
9836 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9837 return "sal{<imodesuffix>}\t%0";
9839 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9842 [(set_attr "isa" "*,*,bmi2")
9844 (cond [(eq_attr "alternative" "1")
9845 (const_string "lea")
9846 (eq_attr "alternative" "2")
9847 (const_string "ishiftx")
9848 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9849 (match_operand 0 "register_operand"))
9850 (match_operand 2 "const1_operand"))
9851 (const_string "alu")
9853 (const_string "ishift")))
9854 (set (attr "length_immediate")
9856 (ior (eq_attr "type" "alu")
9857 (and (eq_attr "type" "ishift")
9858 (and (match_operand 2 "const1_operand")
9859 (ior (match_test "TARGET_SHIFT1")
9860 (match_test "optimize_function_for_size_p (cfun)")))))
9862 (const_string "*")))
9863 (set_attr "mode" "<MODE>")])
9865 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9867 [(set (match_operand:SWI48 0 "register_operand")
9868 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9869 (match_operand:QI 2 "register_operand")))
9870 (clobber (reg:CC FLAGS_REG))]
9871 "TARGET_BMI2 && reload_completed"
9873 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9874 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9876 (define_insn "*bmi2_ashlsi3_1_zext"
9877 [(set (match_operand:DI 0 "register_operand" "=r")
9879 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9880 (match_operand:SI 2 "register_operand" "r"))))]
9881 "TARGET_64BIT && TARGET_BMI2"
9882 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9883 [(set_attr "type" "ishiftx")
9884 (set_attr "mode" "SI")])
9886 (define_insn "*ashlsi3_1_zext"
9887 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9889 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9890 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9891 (clobber (reg:CC FLAGS_REG))]
9892 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9894 switch (get_attr_type (insn))
9901 gcc_assert (operands[2] == const1_rtx);
9902 return "add{l}\t%k0, %k0";
9905 if (operands[2] == const1_rtx
9906 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9907 return "sal{l}\t%k0";
9909 return "sal{l}\t{%2, %k0|%k0, %2}";
9912 [(set_attr "isa" "*,*,bmi2")
9914 (cond [(eq_attr "alternative" "1")
9915 (const_string "lea")
9916 (eq_attr "alternative" "2")
9917 (const_string "ishiftx")
9918 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9919 (match_operand 2 "const1_operand"))
9920 (const_string "alu")
9922 (const_string "ishift")))
9923 (set (attr "length_immediate")
9925 (ior (eq_attr "type" "alu")
9926 (and (eq_attr "type" "ishift")
9927 (and (match_operand 2 "const1_operand")
9928 (ior (match_test "TARGET_SHIFT1")
9929 (match_test "optimize_function_for_size_p (cfun)")))))
9931 (const_string "*")))
9932 (set_attr "mode" "SI")])
9934 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9936 [(set (match_operand:DI 0 "register_operand")
9938 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9939 (match_operand:QI 2 "register_operand"))))
9940 (clobber (reg:CC FLAGS_REG))]
9941 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9943 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9944 "operands[2] = gen_lowpart (SImode, operands[2]);")
9946 (define_insn "*ashlhi3_1"
9947 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9948 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9949 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9950 (clobber (reg:CC FLAGS_REG))]
9951 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9953 switch (get_attr_type (insn))
9959 gcc_assert (operands[2] == const1_rtx);
9960 return "add{w}\t%0, %0";
9963 if (operands[2] == const1_rtx
9964 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9965 return "sal{w}\t%0";
9967 return "sal{w}\t{%2, %0|%0, %2}";
9971 (cond [(eq_attr "alternative" "1")
9972 (const_string "lea")
9973 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9974 (match_operand 0 "register_operand"))
9975 (match_operand 2 "const1_operand"))
9976 (const_string "alu")
9978 (const_string "ishift")))
9979 (set (attr "length_immediate")
9981 (ior (eq_attr "type" "alu")
9982 (and (eq_attr "type" "ishift")
9983 (and (match_operand 2 "const1_operand")
9984 (ior (match_test "TARGET_SHIFT1")
9985 (match_test "optimize_function_for_size_p (cfun)")))))
9987 (const_string "*")))
9988 (set_attr "mode" "HI,SI")])
9990 (define_insn "*ashlqi3_1"
9991 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9992 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9993 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9994 (clobber (reg:CC FLAGS_REG))]
9995 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9997 switch (get_attr_type (insn))
10003 gcc_assert (operands[2] == const1_rtx);
10004 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
10005 return "add{l}\t%k0, %k0";
10007 return "add{b}\t%0, %0";
10010 if (operands[2] == const1_rtx
10011 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10013 if (get_attr_mode (insn) == MODE_SI)
10014 return "sal{l}\t%k0";
10016 return "sal{b}\t%0";
10020 if (get_attr_mode (insn) == MODE_SI)
10021 return "sal{l}\t{%2, %k0|%k0, %2}";
10023 return "sal{b}\t{%2, %0|%0, %2}";
10027 [(set (attr "type")
10028 (cond [(eq_attr "alternative" "2")
10029 (const_string "lea")
10030 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10031 (match_operand 0 "register_operand"))
10032 (match_operand 2 "const1_operand"))
10033 (const_string "alu")
10035 (const_string "ishift")))
10036 (set (attr "length_immediate")
10038 (ior (eq_attr "type" "alu")
10039 (and (eq_attr "type" "ishift")
10040 (and (match_operand 2 "const1_operand")
10041 (ior (match_test "TARGET_SHIFT1")
10042 (match_test "optimize_function_for_size_p (cfun)")))))
10044 (const_string "*")))
10045 (set_attr "mode" "QI,SI,SI")
10046 ;; Potential partial reg stall on alternative 1.
10047 (set (attr "preferred_for_speed")
10048 (cond [(eq_attr "alternative" "1")
10049 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10050 (symbol_ref "true")))])
10052 (define_insn "*ashlqi3_1_slp"
10053 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10054 (ashift:QI (match_dup 0)
10055 (match_operand:QI 1 "nonmemory_operand" "cI")))
10056 (clobber (reg:CC FLAGS_REG))]
10057 "(optimize_function_for_size_p (cfun)
10058 || !TARGET_PARTIAL_FLAG_REG_STALL
10059 || (operands[1] == const1_rtx
10061 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10063 switch (get_attr_type (insn))
10066 gcc_assert (operands[1] == const1_rtx);
10067 return "add{b}\t%0, %0";
10070 if (operands[1] == const1_rtx
10071 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10072 return "sal{b}\t%0";
10074 return "sal{b}\t{%1, %0|%0, %1}";
10077 [(set (attr "type")
10078 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10079 (match_operand 0 "register_operand"))
10080 (match_operand 1 "const1_operand"))
10081 (const_string "alu")
10083 (const_string "ishift1")))
10084 (set (attr "length_immediate")
10086 (ior (eq_attr "type" "alu")
10087 (and (eq_attr "type" "ishift1")
10088 (and (match_operand 1 "const1_operand")
10089 (ior (match_test "TARGET_SHIFT1")
10090 (match_test "optimize_function_for_size_p (cfun)")))))
10092 (const_string "*")))
10093 (set_attr "mode" "QI")])
10095 ;; Convert ashift to the lea pattern to avoid flags dependency.
10097 [(set (match_operand:SWI 0 "register_operand")
10098 (ashift:SWI (match_operand:SWI 1 "index_register_operand")
10099 (match_operand 2 "const_0_to_3_operand")))
10100 (clobber (reg:CC FLAGS_REG))]
10102 && REGNO (operands[0]) != REGNO (operands[1])"
10103 [(set (match_dup 0)
10104 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
10106 if (<MODE>mode != <LEAMODE>mode)
10108 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
10109 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
10111 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10114 ;; Convert ashift to the lea pattern to avoid flags dependency.
10116 [(set (match_operand:DI 0 "register_operand")
10118 (ashift:SI (match_operand:SI 1 "index_register_operand")
10119 (match_operand 2 "const_0_to_3_operand"))))
10120 (clobber (reg:CC FLAGS_REG))]
10121 "TARGET_64BIT && reload_completed
10122 && REGNO (operands[0]) != REGNO (operands[1])"
10123 [(set (match_dup 0)
10124 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10126 operands[1] = gen_lowpart (SImode, operands[1]);
10127 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10130 ;; This pattern can't accept a variable shift count, since shifts by
10131 ;; zero don't affect the flags. We assume that shifts by constant
10132 ;; zero are optimized away.
10133 (define_insn "*ashl<mode>3_cmp"
10134 [(set (reg FLAGS_REG)
10136 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10137 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10139 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10140 (ashift:SWI (match_dup 1) (match_dup 2)))]
10141 "(optimize_function_for_size_p (cfun)
10142 || !TARGET_PARTIAL_FLAG_REG_STALL
10143 || (operands[2] == const1_rtx
10145 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10146 && ix86_match_ccmode (insn, CCGOCmode)
10147 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10149 switch (get_attr_type (insn))
10152 gcc_assert (operands[2] == const1_rtx);
10153 return "add{<imodesuffix>}\t%0, %0";
10156 if (operands[2] == const1_rtx
10157 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10158 return "sal{<imodesuffix>}\t%0";
10160 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10163 [(set (attr "type")
10164 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10165 (match_operand 0 "register_operand"))
10166 (match_operand 2 "const1_operand"))
10167 (const_string "alu")
10169 (const_string "ishift")))
10170 (set (attr "length_immediate")
10172 (ior (eq_attr "type" "alu")
10173 (and (eq_attr "type" "ishift")
10174 (and (match_operand 2 "const1_operand")
10175 (ior (match_test "TARGET_SHIFT1")
10176 (match_test "optimize_function_for_size_p (cfun)")))))
10178 (const_string "*")))
10179 (set_attr "mode" "<MODE>")])
10181 (define_insn "*ashlsi3_cmp_zext"
10182 [(set (reg FLAGS_REG)
10184 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10185 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10187 (set (match_operand:DI 0 "register_operand" "=r")
10188 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10190 && (optimize_function_for_size_p (cfun)
10191 || !TARGET_PARTIAL_FLAG_REG_STALL
10192 || (operands[2] == const1_rtx
10194 || TARGET_DOUBLE_WITH_ADD)))
10195 && ix86_match_ccmode (insn, CCGOCmode)
10196 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10198 switch (get_attr_type (insn))
10201 gcc_assert (operands[2] == const1_rtx);
10202 return "add{l}\t%k0, %k0";
10205 if (operands[2] == const1_rtx
10206 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10207 return "sal{l}\t%k0";
10209 return "sal{l}\t{%2, %k0|%k0, %2}";
10212 [(set (attr "type")
10213 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
10214 (match_operand 2 "const1_operand"))
10215 (const_string "alu")
10217 (const_string "ishift")))
10218 (set (attr "length_immediate")
10220 (ior (eq_attr "type" "alu")
10221 (and (eq_attr "type" "ishift")
10222 (and (match_operand 2 "const1_operand")
10223 (ior (match_test "TARGET_SHIFT1")
10224 (match_test "optimize_function_for_size_p (cfun)")))))
10226 (const_string "*")))
10227 (set_attr "mode" "SI")])
10229 (define_insn "*ashl<mode>3_cconly"
10230 [(set (reg FLAGS_REG)
10232 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
10233 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10235 (clobber (match_scratch:SWI 0 "=<r>"))]
10236 "(optimize_function_for_size_p (cfun)
10237 || !TARGET_PARTIAL_FLAG_REG_STALL
10238 || (operands[2] == const1_rtx
10240 || TARGET_DOUBLE_WITH_ADD)))
10241 && ix86_match_ccmode (insn, CCGOCmode)"
10243 switch (get_attr_type (insn))
10246 gcc_assert (operands[2] == const1_rtx);
10247 return "add{<imodesuffix>}\t%0, %0";
10250 if (operands[2] == const1_rtx
10251 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10252 return "sal{<imodesuffix>}\t%0";
10254 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10257 [(set (attr "type")
10258 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10259 (match_operand 0 "register_operand"))
10260 (match_operand 2 "const1_operand"))
10261 (const_string "alu")
10263 (const_string "ishift")))
10264 (set (attr "length_immediate")
10266 (ior (eq_attr "type" "alu")
10267 (and (eq_attr "type" "ishift")
10268 (and (match_operand 2 "const1_operand")
10269 (ior (match_test "TARGET_SHIFT1")
10270 (match_test "optimize_function_for_size_p (cfun)")))))
10272 (const_string "*")))
10273 (set_attr "mode" "<MODE>")])
10275 ;; See comment above `ashl<mode>3' about how this works.
10277 (define_expand "<shift_insn><mode>3"
10278 [(set (match_operand:SDWIM 0 "<shift_operand>")
10279 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
10280 (match_operand:QI 2 "nonmemory_operand")))]
10282 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10284 ;; Avoid useless masking of count operand.
10285 (define_insn "*<shift_insn><mode>3_mask"
10286 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10288 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10291 (match_operand:SI 2 "register_operand" "c")
10292 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10293 (clobber (reg:CC FLAGS_REG))]
10294 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10295 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10296 == GET_MODE_BITSIZE (<MODE>mode)-1"
10298 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10300 [(set_attr "type" "ishift")
10301 (set_attr "mode" "<MODE>")])
10303 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
10304 [(set (match_operand:DWI 0 "register_operand" "=r")
10305 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10306 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10307 (clobber (reg:CC FLAGS_REG))]
10310 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10312 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10313 [(set_attr "type" "multi")])
10315 ;; By default we don't ask for a scratch register, because when DWImode
10316 ;; values are manipulated, registers are already at a premium. But if
10317 ;; we have one handy, we won't turn it away.
10320 [(match_scratch:DWIH 3 "r")
10321 (parallel [(set (match_operand:<DWI> 0 "register_operand")
10323 (match_operand:<DWI> 1 "register_operand")
10324 (match_operand:QI 2 "nonmemory_operand")))
10325 (clobber (reg:CC FLAGS_REG))])
10329 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
10331 (define_insn "x86_64_shrd"
10332 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10333 (ior:DI (lshiftrt:DI (match_dup 0)
10334 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10335 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10336 (minus:QI (const_int 64) (match_dup 2)))))
10337 (clobber (reg:CC FLAGS_REG))]
10339 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10340 [(set_attr "type" "ishift")
10341 (set_attr "prefix_0f" "1")
10342 (set_attr "mode" "DI")
10343 (set_attr "athlon_decode" "vector")
10344 (set_attr "amdfam10_decode" "vector")
10345 (set_attr "bdver1_decode" "vector")])
10347 (define_insn "x86_shrd"
10348 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10349 (ior:SI (lshiftrt:SI (match_dup 0)
10350 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10351 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10352 (minus:QI (const_int 32) (match_dup 2)))))
10353 (clobber (reg:CC FLAGS_REG))]
10355 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10356 [(set_attr "type" "ishift")
10357 (set_attr "prefix_0f" "1")
10358 (set_attr "mode" "SI")
10359 (set_attr "pent_pair" "np")
10360 (set_attr "athlon_decode" "vector")
10361 (set_attr "amdfam10_decode" "vector")
10362 (set_attr "bdver1_decode" "vector")])
10364 (define_insn "ashrdi3_cvt"
10365 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10366 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10367 (match_operand:QI 2 "const_int_operand")))
10368 (clobber (reg:CC FLAGS_REG))]
10369 "TARGET_64BIT && INTVAL (operands[2]) == 63
10370 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10371 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10374 sar{q}\t{%2, %0|%0, %2}"
10375 [(set_attr "type" "imovx,ishift")
10376 (set_attr "prefix_0f" "0,*")
10377 (set_attr "length_immediate" "0,*")
10378 (set_attr "modrm" "0,1")
10379 (set_attr "mode" "DI")])
10381 (define_insn "ashrsi3_cvt"
10382 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10383 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10384 (match_operand:QI 2 "const_int_operand")))
10385 (clobber (reg:CC FLAGS_REG))]
10386 "INTVAL (operands[2]) == 31
10387 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10388 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10391 sar{l}\t{%2, %0|%0, %2}"
10392 [(set_attr "type" "imovx,ishift")
10393 (set_attr "prefix_0f" "0,*")
10394 (set_attr "length_immediate" "0,*")
10395 (set_attr "modrm" "0,1")
10396 (set_attr "mode" "SI")])
10398 (define_insn "*ashrsi3_cvt_zext"
10399 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10401 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10402 (match_operand:QI 2 "const_int_operand"))))
10403 (clobber (reg:CC FLAGS_REG))]
10404 "TARGET_64BIT && INTVAL (operands[2]) == 31
10405 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10406 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10409 sar{l}\t{%2, %k0|%k0, %2}"
10410 [(set_attr "type" "imovx,ishift")
10411 (set_attr "prefix_0f" "0,*")
10412 (set_attr "length_immediate" "0,*")
10413 (set_attr "modrm" "0,1")
10414 (set_attr "mode" "SI")])
10416 (define_expand "x86_shift<mode>_adj_3"
10417 [(use (match_operand:SWI48 0 "register_operand"))
10418 (use (match_operand:SWI48 1 "register_operand"))
10419 (use (match_operand:QI 2 "register_operand"))]
10422 rtx_code_label *label = gen_label_rtx ();
10425 emit_insn (gen_testqi_ccz_1 (operands[2],
10426 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10428 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10429 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10430 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10431 gen_rtx_LABEL_REF (VOIDmode, label),
10433 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10434 JUMP_LABEL (tmp) = label;
10436 emit_move_insn (operands[0], operands[1]);
10437 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10438 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10439 emit_label (label);
10440 LABEL_NUSES (label) = 1;
10445 (define_insn "*bmi2_<shift_insn><mode>3_1"
10446 [(set (match_operand:SWI48 0 "register_operand" "=r")
10447 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10448 (match_operand:SWI48 2 "register_operand" "r")))]
10450 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10451 [(set_attr "type" "ishiftx")
10452 (set_attr "mode" "<MODE>")])
10454 (define_insn "*<shift_insn><mode>3_1"
10455 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10457 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10458 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10459 (clobber (reg:CC FLAGS_REG))]
10460 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10462 switch (get_attr_type (insn))
10468 if (operands[2] == const1_rtx
10469 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10470 return "<shift>{<imodesuffix>}\t%0";
10472 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10475 [(set_attr "isa" "*,bmi2")
10476 (set_attr "type" "ishift,ishiftx")
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 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10488 [(set (match_operand:SWI48 0 "register_operand")
10489 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10490 (match_operand:QI 2 "register_operand")))
10491 (clobber (reg:CC FLAGS_REG))]
10492 "TARGET_BMI2 && reload_completed"
10493 [(set (match_dup 0)
10494 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10495 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10497 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10498 [(set (match_operand:DI 0 "register_operand" "=r")
10500 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10501 (match_operand:SI 2 "register_operand" "r"))))]
10502 "TARGET_64BIT && TARGET_BMI2"
10503 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10504 [(set_attr "type" "ishiftx")
10505 (set_attr "mode" "SI")])
10507 (define_insn "*<shift_insn>si3_1_zext"
10508 [(set (match_operand:DI 0 "register_operand" "=r,r")
10510 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10511 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10512 (clobber (reg:CC FLAGS_REG))]
10513 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10515 switch (get_attr_type (insn))
10521 if (operands[2] == const1_rtx
10522 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10523 return "<shift>{l}\t%k0";
10525 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10528 [(set_attr "isa" "*,bmi2")
10529 (set_attr "type" "ishift,ishiftx")
10530 (set (attr "length_immediate")
10532 (and (match_operand 2 "const1_operand")
10533 (ior (match_test "TARGET_SHIFT1")
10534 (match_test "optimize_function_for_size_p (cfun)")))
10536 (const_string "*")))
10537 (set_attr "mode" "SI")])
10539 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10541 [(set (match_operand:DI 0 "register_operand")
10543 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10544 (match_operand:QI 2 "register_operand"))))
10545 (clobber (reg:CC FLAGS_REG))]
10546 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10547 [(set (match_dup 0)
10548 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10549 "operands[2] = gen_lowpart (SImode, operands[2]);")
10551 (define_insn "*<shift_insn><mode>3_1"
10552 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10554 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10555 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10556 (clobber (reg:CC FLAGS_REG))]
10557 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10559 if (operands[2] == const1_rtx
10560 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10561 return "<shift>{<imodesuffix>}\t%0";
10563 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10565 [(set_attr "type" "ishift")
10566 (set (attr "length_immediate")
10568 (and (match_operand 2 "const1_operand")
10569 (ior (match_test "TARGET_SHIFT1")
10570 (match_test "optimize_function_for_size_p (cfun)")))
10572 (const_string "*")))
10573 (set_attr "mode" "<MODE>")])
10575 (define_insn "*<shift_insn>qi3_1_slp"
10576 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10577 (any_shiftrt:QI (match_dup 0)
10578 (match_operand:QI 1 "nonmemory_operand" "cI")))
10579 (clobber (reg:CC FLAGS_REG))]
10580 "(optimize_function_for_size_p (cfun)
10581 || !TARGET_PARTIAL_REG_STALL
10582 || (operands[1] == const1_rtx
10583 && TARGET_SHIFT1))"
10585 if (operands[1] == const1_rtx
10586 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10587 return "<shift>{b}\t%0";
10589 return "<shift>{b}\t{%1, %0|%0, %1}";
10591 [(set_attr "type" "ishift1")
10592 (set (attr "length_immediate")
10594 (and (match_operand 1 "const1_operand")
10595 (ior (match_test "TARGET_SHIFT1")
10596 (match_test "optimize_function_for_size_p (cfun)")))
10598 (const_string "*")))
10599 (set_attr "mode" "QI")])
10601 ;; This pattern can't accept a variable shift count, since shifts by
10602 ;; zero don't affect the flags. We assume that shifts by constant
10603 ;; zero are optimized away.
10604 (define_insn "*<shift_insn><mode>3_cmp"
10605 [(set (reg FLAGS_REG)
10608 (match_operand:SWI 1 "nonimmediate_operand" "0")
10609 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10611 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10612 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10613 "(optimize_function_for_size_p (cfun)
10614 || !TARGET_PARTIAL_FLAG_REG_STALL
10615 || (operands[2] == const1_rtx
10617 && ix86_match_ccmode (insn, CCGOCmode)
10618 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10620 if (operands[2] == const1_rtx
10621 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10622 return "<shift>{<imodesuffix>}\t%0";
10624 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10626 [(set_attr "type" "ishift")
10627 (set (attr "length_immediate")
10629 (and (match_operand 2 "const1_operand")
10630 (ior (match_test "TARGET_SHIFT1")
10631 (match_test "optimize_function_for_size_p (cfun)")))
10633 (const_string "*")))
10634 (set_attr "mode" "<MODE>")])
10636 (define_insn "*<shift_insn>si3_cmp_zext"
10637 [(set (reg FLAGS_REG)
10639 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10640 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10642 (set (match_operand:DI 0 "register_operand" "=r")
10643 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10645 && (optimize_function_for_size_p (cfun)
10646 || !TARGET_PARTIAL_FLAG_REG_STALL
10647 || (operands[2] == const1_rtx
10649 && ix86_match_ccmode (insn, CCGOCmode)
10650 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10652 if (operands[2] == const1_rtx
10653 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10654 return "<shift>{l}\t%k0";
10656 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10658 [(set_attr "type" "ishift")
10659 (set (attr "length_immediate")
10661 (and (match_operand 2 "const1_operand")
10662 (ior (match_test "TARGET_SHIFT1")
10663 (match_test "optimize_function_for_size_p (cfun)")))
10665 (const_string "*")))
10666 (set_attr "mode" "SI")])
10668 (define_insn "*<shift_insn><mode>3_cconly"
10669 [(set (reg FLAGS_REG)
10672 (match_operand:SWI 1 "register_operand" "0")
10673 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10675 (clobber (match_scratch:SWI 0 "=<r>"))]
10676 "(optimize_function_for_size_p (cfun)
10677 || !TARGET_PARTIAL_FLAG_REG_STALL
10678 || (operands[2] == const1_rtx
10680 && ix86_match_ccmode (insn, CCGOCmode)"
10682 if (operands[2] == const1_rtx
10683 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10684 return "<shift>{<imodesuffix>}\t%0";
10686 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10688 [(set_attr "type" "ishift")
10689 (set (attr "length_immediate")
10691 (and (match_operand 2 "const1_operand")
10692 (ior (match_test "TARGET_SHIFT1")
10693 (match_test "optimize_function_for_size_p (cfun)")))
10695 (const_string "*")))
10696 (set_attr "mode" "<MODE>")])
10698 ;; Rotate instructions
10700 (define_expand "<rotate_insn>ti3"
10701 [(set (match_operand:TI 0 "register_operand")
10702 (any_rotate:TI (match_operand:TI 1 "register_operand")
10703 (match_operand:QI 2 "nonmemory_operand")))]
10706 if (const_1_to_63_operand (operands[2], VOIDmode))
10707 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10708 (operands[0], operands[1], operands[2]));
10715 (define_expand "<rotate_insn>di3"
10716 [(set (match_operand:DI 0 "shiftdi_operand")
10717 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10718 (match_operand:QI 2 "nonmemory_operand")))]
10722 ix86_expand_binary_operator (<CODE>, DImode, operands);
10723 else if (const_1_to_31_operand (operands[2], VOIDmode))
10724 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10725 (operands[0], operands[1], operands[2]));
10732 (define_expand "<rotate_insn><mode>3"
10733 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10734 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10735 (match_operand:QI 2 "nonmemory_operand")))]
10737 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10739 ;; Avoid useless masking of count operand.
10740 (define_insn "*<rotate_insn><mode>3_mask"
10741 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10743 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10746 (match_operand:SI 2 "register_operand" "c")
10747 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10748 (clobber (reg:CC FLAGS_REG))]
10749 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10750 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10751 == GET_MODE_BITSIZE (<MODE>mode)-1"
10753 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10755 [(set_attr "type" "rotate")
10756 (set_attr "mode" "<MODE>")])
10758 ;; Implement rotation using two double-precision
10759 ;; shift instructions and a scratch register.
10761 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10762 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10763 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10764 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10765 (clobber (reg:CC FLAGS_REG))
10766 (clobber (match_scratch:DWIH 3 "=&r"))]
10770 [(set (match_dup 3) (match_dup 4))
10772 [(set (match_dup 4)
10773 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10774 (lshiftrt:DWIH (match_dup 5)
10775 (minus:QI (match_dup 6) (match_dup 2)))))
10776 (clobber (reg:CC FLAGS_REG))])
10778 [(set (match_dup 5)
10779 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10780 (lshiftrt:DWIH (match_dup 3)
10781 (minus:QI (match_dup 6) (match_dup 2)))))
10782 (clobber (reg:CC FLAGS_REG))])]
10784 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10786 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10789 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10790 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10791 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10792 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10793 (clobber (reg:CC FLAGS_REG))
10794 (clobber (match_scratch:DWIH 3 "=&r"))]
10798 [(set (match_dup 3) (match_dup 4))
10800 [(set (match_dup 4)
10801 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10802 (ashift:DWIH (match_dup 5)
10803 (minus:QI (match_dup 6) (match_dup 2)))))
10804 (clobber (reg:CC FLAGS_REG))])
10806 [(set (match_dup 5)
10807 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10808 (ashift:DWIH (match_dup 3)
10809 (minus:QI (match_dup 6) (match_dup 2)))))
10810 (clobber (reg:CC FLAGS_REG))])]
10812 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10814 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10817 (define_insn "*bmi2_rorx<mode>3_1"
10818 [(set (match_operand:SWI48 0 "register_operand" "=r")
10819 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10820 (match_operand:QI 2 "immediate_operand" "<S>")))]
10822 "rorx\t{%2, %1, %0|%0, %1, %2}"
10823 [(set_attr "type" "rotatex")
10824 (set_attr "mode" "<MODE>")])
10826 (define_insn "*<rotate_insn><mode>3_1"
10827 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10829 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10830 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10831 (clobber (reg:CC FLAGS_REG))]
10832 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10834 switch (get_attr_type (insn))
10840 if (operands[2] == const1_rtx
10841 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10842 return "<rotate>{<imodesuffix>}\t%0";
10844 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10847 [(set_attr "isa" "*,bmi2")
10848 (set_attr "type" "rotate,rotatex")
10849 (set (attr "length_immediate")
10851 (and (eq_attr "type" "rotate")
10852 (and (match_operand 2 "const1_operand")
10853 (ior (match_test "TARGET_SHIFT1")
10854 (match_test "optimize_function_for_size_p (cfun)"))))
10856 (const_string "*")))
10857 (set_attr "mode" "<MODE>")])
10859 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10861 [(set (match_operand:SWI48 0 "register_operand")
10862 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10863 (match_operand:QI 2 "immediate_operand")))
10864 (clobber (reg:CC FLAGS_REG))]
10865 "TARGET_BMI2 && reload_completed"
10866 [(set (match_dup 0)
10867 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10870 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10874 [(set (match_operand:SWI48 0 "register_operand")
10875 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10876 (match_operand:QI 2 "immediate_operand")))
10877 (clobber (reg:CC FLAGS_REG))]
10878 "TARGET_BMI2 && reload_completed"
10879 [(set (match_dup 0)
10880 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10882 (define_insn "*bmi2_rorxsi3_1_zext"
10883 [(set (match_operand:DI 0 "register_operand" "=r")
10885 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10886 (match_operand:QI 2 "immediate_operand" "I"))))]
10887 "TARGET_64BIT && TARGET_BMI2"
10888 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10889 [(set_attr "type" "rotatex")
10890 (set_attr "mode" "SI")])
10892 (define_insn "*<rotate_insn>si3_1_zext"
10893 [(set (match_operand:DI 0 "register_operand" "=r,r")
10895 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10896 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10897 (clobber (reg:CC FLAGS_REG))]
10898 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10900 switch (get_attr_type (insn))
10906 if (operands[2] == const1_rtx
10907 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10908 return "<rotate>{l}\t%k0";
10910 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10913 [(set_attr "isa" "*,bmi2")
10914 (set_attr "type" "rotate,rotatex")
10915 (set (attr "length_immediate")
10917 (and (eq_attr "type" "rotate")
10918 (and (match_operand 2 "const1_operand")
10919 (ior (match_test "TARGET_SHIFT1")
10920 (match_test "optimize_function_for_size_p (cfun)"))))
10922 (const_string "*")))
10923 (set_attr "mode" "SI")])
10925 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10927 [(set (match_operand:DI 0 "register_operand")
10929 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10930 (match_operand:QI 2 "immediate_operand"))))
10931 (clobber (reg:CC FLAGS_REG))]
10932 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10933 [(set (match_dup 0)
10934 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10937 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10941 [(set (match_operand:DI 0 "register_operand")
10943 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10944 (match_operand:QI 2 "immediate_operand"))))
10945 (clobber (reg:CC FLAGS_REG))]
10946 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10947 [(set (match_dup 0)
10948 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10950 (define_insn "*<rotate_insn><mode>3_1"
10951 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10952 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10953 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10954 (clobber (reg:CC FLAGS_REG))]
10955 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10957 if (operands[2] == const1_rtx
10958 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10959 return "<rotate>{<imodesuffix>}\t%0";
10961 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10963 [(set_attr "type" "rotate")
10964 (set (attr "length_immediate")
10966 (and (match_operand 2 "const1_operand")
10967 (ior (match_test "TARGET_SHIFT1")
10968 (match_test "optimize_function_for_size_p (cfun)")))
10970 (const_string "*")))
10971 (set_attr "mode" "<MODE>")])
10973 (define_insn "*<rotate_insn>qi3_1_slp"
10974 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10975 (any_rotate:QI (match_dup 0)
10976 (match_operand:QI 1 "nonmemory_operand" "cI")))
10977 (clobber (reg:CC FLAGS_REG))]
10978 "(optimize_function_for_size_p (cfun)
10979 || !TARGET_PARTIAL_REG_STALL
10980 || (operands[1] == const1_rtx
10981 && TARGET_SHIFT1))"
10983 if (operands[1] == const1_rtx
10984 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10985 return "<rotate>{b}\t%0";
10987 return "<rotate>{b}\t{%1, %0|%0, %1}";
10989 [(set_attr "type" "rotate1")
10990 (set (attr "length_immediate")
10992 (and (match_operand 1 "const1_operand")
10993 (ior (match_test "TARGET_SHIFT1")
10994 (match_test "optimize_function_for_size_p (cfun)")))
10996 (const_string "*")))
10997 (set_attr "mode" "QI")])
11000 [(set (match_operand:HI 0 "register_operand")
11001 (any_rotate:HI (match_dup 0) (const_int 8)))
11002 (clobber (reg:CC FLAGS_REG))]
11004 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
11005 [(parallel [(set (strict_low_part (match_dup 0))
11006 (bswap:HI (match_dup 0)))
11007 (clobber (reg:CC FLAGS_REG))])])
11009 ;; Bit set / bit test instructions
11011 ;; %%% bts, btr, btc, bt.
11012 ;; In general these instructions are *slow* when applied to memory,
11013 ;; since they enforce atomic operation. When applied to registers,
11014 ;; it depends on the cpu implementation. They're never faster than
11015 ;; the corresponding and/ior/xor operations, so with 32-bit there's
11016 ;; no point. But in 64-bit, we can't hold the relevant immediates
11017 ;; within the instruction itself, so operating on bits in the high
11018 ;; 32-bits of a register becomes easier.
11020 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
11021 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
11022 ;; negdf respectively, so they can never be disabled entirely.
11024 (define_insn "*btsq"
11025 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
11027 (match_operand 1 "const_0_to_63_operand" "J"))
11029 (clobber (reg:CC FLAGS_REG))]
11030 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11031 "bts{q}\t{%1, %0|%0, %1}"
11032 [(set_attr "type" "alu1")
11033 (set_attr "prefix_0f" "1")
11034 (set_attr "znver1_decode" "double")
11035 (set_attr "mode" "DI")])
11037 (define_insn "*btrq"
11038 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
11040 (match_operand 1 "const_0_to_63_operand" "J"))
11042 (clobber (reg:CC FLAGS_REG))]
11043 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11044 "btr{q}\t{%1, %0|%0, %1}"
11045 [(set_attr "type" "alu1")
11046 (set_attr "prefix_0f" "1")
11047 (set_attr "znver1_decode" "double")
11048 (set_attr "mode" "DI")])
11050 (define_insn "*btcq"
11051 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
11053 (match_operand 1 "const_0_to_63_operand" "J"))
11054 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
11055 (clobber (reg:CC FLAGS_REG))]
11056 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11057 "btc{q}\t{%1, %0|%0, %1}"
11058 [(set_attr "type" "alu1")
11059 (set_attr "prefix_0f" "1")
11060 (set_attr "znver1_decode" "double")
11061 (set_attr "mode" "DI")])
11063 ;; Allow Nocona to avoid these instructions if a register is available.
11066 [(match_scratch:DI 2 "r")
11067 (parallel [(set (zero_extract:DI
11068 (match_operand:DI 0 "register_operand")
11070 (match_operand 1 "const_0_to_63_operand"))
11072 (clobber (reg:CC FLAGS_REG))])]
11073 "TARGET_64BIT && !TARGET_USE_BT"
11074 [(parallel [(set (match_dup 0)
11075 (ior:DI (match_dup 0) (match_dup 3)))
11076 (clobber (reg:CC FLAGS_REG))])]
11078 int i = INTVAL (operands[1]);
11080 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11082 if (!x86_64_immediate_operand (operands[3], DImode))
11084 emit_move_insn (operands[2], operands[3]);
11085 operands[3] = operands[2];
11090 [(match_scratch:DI 2 "r")
11091 (parallel [(set (zero_extract:DI
11092 (match_operand:DI 0 "register_operand")
11094 (match_operand 1 "const_0_to_63_operand"))
11096 (clobber (reg:CC FLAGS_REG))])]
11097 "TARGET_64BIT && !TARGET_USE_BT"
11098 [(parallel [(set (match_dup 0)
11099 (and:DI (match_dup 0) (match_dup 3)))
11100 (clobber (reg:CC FLAGS_REG))])]
11102 int i = INTVAL (operands[1]);
11104 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
11106 if (!x86_64_immediate_operand (operands[3], DImode))
11108 emit_move_insn (operands[2], operands[3]);
11109 operands[3] = operands[2];
11114 [(match_scratch:DI 2 "r")
11115 (parallel [(set (zero_extract:DI
11116 (match_operand:DI 0 "register_operand")
11118 (match_operand 1 "const_0_to_63_operand"))
11119 (not:DI (zero_extract:DI
11120 (match_dup 0) (const_int 1) (match_dup 1))))
11121 (clobber (reg:CC FLAGS_REG))])]
11122 "TARGET_64BIT && !TARGET_USE_BT"
11123 [(parallel [(set (match_dup 0)
11124 (xor:DI (match_dup 0) (match_dup 3)))
11125 (clobber (reg:CC FLAGS_REG))])]
11127 int i = INTVAL (operands[1]);
11129 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11131 if (!x86_64_immediate_operand (operands[3], DImode))
11133 emit_move_insn (operands[2], operands[3]);
11134 operands[3] = operands[2];
11138 (define_insn "*bt<mode>"
11139 [(set (reg:CCC FLAGS_REG)
11141 (zero_extract:SWI48
11142 (match_operand:SWI48 0 "register_operand" "r")
11144 (match_operand:SI 1 "nonmemory_operand" "rN"))
11148 switch (get_attr_mode (insn))
11151 return "bt{l}\t{%1, %k0|%k0, %1}";
11154 return "bt{q}\t{%q1, %0|%0, %q1}";
11157 gcc_unreachable ();
11160 [(set_attr "type" "alu1")
11161 (set_attr "prefix_0f" "1")
11164 (and (match_test "CONST_INT_P (operands[1])")
11165 (match_test "INTVAL (operands[1]) < 32"))
11166 (const_string "SI")
11167 (const_string "<MODE>")))])
11169 (define_insn_and_split "*jcc_bt<mode>"
11171 (if_then_else (match_operator 0 "bt_comparison_operator"
11172 [(zero_extract:SWI48
11173 (match_operand:SWI48 1 "register_operand")
11175 (match_operand:SI 2 "nonmemory_operand"))
11177 (label_ref (match_operand 3))
11179 (clobber (reg:CC FLAGS_REG))]
11180 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11181 && (CONST_INT_P (operands[2])
11182 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
11183 && INTVAL (operands[2])
11184 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
11185 : register_operand (operands[2], SImode))
11186 && can_create_pseudo_p ()"
11189 [(set (reg:CCC FLAGS_REG)
11191 (zero_extract:SWI48
11197 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11198 (label_ref (match_dup 3))
11201 operands[0] = shallow_copy_rtx (operands[0]);
11202 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11205 (define_insn_and_split "*jcc_bt<mode>_1"
11207 (if_then_else (match_operator 0 "bt_comparison_operator"
11208 [(zero_extract:SWI48
11209 (match_operand:SWI48 1 "register_operand")
11212 (match_operand:QI 2 "register_operand")))
11214 (label_ref (match_operand 3))
11216 (clobber (reg:CC FLAGS_REG))]
11217 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11218 && can_create_pseudo_p ()"
11221 [(set (reg:CCC FLAGS_REG)
11223 (zero_extract:SWI48
11229 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11230 (label_ref (match_dup 3))
11233 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
11234 operands[0] = shallow_copy_rtx (operands[0]);
11235 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11238 ;; Avoid useless masking of bit offset operand.
11239 (define_insn_and_split "*jcc_bt<mode>_mask"
11241 (if_then_else (match_operator 0 "bt_comparison_operator"
11242 [(zero_extract:SWI48
11243 (match_operand:SWI48 1 "register_operand")
11246 (match_operand:SI 2 "register_operand")
11247 (match_operand 3 "const_int_operand")))])
11248 (label_ref (match_operand 4))
11250 (clobber (reg:CC FLAGS_REG))]
11251 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11252 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11253 == GET_MODE_BITSIZE (<MODE>mode)-1
11254 && can_create_pseudo_p ()"
11257 [(set (reg:CCC FLAGS_REG)
11259 (zero_extract:SWI48
11265 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11266 (label_ref (match_dup 4))
11269 operands[0] = shallow_copy_rtx (operands[0]);
11270 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11273 ;; Store-flag instructions.
11275 ;; For all sCOND expanders, also expand the compare or test insn that
11276 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
11278 (define_insn_and_split "*setcc_di_1"
11279 [(set (match_operand:DI 0 "register_operand" "=q")
11280 (match_operator:DI 1 "ix86_comparison_operator"
11281 [(reg FLAGS_REG) (const_int 0)]))]
11282 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
11284 "&& reload_completed"
11285 [(set (match_dup 2) (match_dup 1))
11286 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
11288 operands[1] = shallow_copy_rtx (operands[1]);
11289 PUT_MODE (operands[1], QImode);
11290 operands[2] = gen_lowpart (QImode, operands[0]);
11293 (define_insn_and_split "*setcc_si_1_and"
11294 [(set (match_operand:SI 0 "register_operand" "=q")
11295 (match_operator:SI 1 "ix86_comparison_operator"
11296 [(reg FLAGS_REG) (const_int 0)]))
11297 (clobber (reg:CC FLAGS_REG))]
11298 "!TARGET_PARTIAL_REG_STALL
11299 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
11301 "&& reload_completed"
11302 [(set (match_dup 2) (match_dup 1))
11303 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
11304 (clobber (reg:CC FLAGS_REG))])]
11306 operands[1] = shallow_copy_rtx (operands[1]);
11307 PUT_MODE (operands[1], QImode);
11308 operands[2] = gen_lowpart (QImode, operands[0]);
11311 (define_insn_and_split "*setcc_si_1_movzbl"
11312 [(set (match_operand:SI 0 "register_operand" "=q")
11313 (match_operator:SI 1 "ix86_comparison_operator"
11314 [(reg FLAGS_REG) (const_int 0)]))]
11315 "!TARGET_PARTIAL_REG_STALL
11316 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
11318 "&& reload_completed"
11319 [(set (match_dup 2) (match_dup 1))
11320 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
11322 operands[1] = shallow_copy_rtx (operands[1]);
11323 PUT_MODE (operands[1], QImode);
11324 operands[2] = gen_lowpart (QImode, operands[0]);
11327 (define_insn "*setcc_qi"
11328 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11329 (match_operator:QI 1 "ix86_comparison_operator"
11330 [(reg FLAGS_REG) (const_int 0)]))]
11333 [(set_attr "type" "setcc")
11334 (set_attr "mode" "QI")])
11336 (define_insn "*setcc_qi_slp"
11337 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11338 (match_operator:QI 1 "ix86_comparison_operator"
11339 [(reg FLAGS_REG) (const_int 0)]))]
11342 [(set_attr "type" "setcc")
11343 (set_attr "mode" "QI")])
11345 ;; In general it is not safe to assume too much about CCmode registers,
11346 ;; so simplify-rtx stops when it sees a second one. Under certain
11347 ;; conditions this is safe on x86, so help combine not create
11354 [(set (match_operand:QI 0 "nonimmediate_operand")
11355 (ne:QI (match_operator 1 "ix86_comparison_operator"
11356 [(reg FLAGS_REG) (const_int 0)])
11359 [(set (match_dup 0) (match_dup 1))]
11361 operands[1] = shallow_copy_rtx (operands[1]);
11362 PUT_MODE (operands[1], QImode);
11366 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11367 (ne:QI (match_operator 1 "ix86_comparison_operator"
11368 [(reg FLAGS_REG) (const_int 0)])
11371 [(set (match_dup 0) (match_dup 1))]
11373 operands[1] = shallow_copy_rtx (operands[1]);
11374 PUT_MODE (operands[1], QImode);
11378 [(set (match_operand:QI 0 "nonimmediate_operand")
11379 (eq:QI (match_operator 1 "ix86_comparison_operator"
11380 [(reg FLAGS_REG) (const_int 0)])
11383 [(set (match_dup 0) (match_dup 1))]
11385 operands[1] = shallow_copy_rtx (operands[1]);
11386 PUT_MODE (operands[1], QImode);
11387 PUT_CODE (operands[1],
11388 ix86_reverse_condition (GET_CODE (operands[1]),
11389 GET_MODE (XEXP (operands[1], 0))));
11391 /* Make sure that (a) the CCmode we have for the flags is strong
11392 enough for the reversed compare or (b) we have a valid FP compare. */
11393 if (! ix86_comparison_operator (operands[1], VOIDmode))
11398 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11399 (eq:QI (match_operator 1 "ix86_comparison_operator"
11400 [(reg FLAGS_REG) (const_int 0)])
11403 [(set (match_dup 0) (match_dup 1))]
11405 operands[1] = shallow_copy_rtx (operands[1]);
11406 PUT_MODE (operands[1], QImode);
11407 PUT_CODE (operands[1],
11408 ix86_reverse_condition (GET_CODE (operands[1]),
11409 GET_MODE (XEXP (operands[1], 0))));
11411 /* Make sure that (a) the CCmode we have for the flags is strong
11412 enough for the reversed compare or (b) we have a valid FP compare. */
11413 if (! ix86_comparison_operator (operands[1], VOIDmode))
11417 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
11418 ;; subsequent logical operations are used to imitate conditional moves.
11419 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
11422 (define_insn "setcc_<mode>_sse"
11423 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
11424 (match_operator:MODEF 3 "sse_comparison_operator"
11425 [(match_operand:MODEF 1 "register_operand" "0,x")
11426 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
11427 "SSE_FLOAT_MODE_P (<MODE>mode)"
11429 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
11430 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
11431 [(set_attr "isa" "noavx,avx")
11432 (set_attr "type" "ssecmp")
11433 (set_attr "length_immediate" "1")
11434 (set_attr "prefix" "orig,vex")
11435 (set_attr "mode" "<MODE>")])
11437 ;; Basic conditional jump instructions.
11438 ;; We ignore the overflow flag for signed branch instructions.
11440 (define_insn "*jcc_1"
11442 (if_then_else (match_operator 1 "ix86_comparison_operator"
11443 [(reg FLAGS_REG) (const_int 0)])
11444 (label_ref (match_operand 0))
11448 [(set_attr "type" "ibr")
11449 (set_attr "modrm" "0")
11450 (set (attr "length")
11452 (and (ge (minus (match_dup 0) (pc))
11454 (lt (minus (match_dup 0) (pc))
11458 (set_attr "maybe_prefix_bnd" "1")])
11460 (define_insn "*jcc_2"
11462 (if_then_else (match_operator 1 "ix86_comparison_operator"
11463 [(reg FLAGS_REG) (const_int 0)])
11465 (label_ref (match_operand 0))))]
11468 [(set_attr "type" "ibr")
11469 (set_attr "modrm" "0")
11470 (set (attr "length")
11472 (and (ge (minus (match_dup 0) (pc))
11474 (lt (minus (match_dup 0) (pc))
11478 (set_attr "maybe_prefix_bnd" "1")])
11480 ;; In general it is not safe to assume too much about CCmode registers,
11481 ;; so simplify-rtx stops when it sees a second one. Under certain
11482 ;; conditions this is safe on x86, so help combine not create
11490 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11491 [(reg FLAGS_REG) (const_int 0)])
11493 (label_ref (match_operand 1))
11497 (if_then_else (match_dup 0)
11498 (label_ref (match_dup 1))
11501 operands[0] = shallow_copy_rtx (operands[0]);
11502 PUT_MODE (operands[0], VOIDmode);
11507 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11508 [(reg FLAGS_REG) (const_int 0)])
11510 (label_ref (match_operand 1))
11514 (if_then_else (match_dup 0)
11515 (label_ref (match_dup 1))
11518 operands[0] = shallow_copy_rtx (operands[0]);
11519 PUT_MODE (operands[0], VOIDmode);
11520 PUT_CODE (operands[0],
11521 ix86_reverse_condition (GET_CODE (operands[0]),
11522 GET_MODE (XEXP (operands[0], 0))));
11524 /* Make sure that (a) the CCmode we have for the flags is strong
11525 enough for the reversed compare or (b) we have a valid FP compare. */
11526 if (! ix86_comparison_operator (operands[0], VOIDmode))
11530 ;; Define combination compare-and-branch fp compare instructions to help
11533 (define_insn "*jcc<mode>_0_i387"
11535 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11536 [(match_operand:X87MODEF 1 "register_operand" "f")
11537 (match_operand:X87MODEF 2 "const0_operand")])
11538 (label_ref (match_operand 3))
11540 (clobber (reg:CCFP FPSR_REG))
11541 (clobber (reg:CCFP FLAGS_REG))
11542 (clobber (match_scratch:HI 4 "=a"))]
11543 "TARGET_80387 && !TARGET_CMOVE"
11546 (define_insn "*jcc<mode>_0_r_i387"
11548 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11549 [(match_operand:X87MODEF 1 "register_operand" "f")
11550 (match_operand:X87MODEF 2 "const0_operand")])
11552 (label_ref (match_operand 3))))
11553 (clobber (reg:CCFP FPSR_REG))
11554 (clobber (reg:CCFP FLAGS_REG))
11555 (clobber (match_scratch:HI 4 "=a"))]
11556 "TARGET_80387 && !TARGET_CMOVE"
11559 (define_insn "*jccxf_i387"
11561 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11562 [(match_operand:XF 1 "register_operand" "f")
11563 (match_operand:XF 2 "register_operand" "f")])
11564 (label_ref (match_operand 3))
11566 (clobber (reg:CCFP FPSR_REG))
11567 (clobber (reg:CCFP FLAGS_REG))
11568 (clobber (match_scratch:HI 4 "=a"))]
11569 "TARGET_80387 && !TARGET_CMOVE"
11572 (define_insn "*jccxf_r_i387"
11574 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11575 [(match_operand:XF 1 "register_operand" "f")
11576 (match_operand:XF 2 "register_operand" "f")])
11578 (label_ref (match_operand 3))))
11579 (clobber (reg:CCFP FPSR_REG))
11580 (clobber (reg:CCFP FLAGS_REG))
11581 (clobber (match_scratch:HI 4 "=a"))]
11582 "TARGET_80387 && !TARGET_CMOVE"
11585 (define_insn "*jcc<mode>_i387"
11587 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11588 [(match_operand:MODEF 1 "register_operand" "f")
11589 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11590 (label_ref (match_operand 3))
11592 (clobber (reg:CCFP FPSR_REG))
11593 (clobber (reg:CCFP FLAGS_REG))
11594 (clobber (match_scratch:HI 4 "=a"))]
11595 "TARGET_80387 && !TARGET_CMOVE"
11598 (define_insn "*jcc<mode>_r_i387"
11600 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11601 [(match_operand:MODEF 1 "register_operand" "f")
11602 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11604 (label_ref (match_operand 3))))
11605 (clobber (reg:CCFP FPSR_REG))
11606 (clobber (reg:CCFP FLAGS_REG))
11607 (clobber (match_scratch:HI 4 "=a"))]
11608 "TARGET_80387 && !TARGET_CMOVE"
11611 (define_insn "*jccu<mode>_i387"
11613 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11614 [(match_operand:X87MODEF 1 "register_operand" "f")
11615 (match_operand:X87MODEF 2 "register_operand" "f")])
11616 (label_ref (match_operand 3))
11618 (clobber (reg:CCFP FPSR_REG))
11619 (clobber (reg:CCFP FLAGS_REG))
11620 (clobber (match_scratch:HI 4 "=a"))]
11621 "TARGET_80387 && !TARGET_CMOVE"
11624 (define_insn "*jccu<mode>_r_i387"
11626 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11627 [(match_operand:X87MODEF 1 "register_operand" "f")
11628 (match_operand:X87MODEF 2 "register_operand" "f")])
11630 (label_ref (match_operand 3))))
11631 (clobber (reg:CCFP FPSR_REG))
11632 (clobber (reg:CCFP FLAGS_REG))
11633 (clobber (match_scratch:HI 4 "=a"))]
11634 "TARGET_80387 && !TARGET_CMOVE"
11639 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11640 [(match_operand:X87MODEF 1 "register_operand")
11641 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11643 (match_operand 4)))
11644 (clobber (reg:CCFP FPSR_REG))
11645 (clobber (reg:CCFP FLAGS_REG))]
11646 "TARGET_80387 && !TARGET_CMOVE
11647 && reload_completed"
11650 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11651 operands[3], operands[4], NULL_RTX);
11657 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11658 [(match_operand:X87MODEF 1 "register_operand")
11659 (match_operand:X87MODEF 2 "general_operand")])
11661 (match_operand 4)))
11662 (clobber (reg:CCFP FPSR_REG))
11663 (clobber (reg:CCFP FLAGS_REG))
11664 (clobber (match_scratch:HI 5))]
11665 "TARGET_80387 && !TARGET_CMOVE
11666 && reload_completed"
11669 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11670 operands[3], operands[4], operands[5]);
11674 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11675 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11676 ;; with a precedence over other operators and is always put in the first
11677 ;; place. Swap condition and operands to match ficom instruction.
11679 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11682 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11683 [(match_operator:X87MODEF 1 "float_operator"
11684 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11685 (match_operand:X87MODEF 3 "register_operand" "f")])
11686 (label_ref (match_operand 4))
11688 (clobber (reg:CCFP FPSR_REG))
11689 (clobber (reg:CCFP FLAGS_REG))
11690 (clobber (match_scratch:HI 5 "=a"))]
11691 "TARGET_80387 && !TARGET_CMOVE
11692 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11693 || optimize_function_for_size_p (cfun))"
11696 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11699 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11700 [(match_operator:X87MODEF 1 "float_operator"
11701 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11702 (match_operand:X87MODEF 3 "register_operand" "f")])
11704 (label_ref (match_operand 4))))
11705 (clobber (reg:CCFP FPSR_REG))
11706 (clobber (reg:CCFP FLAGS_REG))
11707 (clobber (match_scratch:HI 5 "=a"))]
11708 "TARGET_80387 && !TARGET_CMOVE
11709 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11710 || optimize_function_for_size_p (cfun))"
11716 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11717 [(match_operator:X87MODEF 1 "float_operator"
11718 [(match_operand:SWI24 2 "memory_operand")])
11719 (match_operand:X87MODEF 3 "register_operand")])
11721 (match_operand 5)))
11722 (clobber (reg:CCFP FPSR_REG))
11723 (clobber (reg:CCFP FLAGS_REG))
11724 (clobber (match_scratch:HI 6))]
11725 "TARGET_80387 && !TARGET_CMOVE
11726 && reload_completed"
11729 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11730 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11731 operands[4], operands[5], operands[6]);
11735 ;; Unconditional and other jump instructions
11737 (define_insn "jump"
11739 (label_ref (match_operand 0)))]
11742 [(set_attr "type" "ibr")
11743 (set_attr "modrm" "0")
11744 (set (attr "length")
11746 (and (ge (minus (match_dup 0) (pc))
11748 (lt (minus (match_dup 0) (pc))
11752 (set_attr "maybe_prefix_bnd" "1")])
11754 (define_expand "indirect_jump"
11755 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11759 operands[0] = convert_memory_address (word_mode, operands[0]);
11762 (define_insn "*indirect_jump"
11763 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11766 [(set_attr "type" "ibr")
11767 (set_attr "length_immediate" "0")
11768 (set_attr "maybe_prefix_bnd" "1")])
11770 (define_expand "tablejump"
11771 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11772 (use (label_ref (match_operand 1)))])]
11775 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11776 relative. Convert the relative address to an absolute address. */
11780 enum rtx_code code;
11782 /* We can't use @GOTOFF for text labels on VxWorks;
11783 see gotoff_operand. */
11784 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11788 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11790 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11794 op1 = pic_offset_table_rtx;
11799 op0 = pic_offset_table_rtx;
11803 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11808 operands[0] = convert_memory_address (word_mode, operands[0]);
11811 (define_insn "*tablejump_1"
11812 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11813 (use (label_ref (match_operand 1)))]
11816 [(set_attr "type" "ibr")
11817 (set_attr "length_immediate" "0")
11818 (set_attr "maybe_prefix_bnd" "1")])
11820 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11823 [(set (reg FLAGS_REG) (match_operand 0))
11824 (set (match_operand:QI 1 "register_operand")
11825 (match_operator:QI 2 "ix86_comparison_operator"
11826 [(reg FLAGS_REG) (const_int 0)]))
11827 (set (match_operand 3 "any_QIreg_operand")
11828 (zero_extend (match_dup 1)))]
11829 "(peep2_reg_dead_p (3, operands[1])
11830 || operands_match_p (operands[1], operands[3]))
11831 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11832 [(set (match_dup 4) (match_dup 0))
11833 (set (strict_low_part (match_dup 5))
11836 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11837 operands[5] = gen_lowpart (QImode, operands[3]);
11838 ix86_expand_clear (operands[3]);
11842 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11843 (match_operand 4)])
11844 (set (match_operand:QI 1 "register_operand")
11845 (match_operator:QI 2 "ix86_comparison_operator"
11846 [(reg FLAGS_REG) (const_int 0)]))
11847 (set (match_operand 3 "any_QIreg_operand")
11848 (zero_extend (match_dup 1)))]
11849 "(peep2_reg_dead_p (3, operands[1])
11850 || operands_match_p (operands[1], operands[3]))
11851 && ! reg_overlap_mentioned_p (operands[3], operands[0])
11852 && ! (GET_CODE (operands[4]) == CLOBBER
11853 && reg_mentioned_p (operands[3], operands[4]))"
11854 [(parallel [(set (match_dup 5) (match_dup 0))
11856 (set (strict_low_part (match_dup 6))
11859 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11860 operands[6] = gen_lowpart (QImode, operands[3]);
11861 ix86_expand_clear (operands[3]);
11864 ;; Similar, but match zero extend with andsi3.
11867 [(set (reg FLAGS_REG) (match_operand 0))
11868 (set (match_operand:QI 1 "register_operand")
11869 (match_operator:QI 2 "ix86_comparison_operator"
11870 [(reg FLAGS_REG) (const_int 0)]))
11871 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
11872 (and:SI (match_dup 3) (const_int 255)))
11873 (clobber (reg:CC FLAGS_REG))])]
11874 "REGNO (operands[1]) == REGNO (operands[3])
11875 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11876 [(set (match_dup 4) (match_dup 0))
11877 (set (strict_low_part (match_dup 5))
11880 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11881 operands[5] = gen_lowpart (QImode, operands[3]);
11882 ix86_expand_clear (operands[3]);
11886 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11887 (match_operand 4)])
11888 (set (match_operand:QI 1 "register_operand")
11889 (match_operator:QI 2 "ix86_comparison_operator"
11890 [(reg FLAGS_REG) (const_int 0)]))
11891 (parallel [(set (match_operand 3 "any_QIreg_operand")
11892 (zero_extend (match_dup 1)))
11893 (clobber (reg:CC FLAGS_REG))])]
11894 "(peep2_reg_dead_p (3, operands[1])
11895 || operands_match_p (operands[1], operands[3]))
11896 && ! reg_overlap_mentioned_p (operands[3], operands[0])
11897 && ! (GET_CODE (operands[4]) == CLOBBER
11898 && reg_mentioned_p (operands[3], operands[4]))"
11899 [(parallel [(set (match_dup 5) (match_dup 0))
11901 (set (strict_low_part (match_dup 6))
11904 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11905 operands[6] = gen_lowpart (QImode, operands[3]);
11906 ix86_expand_clear (operands[3]);
11909 ;; Call instructions.
11911 ;; The predicates normally associated with named expanders are not properly
11912 ;; checked for calls. This is a bug in the generic code, but it isn't that
11913 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11915 ;; P6 processors will jump to the address after the decrement when %esp
11916 ;; is used as a call operand, so they will execute return address as a code.
11917 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11919 ;; Register constraint for call instruction.
11920 (define_mode_attr c [(SI "l") (DI "r")])
11922 ;; Call subroutine returning no value.
11924 (define_expand "call"
11925 [(call (match_operand:QI 0)
11927 (use (match_operand 2))]
11930 ix86_expand_call (NULL, operands[0], operands[1],
11931 operands[2], NULL, false);
11935 (define_expand "sibcall"
11936 [(call (match_operand:QI 0)
11938 (use (match_operand 2))]
11941 ix86_expand_call (NULL, operands[0], operands[1],
11942 operands[2], NULL, true);
11946 (define_insn "*call"
11947 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11948 (match_operand 1))]
11949 "!SIBLING_CALL_P (insn)"
11950 "* return ix86_output_call_insn (insn, operands[0]);"
11951 [(set_attr "type" "call")])
11953 ;; This covers both call and sibcall since only GOT slot is allowed.
11954 (define_insn "*call_got_x32"
11955 [(call (mem:QI (zero_extend:DI
11956 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
11957 (match_operand 1))]
11960 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
11961 return ix86_output_call_insn (insn, fnaddr);
11963 [(set_attr "type" "call")])
11965 ;; Since sibcall never returns, we can only use call-clobbered register
11967 (define_insn "*sibcall_GOT_32"
11970 (match_operand:SI 0 "register_no_elim_operand" "U")
11971 (match_operand:SI 1 "GOT32_symbol_operand"))))
11972 (match_operand 2))]
11973 "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11975 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
11976 fnaddr = gen_const_mem (SImode, fnaddr);
11977 return ix86_output_call_insn (insn, fnaddr);
11979 [(set_attr "type" "call")])
11981 (define_insn "*sibcall"
11982 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11983 (match_operand 1))]
11984 "SIBLING_CALL_P (insn)"
11985 "* return ix86_output_call_insn (insn, operands[0]);"
11986 [(set_attr "type" "call")])
11988 (define_insn "*sibcall_memory"
11989 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11991 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11993 "* return ix86_output_call_insn (insn, operands[0]);"
11994 [(set_attr "type" "call")])
11997 [(set (match_operand:W 0 "register_operand")
11998 (match_operand:W 1 "memory_operand"))
11999 (call (mem:QI (match_dup 0))
12000 (match_operand 3))]
12001 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
12002 && !reg_mentioned_p (operands[0],
12003 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12004 [(parallel [(call (mem:QI (match_dup 1))
12006 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12009 [(set (match_operand:W 0 "register_operand")
12010 (match_operand:W 1 "memory_operand"))
12011 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12012 (call (mem:QI (match_dup 0))
12013 (match_operand 3))]
12014 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
12015 && !reg_mentioned_p (operands[0],
12016 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12017 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12018 (parallel [(call (mem:QI (match_dup 1))
12020 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12022 (define_expand "call_pop"
12023 [(parallel [(call (match_operand:QI 0)
12024 (match_operand:SI 1))
12025 (set (reg:SI SP_REG)
12026 (plus:SI (reg:SI SP_REG)
12027 (match_operand:SI 3)))])]
12030 ix86_expand_call (NULL, operands[0], operands[1],
12031 operands[2], operands[3], false);
12035 (define_insn "*call_pop"
12036 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
12038 (set (reg:SI SP_REG)
12039 (plus:SI (reg:SI SP_REG)
12040 (match_operand:SI 2 "immediate_operand" "i")))]
12041 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12042 "* return ix86_output_call_insn (insn, operands[0]);"
12043 [(set_attr "type" "call")])
12045 (define_insn "*sibcall_pop"
12046 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
12048 (set (reg:SI SP_REG)
12049 (plus:SI (reg:SI SP_REG)
12050 (match_operand:SI 2 "immediate_operand" "i")))]
12051 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12052 "* return ix86_output_call_insn (insn, operands[0]);"
12053 [(set_attr "type" "call")])
12055 (define_insn "*sibcall_pop_memory"
12056 [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
12058 (set (reg:SI SP_REG)
12059 (plus:SI (reg:SI SP_REG)
12060 (match_operand:SI 2 "immediate_operand" "i")))
12061 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12063 "* return ix86_output_call_insn (insn, operands[0]);"
12064 [(set_attr "type" "call")])
12067 [(set (match_operand:SI 0 "register_operand")
12068 (match_operand:SI 1 "memory_operand"))
12069 (parallel [(call (mem:QI (match_dup 0))
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 [(call (mem:QI (match_dup 1))
12079 (set (reg:SI SP_REG)
12080 (plus:SI (reg:SI SP_REG)
12082 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12085 [(set (match_operand:SI 0 "register_operand")
12086 (match_operand:SI 1 "memory_operand"))
12087 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12088 (parallel [(call (mem:QI (match_dup 0))
12090 (set (reg:SI SP_REG)
12091 (plus:SI (reg:SI SP_REG)
12092 (match_operand:SI 4 "immediate_operand")))])]
12093 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12094 && !reg_mentioned_p (operands[0],
12095 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12096 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12097 (parallel [(call (mem:QI (match_dup 1))
12099 (set (reg:SI SP_REG)
12100 (plus:SI (reg:SI SP_REG)
12102 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12104 ;; Combining simple memory jump instruction
12107 [(set (match_operand:W 0 "register_operand")
12108 (match_operand:W 1 "memory_operand"))
12109 (set (pc) (match_dup 0))]
12110 "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
12111 [(set (pc) (match_dup 1))])
12113 ;; Call subroutine, returning value in operand 0
12115 (define_expand "call_value"
12116 [(set (match_operand 0)
12117 (call (match_operand:QI 1)
12118 (match_operand 2)))
12119 (use (match_operand 3))]
12122 ix86_expand_call (operands[0], operands[1], operands[2],
12123 operands[3], NULL, false);
12127 (define_expand "sibcall_value"
12128 [(set (match_operand 0)
12129 (call (match_operand:QI 1)
12130 (match_operand 2)))
12131 (use (match_operand 3))]
12134 ix86_expand_call (operands[0], operands[1], operands[2],
12135 operands[3], NULL, true);
12139 (define_insn "*call_value"
12140 [(set (match_operand 0)
12141 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
12142 (match_operand 2)))]
12143 "!SIBLING_CALL_P (insn)"
12144 "* return ix86_output_call_insn (insn, operands[1]);"
12145 [(set_attr "type" "callv")])
12147 ;; This covers both call and sibcall since only GOT slot is allowed.
12148 (define_insn "*call_value_got_x32"
12149 [(set (match_operand 0)
12152 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
12153 (match_operand 2)))]
12156 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
12157 return ix86_output_call_insn (insn, fnaddr);
12159 [(set_attr "type" "callv")])
12161 ;; Since sibcall never returns, we can only use call-clobbered register
12163 (define_insn "*sibcall_value_GOT_32"
12164 [(set (match_operand 0)
12167 (match_operand:SI 1 "register_no_elim_operand" "U")
12168 (match_operand:SI 2 "GOT32_symbol_operand"))))
12169 (match_operand 3)))]
12170 "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
12172 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
12173 fnaddr = gen_const_mem (SImode, fnaddr);
12174 return ix86_output_call_insn (insn, fnaddr);
12176 [(set_attr "type" "callv")])
12178 (define_insn "*sibcall_value"
12179 [(set (match_operand 0)
12180 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
12181 (match_operand 2)))]
12182 "SIBLING_CALL_P (insn)"
12183 "* return ix86_output_call_insn (insn, operands[1]);"
12184 [(set_attr "type" "callv")])
12186 (define_insn "*sibcall_value_memory"
12187 [(set (match_operand 0)
12188 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
12189 (match_operand 2)))
12190 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12192 "* return ix86_output_call_insn (insn, operands[1]);"
12193 [(set_attr "type" "callv")])
12196 [(set (match_operand:W 0 "register_operand")
12197 (match_operand:W 1 "memory_operand"))
12198 (set (match_operand 2)
12199 (call (mem:QI (match_dup 0))
12200 (match_operand 3)))]
12201 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
12202 && !reg_mentioned_p (operands[0],
12203 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12204 [(parallel [(set (match_dup 2)
12205 (call (mem:QI (match_dup 1))
12207 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12210 [(set (match_operand:W 0 "register_operand")
12211 (match_operand:W 1 "memory_operand"))
12212 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12213 (set (match_operand 2)
12214 (call (mem:QI (match_dup 0))
12215 (match_operand 3)))]
12216 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
12217 && !reg_mentioned_p (operands[0],
12218 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12219 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12220 (parallel [(set (match_dup 2)
12221 (call (mem:QI (match_dup 1))
12223 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12225 (define_expand "call_value_pop"
12226 [(parallel [(set (match_operand 0)
12227 (call (match_operand:QI 1)
12228 (match_operand:SI 2)))
12229 (set (reg:SI SP_REG)
12230 (plus:SI (reg:SI SP_REG)
12231 (match_operand:SI 4)))])]
12234 ix86_expand_call (operands[0], operands[1], operands[2],
12235 operands[3], operands[4], false);
12239 (define_insn "*call_value_pop"
12240 [(set (match_operand 0)
12241 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
12242 (match_operand 2)))
12243 (set (reg:SI SP_REG)
12244 (plus:SI (reg:SI SP_REG)
12245 (match_operand:SI 3 "immediate_operand" "i")))]
12246 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12247 "* return ix86_output_call_insn (insn, operands[1]);"
12248 [(set_attr "type" "callv")])
12250 (define_insn "*sibcall_value_pop"
12251 [(set (match_operand 0)
12252 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
12253 (match_operand 2)))
12254 (set (reg:SI SP_REG)
12255 (plus:SI (reg:SI SP_REG)
12256 (match_operand:SI 3 "immediate_operand" "i")))]
12257 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12258 "* return ix86_output_call_insn (insn, operands[1]);"
12259 [(set_attr "type" "callv")])
12261 (define_insn "*sibcall_value_pop_memory"
12262 [(set (match_operand 0)
12263 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
12264 (match_operand 2)))
12265 (set (reg:SI SP_REG)
12266 (plus:SI (reg:SI SP_REG)
12267 (match_operand:SI 3 "immediate_operand" "i")))
12268 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12270 "* return ix86_output_call_insn (insn, operands[1]);"
12271 [(set_attr "type" "callv")])
12274 [(set (match_operand:SI 0 "register_operand")
12275 (match_operand:SI 1 "memory_operand"))
12276 (parallel [(set (match_operand 2)
12277 (call (mem:QI (match_dup 0))
12278 (match_operand 3)))
12279 (set (reg:SI SP_REG)
12280 (plus:SI (reg:SI SP_REG)
12281 (match_operand:SI 4 "immediate_operand")))])]
12282 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12283 && !reg_mentioned_p (operands[0],
12284 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12285 [(parallel [(set (match_dup 2)
12286 (call (mem:QI (match_dup 1))
12288 (set (reg:SI SP_REG)
12289 (plus:SI (reg:SI SP_REG)
12291 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12294 [(set (match_operand:SI 0 "register_operand")
12295 (match_operand:SI 1 "memory_operand"))
12296 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12297 (parallel [(set (match_operand 2)
12298 (call (mem:QI (match_dup 0))
12299 (match_operand 3)))
12300 (set (reg:SI SP_REG)
12301 (plus:SI (reg:SI SP_REG)
12302 (match_operand:SI 4 "immediate_operand")))])]
12303 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12304 && !reg_mentioned_p (operands[0],
12305 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12306 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12307 (parallel [(set (match_dup 2)
12308 (call (mem:QI (match_dup 1))
12310 (set (reg:SI SP_REG)
12311 (plus:SI (reg:SI SP_REG)
12313 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12315 ;; Call subroutine returning any type.
12317 (define_expand "untyped_call"
12318 [(parallel [(call (match_operand 0)
12321 (match_operand 2)])]
12326 /* In order to give reg-stack an easier job in validating two
12327 coprocessor registers as containing a possible return value,
12328 simply pretend the untyped call returns a complex long double
12331 We can't use SSE_REGPARM_MAX here since callee is unprototyped
12332 and should have the default ABI. */
12334 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12335 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12336 operands[0], const0_rtx,
12337 GEN_INT ((TARGET_64BIT
12338 ? (ix86_abi == SYSV_ABI
12339 ? X86_64_SSE_REGPARM_MAX
12340 : X86_64_MS_SSE_REGPARM_MAX)
12341 : X86_32_SSE_REGPARM_MAX)
12345 for (i = 0; i < XVECLEN (operands[2], 0); i++)
12347 rtx set = XVECEXP (operands[2], 0, i);
12348 emit_move_insn (SET_DEST (set), SET_SRC (set));
12351 /* The optimizer does not know that the call sets the function value
12352 registers we stored in the result block. We avoid problems by
12353 claiming that all hard registers are used and clobbered at this
12355 emit_insn (gen_blockage ());
12360 ;; Prologue and epilogue instructions
12362 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12363 ;; all of memory. This blocks insns from being moved across this point.
12365 (define_insn "blockage"
12366 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12369 [(set_attr "length" "0")])
12371 ;; Do not schedule instructions accessing memory across this point.
12373 (define_expand "memory_blockage"
12374 [(set (match_dup 0)
12375 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12378 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12379 MEM_VOLATILE_P (operands[0]) = 1;
12382 (define_insn "*memory_blockage"
12383 [(set (match_operand:BLK 0)
12384 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12387 [(set_attr "length" "0")])
12389 ;; As USE insns aren't meaningful after reload, this is used instead
12390 ;; to prevent deleting instructions setting registers for PIC code
12391 (define_insn "prologue_use"
12392 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12395 [(set_attr "length" "0")])
12397 ;; Insn emitted into the body of a function to return from a function.
12398 ;; This is only done if the function's epilogue is known to be simple.
12399 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12401 (define_expand "return"
12403 "ix86_can_use_return_insn_p ()"
12405 if (crtl->args.pops_args)
12407 rtx popc = GEN_INT (crtl->args.pops_args);
12408 emit_jump_insn (gen_simple_return_pop_internal (popc));
12413 ;; We need to disable this for TARGET_SEH, as otherwise
12414 ;; shrink-wrapped prologue gets enabled too. This might exceed
12415 ;; the maximum size of prologue in unwind information.
12416 ;; Also disallow shrink-wrapping if using stack slot to pass the
12417 ;; static chain pointer - the first instruction has to be pushl %esi
12418 ;; and it can't be moved around, as we use alternate entry points
12421 (define_expand "simple_return"
12423 "!TARGET_SEH && !ix86_static_chain_on_stack"
12425 if (crtl->args.pops_args)
12427 rtx popc = GEN_INT (crtl->args.pops_args);
12428 emit_jump_insn (gen_simple_return_pop_internal (popc));
12433 (define_insn "simple_return_internal"
12437 [(set_attr "length" "1")
12438 (set_attr "atom_unit" "jeu")
12439 (set_attr "length_immediate" "0")
12440 (set_attr "modrm" "0")
12441 (set_attr "maybe_prefix_bnd" "1")])
12443 (define_insn "interrupt_return"
12445 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
12448 return TARGET_64BIT ? "iretq" : "iret";
12451 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12452 ;; instruction Athlon and K8 have.
12454 (define_insn "simple_return_internal_long"
12456 (unspec [(const_int 0)] UNSPEC_REP)]
12459 if (ix86_bnd_prefixed_insn_p (insn))
12462 return "rep%; ret";
12464 [(set_attr "length" "2")
12465 (set_attr "atom_unit" "jeu")
12466 (set_attr "length_immediate" "0")
12467 (set_attr "prefix_rep" "1")
12468 (set_attr "modrm" "0")])
12470 (define_insn "simple_return_pop_internal"
12472 (use (match_operand:SI 0 "const_int_operand"))]
12475 [(set_attr "length" "3")
12476 (set_attr "atom_unit" "jeu")
12477 (set_attr "length_immediate" "2")
12478 (set_attr "modrm" "0")
12479 (set_attr "maybe_prefix_bnd" "1")])
12481 (define_insn "simple_return_indirect_internal"
12483 (use (match_operand:SI 0 "register_operand" "r"))]
12486 [(set_attr "type" "ibr")
12487 (set_attr "length_immediate" "0")
12488 (set_attr "maybe_prefix_bnd" "1")])
12494 [(set_attr "length" "1")
12495 (set_attr "length_immediate" "0")
12496 (set_attr "modrm" "0")])
12498 ;; Generate nops. Operand 0 is the number of nops, up to 8.
12499 (define_insn "nops"
12500 [(unspec_volatile [(match_operand 0 "const_int_operand")]
12504 int num = INTVAL (operands[0]);
12506 gcc_assert (IN_RANGE (num, 1, 8));
12509 fputs ("\tnop\n", asm_out_file);
12513 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12514 (set_attr "length_immediate" "0")
12515 (set_attr "modrm" "0")])
12517 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12518 ;; branch prediction penalty for the third jump in a 16-byte
12522 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12525 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12526 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12528 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12529 The align insn is used to avoid 3 jump instructions in the row to improve
12530 branch prediction and the benefits hardly outweigh the cost of extra 8
12531 nops on the average inserted by full alignment pseudo operation. */
12535 [(set_attr "length" "16")])
12537 (define_expand "prologue"
12540 "ix86_expand_prologue (); DONE;")
12542 (define_expand "set_got"
12544 [(set (match_operand:SI 0 "register_operand")
12545 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12546 (clobber (reg:CC FLAGS_REG))])]
12549 if (flag_pic && !TARGET_VXWORKS_RTP)
12550 ix86_pc_thunk_call_expanded = true;
12553 (define_insn "*set_got"
12554 [(set (match_operand:SI 0 "register_operand" "=r")
12555 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12556 (clobber (reg:CC FLAGS_REG))]
12558 "* return output_set_got (operands[0], NULL_RTX);"
12559 [(set_attr "type" "multi")
12560 (set_attr "length" "12")])
12562 (define_expand "set_got_labelled"
12564 [(set (match_operand:SI 0 "register_operand")
12565 (unspec:SI [(label_ref (match_operand 1))]
12567 (clobber (reg:CC FLAGS_REG))])]
12570 if (flag_pic && !TARGET_VXWORKS_RTP)
12571 ix86_pc_thunk_call_expanded = true;
12574 (define_insn "*set_got_labelled"
12575 [(set (match_operand:SI 0 "register_operand" "=r")
12576 (unspec:SI [(label_ref (match_operand 1))]
12578 (clobber (reg:CC FLAGS_REG))]
12580 "* return output_set_got (operands[0], operands[1]);"
12581 [(set_attr "type" "multi")
12582 (set_attr "length" "12")])
12584 (define_insn "set_got_rex64"
12585 [(set (match_operand:DI 0 "register_operand" "=r")
12586 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12588 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12589 [(set_attr "type" "lea")
12590 (set_attr "length_address" "4")
12591 (set_attr "modrm_class" "unknown")
12592 (set_attr "mode" "DI")])
12594 (define_insn "set_rip_rex64"
12595 [(set (match_operand:DI 0 "register_operand" "=r")
12596 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12598 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12599 [(set_attr "type" "lea")
12600 (set_attr "length_address" "4")
12601 (set_attr "mode" "DI")])
12603 (define_insn "set_got_offset_rex64"
12604 [(set (match_operand:DI 0 "register_operand" "=r")
12606 [(label_ref (match_operand 1))]
12607 UNSPEC_SET_GOT_OFFSET))]
12609 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12610 [(set_attr "type" "imov")
12611 (set_attr "length_immediate" "0")
12612 (set_attr "length_address" "8")
12613 (set_attr "mode" "DI")])
12615 (define_expand "epilogue"
12618 "ix86_expand_epilogue (1); DONE;")
12620 (define_expand "sibcall_epilogue"
12623 "ix86_expand_epilogue (0); DONE;")
12625 (define_expand "eh_return"
12626 [(use (match_operand 0 "register_operand"))]
12629 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12631 /* Tricky bit: we write the address of the handler to which we will
12632 be returning into someone else's stack frame, one word below the
12633 stack address we wish to restore. */
12634 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12635 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12636 tmp = gen_rtx_MEM (Pmode, tmp);
12637 emit_move_insn (tmp, ra);
12639 emit_jump_insn (gen_eh_return_internal ());
12644 (define_insn_and_split "eh_return_internal"
12648 "epilogue_completed"
12650 "ix86_expand_epilogue (2); DONE;")
12652 (define_insn "leave"
12653 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12654 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12655 (clobber (mem:BLK (scratch)))]
12658 [(set_attr "type" "leave")])
12660 (define_insn "leave_rex64"
12661 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12662 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12663 (clobber (mem:BLK (scratch)))]
12666 [(set_attr "type" "leave")])
12668 ;; Handle -fsplit-stack.
12670 (define_expand "split_stack_prologue"
12674 ix86_expand_split_stack_prologue ();
12678 ;; In order to support the call/return predictor, we use a return
12679 ;; instruction which the middle-end doesn't see.
12680 (define_insn "split_stack_return"
12681 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12682 UNSPECV_SPLIT_STACK_RETURN)]
12685 if (operands[0] == const0_rtx)
12690 [(set_attr "atom_unit" "jeu")
12691 (set_attr "modrm" "0")
12692 (set (attr "length")
12693 (if_then_else (match_operand:SI 0 "const0_operand")
12696 (set (attr "length_immediate")
12697 (if_then_else (match_operand:SI 0 "const0_operand")
12701 ;; If there are operand 0 bytes available on the stack, jump to
12704 (define_expand "split_stack_space_check"
12705 [(set (pc) (if_then_else
12706 (ltu (minus (reg SP_REG)
12707 (match_operand 0 "register_operand"))
12708 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12709 (label_ref (match_operand 1))
12713 rtx reg, size, limit;
12715 reg = gen_reg_rtx (Pmode);
12716 size = force_reg (Pmode, operands[0]);
12717 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12718 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12719 UNSPEC_STACK_CHECK);
12720 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12721 ix86_expand_branch (GEU, reg, limit, operands[1]);
12726 ;; Bit manipulation instructions.
12728 (define_expand "ffs<mode>2"
12729 [(set (match_dup 2) (const_int -1))
12730 (parallel [(set (match_dup 3) (match_dup 4))
12731 (set (match_operand:SWI48 0 "register_operand")
12733 (match_operand:SWI48 1 "nonimmediate_operand")))])
12734 (set (match_dup 0) (if_then_else:SWI48
12735 (eq (match_dup 3) (const_int 0))
12738 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12739 (clobber (reg:CC FLAGS_REG))])]
12742 machine_mode flags_mode;
12744 if (<MODE>mode == SImode && !TARGET_CMOVE)
12746 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12751 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12753 operands[2] = gen_reg_rtx (<MODE>mode);
12754 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12755 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12758 (define_insn_and_split "ffssi2_no_cmove"
12759 [(set (match_operand:SI 0 "register_operand" "=r")
12760 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12761 (clobber (match_scratch:SI 2 "=&q"))
12762 (clobber (reg:CC FLAGS_REG))]
12765 "&& reload_completed"
12766 [(parallel [(set (match_dup 4) (match_dup 5))
12767 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12768 (set (strict_low_part (match_dup 3))
12769 (eq:QI (match_dup 4) (const_int 0)))
12770 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12771 (clobber (reg:CC FLAGS_REG))])
12772 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12773 (clobber (reg:CC FLAGS_REG))])
12774 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12775 (clobber (reg:CC FLAGS_REG))])]
12777 machine_mode flags_mode
12778 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12780 operands[3] = gen_lowpart (QImode, operands[2]);
12781 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12782 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12784 ix86_expand_clear (operands[2]);
12787 (define_insn "*tzcnt<mode>_1"
12788 [(set (reg:CCC FLAGS_REG)
12789 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12791 (set (match_operand:SWI48 0 "register_operand" "=r")
12792 (ctz:SWI48 (match_dup 1)))]
12793 "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
12794 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12795 [(set_attr "type" "alu1")
12796 (set_attr "prefix_0f" "1")
12797 (set_attr "prefix_rep" "1")
12798 (set_attr "btver2_decode" "double")
12799 (set_attr "mode" "<MODE>")])
12801 (define_insn "*bsf<mode>_1"
12802 [(set (reg:CCZ FLAGS_REG)
12803 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12805 (set (match_operand:SWI48 0 "register_operand" "=r")
12806 (ctz:SWI48 (match_dup 1)))]
12808 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12809 [(set_attr "type" "alu1")
12810 (set_attr "prefix_0f" "1")
12811 (set_attr "btver2_decode" "double")
12812 (set_attr "znver1_decode" "vector")
12813 (set_attr "mode" "<MODE>")])
12815 (define_expand "ctz<mode>2"
12817 [(set (match_operand:SWI248 0 "register_operand")
12819 (match_operand:SWI248 1 "nonimmediate_operand")))
12820 (clobber (reg:CC FLAGS_REG))])])
12822 ; False dependency happens when destination is only updated by tzcnt,
12823 ; lzcnt or popcnt. There is no false dependency when destination is
12824 ; also used in source.
12825 (define_insn_and_split "*ctz<mode>2_falsedep_1"
12826 [(set (match_operand:SWI48 0 "register_operand" "=r")
12828 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12829 (clobber (reg:CC FLAGS_REG))]
12830 "(TARGET_BMI || TARGET_GENERIC)
12831 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12833 "&& reload_completed"
12835 [(set (match_dup 0)
12836 (ctz:SWI48 (match_dup 1)))
12837 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12838 (clobber (reg:CC FLAGS_REG))])]
12840 if (!reg_mentioned_p (operands[0], operands[1]))
12841 ix86_expand_clear (operands[0]);
12844 (define_insn "*ctz<mode>2_falsedep"
12845 [(set (match_operand:SWI48 0 "register_operand" "=r")
12847 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12848 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12849 UNSPEC_INSN_FALSE_DEP)
12850 (clobber (reg:CC FLAGS_REG))]
12854 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12855 else if (TARGET_GENERIC)
12856 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12857 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12859 gcc_unreachable ();
12861 [(set_attr "type" "alu1")
12862 (set_attr "prefix_0f" "1")
12863 (set_attr "prefix_rep" "1")
12864 (set_attr "mode" "<MODE>")])
12866 (define_insn "*ctz<mode>2"
12867 [(set (match_operand:SWI248 0 "register_operand" "=r")
12868 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12869 (clobber (reg:CC FLAGS_REG))]
12873 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12874 else if (optimize_function_for_size_p (cfun))
12876 else if (TARGET_GENERIC)
12877 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12878 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12880 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12882 [(set_attr "type" "alu1")
12883 (set_attr "prefix_0f" "1")
12884 (set (attr "prefix_rep")
12886 (ior (match_test "TARGET_BMI")
12887 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12888 (match_test "TARGET_GENERIC")))
12890 (const_string "0")))
12891 (set_attr "mode" "<MODE>")])
12893 (define_expand "clz<mode>2"
12895 [(set (match_operand:SWI248 0 "register_operand")
12898 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12899 (clobber (reg:CC FLAGS_REG))])
12901 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12902 (clobber (reg:CC FLAGS_REG))])]
12907 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12910 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12913 (define_expand "clz<mode>2_lzcnt"
12915 [(set (match_operand:SWI248 0 "register_operand")
12917 (match_operand:SWI248 1 "nonimmediate_operand")))
12918 (clobber (reg:CC FLAGS_REG))])]
12921 (define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
12922 [(set (match_operand:SWI48 0 "register_operand" "=r")
12924 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12925 (clobber (reg:CC FLAGS_REG))]
12927 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12929 "&& reload_completed"
12931 [(set (match_dup 0)
12932 (clz:SWI48 (match_dup 1)))
12933 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12934 (clobber (reg:CC FLAGS_REG))])]
12936 if (!reg_mentioned_p (operands[0], operands[1]))
12937 ix86_expand_clear (operands[0]);
12940 (define_insn "*clz<mode>2_lzcnt_falsedep"
12941 [(set (match_operand:SWI48 0 "register_operand" "=r")
12943 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12944 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12945 UNSPEC_INSN_FALSE_DEP)
12946 (clobber (reg:CC FLAGS_REG))]
12948 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12949 [(set_attr "prefix_rep" "1")
12950 (set_attr "type" "bitmanip")
12951 (set_attr "mode" "<MODE>")])
12953 (define_insn "*clz<mode>2_lzcnt"
12954 [(set (match_operand:SWI248 0 "register_operand" "=r")
12955 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12956 (clobber (reg:CC FLAGS_REG))]
12958 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12959 [(set_attr "prefix_rep" "1")
12960 (set_attr "type" "bitmanip")
12961 (set_attr "mode" "<MODE>")])
12963 ;; BMI instructions.
12964 (define_insn "*bmi_andn_<mode>"
12965 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12967 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
12968 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12969 (clobber (reg:CC FLAGS_REG))]
12971 "andn\t{%2, %1, %0|%0, %1, %2}"
12972 [(set_attr "type" "bitmanip")
12973 (set_attr "btver2_decode" "direct, double")
12974 (set_attr "mode" "<MODE>")])
12976 (define_insn "*bmi_andn_<mode>_ccno"
12977 [(set (reg FLAGS_REG)
12980 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
12981 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
12983 (clobber (match_scratch:SWI48 0 "=r,r"))]
12984 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
12985 "andn\t{%2, %1, %0|%0, %1, %2}"
12986 [(set_attr "type" "bitmanip")
12987 (set_attr "btver2_decode" "direct, double")
12988 (set_attr "mode" "<MODE>")])
12990 (define_insn "bmi_bextr_<mode>"
12991 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12992 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12993 (match_operand:SWI48 2 "register_operand" "r,r")]
12995 (clobber (reg:CC FLAGS_REG))]
12997 "bextr\t{%2, %1, %0|%0, %1, %2}"
12998 [(set_attr "type" "bitmanip")
12999 (set_attr "btver2_decode" "direct, double")
13000 (set_attr "mode" "<MODE>")])
13002 (define_insn "*bmi_bextr_<mode>_ccz"
13003 [(set (reg:CCZ FLAGS_REG)
13005 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13006 (match_operand:SWI48 2 "register_operand" "r,r")]
13009 (clobber (match_scratch:SWI48 0 "=r,r"))]
13011 "bextr\t{%2, %1, %0|%0, %1, %2}"
13012 [(set_attr "type" "bitmanip")
13013 (set_attr "btver2_decode" "direct, double")
13014 (set_attr "mode" "<MODE>")])
13016 (define_insn "*bmi_blsi_<mode>"
13017 [(set (match_operand:SWI48 0 "register_operand" "=r")
13020 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
13022 (clobber (reg:CC FLAGS_REG))]
13024 "blsi\t{%1, %0|%0, %1}"
13025 [(set_attr "type" "bitmanip")
13026 (set_attr "btver2_decode" "double")
13027 (set_attr "mode" "<MODE>")])
13029 (define_insn "*bmi_blsmsk_<mode>"
13030 [(set (match_operand:SWI48 0 "register_operand" "=r")
13033 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13036 (clobber (reg:CC FLAGS_REG))]
13038 "blsmsk\t{%1, %0|%0, %1}"
13039 [(set_attr "type" "bitmanip")
13040 (set_attr "btver2_decode" "double")
13041 (set_attr "mode" "<MODE>")])
13043 (define_insn "*bmi_blsr_<mode>"
13044 [(set (match_operand:SWI48 0 "register_operand" "=r")
13047 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13050 (clobber (reg:CC FLAGS_REG))]
13052 "blsr\t{%1, %0|%0, %1}"
13053 [(set_attr "type" "bitmanip")
13054 (set_attr "btver2_decode" "double")
13055 (set_attr "mode" "<MODE>")])
13057 ;; BMI2 instructions.
13058 (define_expand "bmi2_bzhi_<mode>3"
13060 [(set (match_operand:SWI48 0 "register_operand")
13061 (zero_extract:SWI48
13062 (match_operand:SWI48 1 "nonimmediate_operand")
13064 (and:SWI48 (match_operand:SWI48 2 "register_operand")
13068 (clobber (reg:CC FLAGS_REG))])]
13070 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
13072 (define_insn "*bmi2_bzhi_<mode>3"
13073 [(set (match_operand:SWI48 0 "register_operand" "=r")
13074 (zero_extract:SWI48
13075 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13077 (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
13079 (match_operand:SWI48 3 "const_int_operand" "n"))
13081 (clobber (reg:CC FLAGS_REG))]
13082 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13083 "bzhi\t{%2, %1, %0|%0, %1, %2}"
13084 [(set_attr "type" "bitmanip")
13085 (set_attr "prefix" "vex")
13086 (set_attr "mode" "<MODE>")])
13088 (define_mode_attr k [(SI "k") (DI "q")])
13090 (define_insn "*bmi2_bzhi_<mode>3_1"
13091 [(set (match_operand:SWI48 0 "register_operand" "=r")
13092 (zero_extract:SWI48
13093 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13095 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13096 (match_operand:SWI48 3 "const_int_operand" "n"))
13098 (clobber (reg:CC FLAGS_REG))]
13099 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13100 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13101 [(set_attr "type" "bitmanip")
13102 (set_attr "prefix" "vex")
13103 (set_attr "mode" "<MODE>")])
13105 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
13106 [(set (reg:CCZ FLAGS_REG)
13108 (zero_extract:SWI48
13109 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13111 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13112 (match_operand:SWI48 3 "const_int_operand" "n"))
13115 (clobber (match_scratch:SWI48 0 "=r"))]
13116 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13117 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13118 [(set_attr "type" "bitmanip")
13119 (set_attr "prefix" "vex")
13120 (set_attr "mode" "<MODE>")])
13122 (define_insn "bmi2_pdep_<mode>3"
13123 [(set (match_operand:SWI48 0 "register_operand" "=r")
13124 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13125 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13128 "pdep\t{%2, %1, %0|%0, %1, %2}"
13129 [(set_attr "type" "bitmanip")
13130 (set_attr "prefix" "vex")
13131 (set_attr "mode" "<MODE>")])
13133 (define_insn "bmi2_pext_<mode>3"
13134 [(set (match_operand:SWI48 0 "register_operand" "=r")
13135 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13136 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13139 "pext\t{%2, %1, %0|%0, %1, %2}"
13140 [(set_attr "type" "bitmanip")
13141 (set_attr "prefix" "vex")
13142 (set_attr "mode" "<MODE>")])
13144 ;; TBM instructions.
13145 (define_insn "tbm_bextri_<mode>"
13146 [(set (match_operand:SWI48 0 "register_operand" "=r")
13147 (zero_extract:SWI48
13148 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13149 (match_operand 2 "const_0_to_255_operand" "N")
13150 (match_operand 3 "const_0_to_255_operand" "N")))
13151 (clobber (reg:CC FLAGS_REG))]
13154 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
13155 return "bextr\t{%2, %1, %0|%0, %1, %2}";
13157 [(set_attr "type" "bitmanip")
13158 (set_attr "mode" "<MODE>")])
13160 (define_insn "*tbm_blcfill_<mode>"
13161 [(set (match_operand:SWI48 0 "register_operand" "=r")
13164 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13167 (clobber (reg:CC FLAGS_REG))]
13169 "blcfill\t{%1, %0|%0, %1}"
13170 [(set_attr "type" "bitmanip")
13171 (set_attr "mode" "<MODE>")])
13173 (define_insn "*tbm_blci_<mode>"
13174 [(set (match_operand:SWI48 0 "register_operand" "=r")
13178 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13181 (clobber (reg:CC FLAGS_REG))]
13183 "blci\t{%1, %0|%0, %1}"
13184 [(set_attr "type" "bitmanip")
13185 (set_attr "mode" "<MODE>")])
13187 (define_insn "*tbm_blcic_<mode>"
13188 [(set (match_operand:SWI48 0 "register_operand" "=r")
13191 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13195 (clobber (reg:CC FLAGS_REG))]
13197 "blcic\t{%1, %0|%0, %1}"
13198 [(set_attr "type" "bitmanip")
13199 (set_attr "mode" "<MODE>")])
13201 (define_insn "*tbm_blcmsk_<mode>"
13202 [(set (match_operand:SWI48 0 "register_operand" "=r")
13205 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13208 (clobber (reg:CC FLAGS_REG))]
13210 "blcmsk\t{%1, %0|%0, %1}"
13211 [(set_attr "type" "bitmanip")
13212 (set_attr "mode" "<MODE>")])
13214 (define_insn "*tbm_blcs_<mode>"
13215 [(set (match_operand:SWI48 0 "register_operand" "=r")
13218 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13221 (clobber (reg:CC FLAGS_REG))]
13223 "blcs\t{%1, %0|%0, %1}"
13224 [(set_attr "type" "bitmanip")
13225 (set_attr "mode" "<MODE>")])
13227 (define_insn "*tbm_blsfill_<mode>"
13228 [(set (match_operand:SWI48 0 "register_operand" "=r")
13231 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13234 (clobber (reg:CC FLAGS_REG))]
13236 "blsfill\t{%1, %0|%0, %1}"
13237 [(set_attr "type" "bitmanip")
13238 (set_attr "mode" "<MODE>")])
13240 (define_insn "*tbm_blsic_<mode>"
13241 [(set (match_operand:SWI48 0 "register_operand" "=r")
13244 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13248 (clobber (reg:CC FLAGS_REG))]
13250 "blsic\t{%1, %0|%0, %1}"
13251 [(set_attr "type" "bitmanip")
13252 (set_attr "mode" "<MODE>")])
13254 (define_insn "*tbm_t1mskc_<mode>"
13255 [(set (match_operand:SWI48 0 "register_operand" "=r")
13258 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13262 (clobber (reg:CC FLAGS_REG))]
13264 "t1mskc\t{%1, %0|%0, %1}"
13265 [(set_attr "type" "bitmanip")
13266 (set_attr "mode" "<MODE>")])
13268 (define_insn "*tbm_tzmsk_<mode>"
13269 [(set (match_operand:SWI48 0 "register_operand" "=r")
13272 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13276 (clobber (reg:CC FLAGS_REG))]
13278 "tzmsk\t{%1, %0|%0, %1}"
13279 [(set_attr "type" "bitmanip")
13280 (set_attr "mode" "<MODE>")])
13282 (define_insn "bsr_rex64"
13283 [(set (match_operand:DI 0 "register_operand" "=r")
13284 (minus:DI (const_int 63)
13285 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13286 (clobber (reg:CC FLAGS_REG))]
13288 "bsr{q}\t{%1, %0|%0, %1}"
13289 [(set_attr "type" "alu1")
13290 (set_attr "prefix_0f" "1")
13291 (set_attr "znver1_decode" "vector")
13292 (set_attr "mode" "DI")])
13295 [(set (match_operand:SI 0 "register_operand" "=r")
13296 (minus:SI (const_int 31)
13297 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13298 (clobber (reg:CC FLAGS_REG))]
13300 "bsr{l}\t{%1, %0|%0, %1}"
13301 [(set_attr "type" "alu1")
13302 (set_attr "prefix_0f" "1")
13303 (set_attr "znver1_decode" "vector")
13304 (set_attr "mode" "SI")])
13306 (define_insn "*bsrhi"
13307 [(set (match_operand:HI 0 "register_operand" "=r")
13308 (minus:HI (const_int 15)
13309 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13310 (clobber (reg:CC FLAGS_REG))]
13312 "bsr{w}\t{%1, %0|%0, %1}"
13313 [(set_attr "type" "alu1")
13314 (set_attr "prefix_0f" "1")
13315 (set_attr "znver1_decode" "vector")
13316 (set_attr "mode" "HI")])
13318 (define_expand "popcount<mode>2"
13320 [(set (match_operand:SWI248 0 "register_operand")
13322 (match_operand:SWI248 1 "nonimmediate_operand")))
13323 (clobber (reg:CC FLAGS_REG))])]
13326 (define_insn_and_split "*popcount<mode>2_falsedep_1"
13327 [(set (match_operand:SWI48 0 "register_operand" "=r")
13329 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13330 (clobber (reg:CC FLAGS_REG))]
13332 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
13334 "&& reload_completed"
13336 [(set (match_dup 0)
13337 (popcount:SWI48 (match_dup 1)))
13338 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13339 (clobber (reg:CC FLAGS_REG))])]
13341 if (!reg_mentioned_p (operands[0], operands[1]))
13342 ix86_expand_clear (operands[0]);
13345 (define_insn "*popcount<mode>2_falsedep"
13346 [(set (match_operand:SWI48 0 "register_operand" "=r")
13348 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13349 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13350 UNSPEC_INSN_FALSE_DEP)
13351 (clobber (reg:CC FLAGS_REG))]
13355 return "popcnt\t{%1, %0|%0, %1}";
13357 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13360 [(set_attr "prefix_rep" "1")
13361 (set_attr "type" "bitmanip")
13362 (set_attr "mode" "<MODE>")])
13364 (define_insn "*popcount<mode>2"
13365 [(set (match_operand:SWI248 0 "register_operand" "=r")
13367 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
13368 (clobber (reg:CC FLAGS_REG))]
13372 return "popcnt\t{%1, %0|%0, %1}";
13374 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13377 [(set_attr "prefix_rep" "1")
13378 (set_attr "type" "bitmanip")
13379 (set_attr "mode" "<MODE>")])
13381 (define_expand "bswapdi2"
13382 [(set (match_operand:DI 0 "register_operand")
13383 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
13387 operands[1] = force_reg (DImode, operands[1]);
13390 (define_expand "bswapsi2"
13391 [(set (match_operand:SI 0 "register_operand")
13392 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
13397 else if (TARGET_BSWAP)
13398 operands[1] = force_reg (SImode, operands[1]);
13401 rtx x = operands[0];
13403 emit_move_insn (x, operands[1]);
13404 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13405 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
13406 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13411 (define_insn "*bswap<mode>2_movbe"
13412 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
13413 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
13415 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13418 movbe\t{%1, %0|%0, %1}
13419 movbe\t{%1, %0|%0, %1}"
13420 [(set_attr "type" "bitmanip,imov,imov")
13421 (set_attr "modrm" "0,1,1")
13422 (set_attr "prefix_0f" "*,1,1")
13423 (set_attr "prefix_extra" "*,1,1")
13424 (set_attr "mode" "<MODE>")])
13426 (define_insn "*bswap<mode>2"
13427 [(set (match_operand:SWI48 0 "register_operand" "=r")
13428 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
13431 [(set_attr "type" "bitmanip")
13432 (set_attr "modrm" "0")
13433 (set_attr "mode" "<MODE>")])
13435 (define_insn "*bswaphi_lowpart_1"
13436 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
13437 (bswap:HI (match_dup 0)))
13438 (clobber (reg:CC FLAGS_REG))]
13439 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
13441 xchg{b}\t{%h0, %b0|%b0, %h0}
13442 rol{w}\t{$8, %0|%0, 8}"
13443 [(set_attr "length" "2,4")
13444 (set_attr "mode" "QI,HI")])
13446 (define_insn "bswaphi_lowpart"
13447 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
13448 (bswap:HI (match_dup 0)))
13449 (clobber (reg:CC FLAGS_REG))]
13451 "rol{w}\t{$8, %0|%0, 8}"
13452 [(set_attr "length" "4")
13453 (set_attr "mode" "HI")])
13455 (define_expand "paritydi2"
13456 [(set (match_operand:DI 0 "register_operand")
13457 (parity:DI (match_operand:DI 1 "register_operand")))]
13460 rtx scratch = gen_reg_rtx (QImode);
13463 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
13464 NULL_RTX, operands[1]));
13466 cond = gen_rtx_fmt_ee (ORDERED, QImode,
13467 gen_rtx_REG (CCmode, FLAGS_REG),
13469 emit_insn (gen_rtx_SET (scratch, cond));
13472 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
13475 rtx tmp = gen_reg_rtx (SImode);
13477 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
13478 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
13483 (define_expand "paritysi2"
13484 [(set (match_operand:SI 0 "register_operand")
13485 (parity:SI (match_operand:SI 1 "register_operand")))]
13488 rtx scratch = gen_reg_rtx (QImode);
13491 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
13493 cond = gen_rtx_fmt_ee (ORDERED, QImode,
13494 gen_rtx_REG (CCmode, FLAGS_REG),
13496 emit_insn (gen_rtx_SET (scratch, cond));
13498 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
13502 (define_insn_and_split "paritydi2_cmp"
13503 [(set (reg:CC FLAGS_REG)
13504 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
13506 (clobber (match_scratch:DI 0 "=r"))
13507 (clobber (match_scratch:SI 1 "=&r"))
13508 (clobber (match_scratch:HI 2 "=Q"))]
13511 "&& reload_completed"
13513 [(set (match_dup 1)
13514 (xor:SI (match_dup 1) (match_dup 4)))
13515 (clobber (reg:CC FLAGS_REG))])
13517 [(set (reg:CC FLAGS_REG)
13518 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13519 (clobber (match_dup 1))
13520 (clobber (match_dup 2))])]
13522 operands[4] = gen_lowpart (SImode, operands[3]);
13526 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
13527 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
13530 operands[1] = gen_highpart (SImode, operands[3]);
13533 (define_insn_and_split "paritysi2_cmp"
13534 [(set (reg:CC FLAGS_REG)
13535 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
13537 (clobber (match_scratch:SI 0 "=r"))
13538 (clobber (match_scratch:HI 1 "=&Q"))]
13541 "&& reload_completed"
13543 [(set (match_dup 1)
13544 (xor:HI (match_dup 1) (match_dup 3)))
13545 (clobber (reg:CC FLAGS_REG))])
13547 [(set (reg:CC FLAGS_REG)
13548 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13549 (clobber (match_dup 1))])]
13551 operands[3] = gen_lowpart (HImode, operands[2]);
13553 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
13554 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
13557 (define_insn "*parityhi2_cmp"
13558 [(set (reg:CC FLAGS_REG)
13559 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
13561 (clobber (match_scratch:HI 0 "=Q"))]
13563 "xor{b}\t{%h0, %b0|%b0, %h0}"
13564 [(set_attr "length" "2")
13565 (set_attr "mode" "HI")])
13568 ;; Thread-local storage patterns for ELF.
13570 ;; Note that these code sequences must appear exactly as shown
13571 ;; in order to allow linker relaxation.
13573 (define_insn "*tls_global_dynamic_32_gnu"
13574 [(set (match_operand:SI 0 "register_operand" "=a")
13576 [(match_operand:SI 1 "register_operand" "b")
13577 (match_operand 2 "tls_symbolic_operand")
13578 (match_operand 3 "constant_call_address_operand" "Bz")
13581 (clobber (match_scratch:SI 4 "=d"))
13582 (clobber (match_scratch:SI 5 "=c"))
13583 (clobber (reg:CC FLAGS_REG))]
13584 "!TARGET_64BIT && TARGET_GNU_TLS"
13587 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
13588 if (TARGET_SUN_TLS)
13589 #ifdef HAVE_AS_IX86_TLSGDPLT
13590 return "call\t%a2@tlsgdplt";
13592 return "call\t%p3@plt";
13594 return "call\t%P3";
13596 [(set_attr "type" "multi")
13597 (set_attr "length" "12")])
13599 (define_expand "tls_global_dynamic_32"
13601 [(set (match_operand:SI 0 "register_operand")
13602 (unspec:SI [(match_operand:SI 2 "register_operand")
13603 (match_operand 1 "tls_symbolic_operand")
13604 (match_operand 3 "constant_call_address_operand")
13607 (clobber (match_scratch:SI 4))
13608 (clobber (match_scratch:SI 5))
13609 (clobber (reg:CC FLAGS_REG))])]
13611 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13613 (define_insn "*tls_global_dynamic_64_<mode>"
13614 [(set (match_operand:P 0 "register_operand" "=a")
13616 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
13617 (match_operand 3)))
13618 (unspec:P [(match_operand 1 "tls_symbolic_operand")
13624 fputs (ASM_BYTE "0x66\n", asm_out_file);
13626 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13627 fputs (ASM_SHORT "0x6666\n", asm_out_file);
13628 fputs ("\trex64\n", asm_out_file);
13629 if (TARGET_SUN_TLS)
13630 return "call\t%p2@plt";
13631 return "call\t%P2";
13633 [(set_attr "type" "multi")
13634 (set (attr "length")
13635 (symbol_ref "TARGET_X32 ? 15 : 16"))])
13637 (define_insn "*tls_global_dynamic_64_largepic"
13638 [(set (match_operand:DI 0 "register_operand" "=a")
13640 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
13641 (match_operand:DI 3 "immediate_operand" "i")))
13642 (match_operand 4)))
13643 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13646 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13647 && GET_CODE (operands[3]) == CONST
13648 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13649 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13652 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13653 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13654 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13655 return "call\t{*%%rax|rax}";
13657 [(set_attr "type" "multi")
13658 (set_attr "length" "22")])
13660 (define_expand "tls_global_dynamic_64_<mode>"
13662 [(set (match_operand:P 0 "register_operand")
13664 (mem:QI (match_operand 2))
13666 (unspec:P [(match_operand 1 "tls_symbolic_operand")
13670 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13672 (define_insn "*tls_local_dynamic_base_32_gnu"
13673 [(set (match_operand:SI 0 "register_operand" "=a")
13675 [(match_operand:SI 1 "register_operand" "b")
13676 (match_operand 2 "constant_call_address_operand" "Bz")
13678 UNSPEC_TLS_LD_BASE))
13679 (clobber (match_scratch:SI 3 "=d"))
13680 (clobber (match_scratch:SI 4 "=c"))
13681 (clobber (reg:CC FLAGS_REG))]
13682 "!TARGET_64BIT && TARGET_GNU_TLS"
13685 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13686 if (TARGET_SUN_TLS)
13688 if (HAVE_AS_IX86_TLSLDMPLT)
13689 return "call\t%&@tlsldmplt";
13691 return "call\t%p2@plt";
13693 return "call\t%P2";
13695 [(set_attr "type" "multi")
13696 (set_attr "length" "11")])
13698 (define_expand "tls_local_dynamic_base_32"
13700 [(set (match_operand:SI 0 "register_operand")
13702 [(match_operand:SI 1 "register_operand")
13703 (match_operand 2 "constant_call_address_operand")
13705 UNSPEC_TLS_LD_BASE))
13706 (clobber (match_scratch:SI 3))
13707 (clobber (match_scratch:SI 4))
13708 (clobber (reg:CC FLAGS_REG))])]
13710 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13712 (define_insn "*tls_local_dynamic_base_64_<mode>"
13713 [(set (match_operand:P 0 "register_operand" "=a")
13715 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13716 (match_operand 2)))
13717 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
13721 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13722 if (TARGET_SUN_TLS)
13723 return "call\t%p1@plt";
13724 return "call\t%P1";
13726 [(set_attr "type" "multi")
13727 (set_attr "length" "12")])
13729 (define_insn "*tls_local_dynamic_base_64_largepic"
13730 [(set (match_operand:DI 0 "register_operand" "=a")
13732 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13733 (match_operand:DI 2 "immediate_operand" "i")))
13734 (match_operand 3)))
13735 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
13736 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13737 && GET_CODE (operands[2]) == CONST
13738 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13739 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13742 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13743 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13744 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13745 return "call\t{*%%rax|rax}";
13747 [(set_attr "type" "multi")
13748 (set_attr "length" "22")])
13750 (define_expand "tls_local_dynamic_base_64_<mode>"
13752 [(set (match_operand:P 0 "register_operand")
13754 (mem:QI (match_operand 1))
13756 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
13758 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13760 ;; Local dynamic of a single variable is a lose. Show combine how
13761 ;; to convert that back to global dynamic.
13763 (define_insn_and_split "*tls_local_dynamic_32_once"
13764 [(set (match_operand:SI 0 "register_operand" "=a")
13766 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13767 (match_operand 2 "constant_call_address_operand" "Bz")
13769 UNSPEC_TLS_LD_BASE)
13770 (const:SI (unspec:SI
13771 [(match_operand 3 "tls_symbolic_operand")]
13773 (clobber (match_scratch:SI 4 "=d"))
13774 (clobber (match_scratch:SI 5 "=c"))
13775 (clobber (reg:CC FLAGS_REG))]
13780 [(set (match_dup 0)
13781 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13784 (clobber (match_dup 4))
13785 (clobber (match_dup 5))
13786 (clobber (reg:CC FLAGS_REG))])])
13788 ;; Segment register for the thread base ptr load
13789 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13791 ;; Load and add the thread base pointer from %<tp_seg>:0.
13792 (define_insn "*load_tp_x32"
13793 [(set (match_operand:SI 0 "register_operand" "=r")
13794 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13796 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13797 [(set_attr "type" "imov")
13798 (set_attr "modrm" "0")
13799 (set_attr "length" "7")
13800 (set_attr "memory" "load")
13801 (set_attr "imm_disp" "false")])
13803 (define_insn "*load_tp_x32_zext"
13804 [(set (match_operand:DI 0 "register_operand" "=r")
13805 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13807 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13808 [(set_attr "type" "imov")
13809 (set_attr "modrm" "0")
13810 (set_attr "length" "7")
13811 (set_attr "memory" "load")
13812 (set_attr "imm_disp" "false")])
13814 (define_insn "*load_tp_<mode>"
13815 [(set (match_operand:P 0 "register_operand" "=r")
13816 (unspec:P [(const_int 0)] UNSPEC_TP))]
13818 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13819 [(set_attr "type" "imov")
13820 (set_attr "modrm" "0")
13821 (set_attr "length" "7")
13822 (set_attr "memory" "load")
13823 (set_attr "imm_disp" "false")])
13825 (define_insn "*add_tp_x32"
13826 [(set (match_operand:SI 0 "register_operand" "=r")
13827 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13828 (match_operand:SI 1 "register_operand" "0")))
13829 (clobber (reg:CC FLAGS_REG))]
13831 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13832 [(set_attr "type" "alu")
13833 (set_attr "modrm" "0")
13834 (set_attr "length" "7")
13835 (set_attr "memory" "load")
13836 (set_attr "imm_disp" "false")])
13838 (define_insn "*add_tp_x32_zext"
13839 [(set (match_operand:DI 0 "register_operand" "=r")
13841 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13842 (match_operand:SI 1 "register_operand" "0"))))
13843 (clobber (reg:CC FLAGS_REG))]
13845 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13846 [(set_attr "type" "alu")
13847 (set_attr "modrm" "0")
13848 (set_attr "length" "7")
13849 (set_attr "memory" "load")
13850 (set_attr "imm_disp" "false")])
13852 (define_insn "*add_tp_<mode>"
13853 [(set (match_operand:P 0 "register_operand" "=r")
13854 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13855 (match_operand:P 1 "register_operand" "0")))
13856 (clobber (reg:CC FLAGS_REG))]
13858 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13859 [(set_attr "type" "alu")
13860 (set_attr "modrm" "0")
13861 (set_attr "length" "7")
13862 (set_attr "memory" "load")
13863 (set_attr "imm_disp" "false")])
13865 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13866 ;; %rax as destination of the initial executable code sequence.
13867 (define_insn "tls_initial_exec_64_sun"
13868 [(set (match_operand:DI 0 "register_operand" "=a")
13870 [(match_operand 1 "tls_symbolic_operand")]
13871 UNSPEC_TLS_IE_SUN))
13872 (clobber (reg:CC FLAGS_REG))]
13873 "TARGET_64BIT && TARGET_SUN_TLS"
13876 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13877 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13879 [(set_attr "type" "multi")])
13881 ;; GNU2 TLS patterns can be split.
13883 (define_expand "tls_dynamic_gnu2_32"
13884 [(set (match_dup 3)
13885 (plus:SI (match_operand:SI 2 "register_operand")
13887 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13890 [(set (match_operand:SI 0 "register_operand")
13891 (unspec:SI [(match_dup 1) (match_dup 3)
13892 (match_dup 2) (reg:SI SP_REG)]
13894 (clobber (reg:CC FLAGS_REG))])]
13895 "!TARGET_64BIT && TARGET_GNU2_TLS"
13897 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13898 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13901 (define_insn "*tls_dynamic_gnu2_lea_32"
13902 [(set (match_operand:SI 0 "register_operand" "=r")
13903 (plus:SI (match_operand:SI 1 "register_operand" "b")
13905 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13906 UNSPEC_TLSDESC))))]
13907 "!TARGET_64BIT && TARGET_GNU2_TLS"
13908 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13909 [(set_attr "type" "lea")
13910 (set_attr "mode" "SI")
13911 (set_attr "length" "6")
13912 (set_attr "length_address" "4")])
13914 (define_insn "*tls_dynamic_gnu2_call_32"
13915 [(set (match_operand:SI 0 "register_operand" "=a")
13916 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13917 (match_operand:SI 2 "register_operand" "0")
13918 ;; we have to make sure %ebx still points to the GOT
13919 (match_operand:SI 3 "register_operand" "b")
13922 (clobber (reg:CC FLAGS_REG))]
13923 "!TARGET_64BIT && TARGET_GNU2_TLS"
13924 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13925 [(set_attr "type" "call")
13926 (set_attr "length" "2")
13927 (set_attr "length_address" "0")])
13929 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13930 [(set (match_operand:SI 0 "register_operand" "=&a")
13932 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13933 (match_operand:SI 4)
13934 (match_operand:SI 2 "register_operand" "b")
13937 (const:SI (unspec:SI
13938 [(match_operand 1 "tls_symbolic_operand")]
13940 (clobber (reg:CC FLAGS_REG))]
13941 "!TARGET_64BIT && TARGET_GNU2_TLS"
13944 [(set (match_dup 0) (match_dup 5))]
13946 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13947 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13950 (define_expand "tls_dynamic_gnu2_64"
13951 [(set (match_dup 2)
13952 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13955 [(set (match_operand:DI 0 "register_operand")
13956 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13958 (clobber (reg:CC FLAGS_REG))])]
13959 "TARGET_64BIT && TARGET_GNU2_TLS"
13961 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13962 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13965 (define_insn "*tls_dynamic_gnu2_lea_64"
13966 [(set (match_operand:DI 0 "register_operand" "=r")
13967 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13969 "TARGET_64BIT && TARGET_GNU2_TLS"
13970 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13971 [(set_attr "type" "lea")
13972 (set_attr "mode" "DI")
13973 (set_attr "length" "7")
13974 (set_attr "length_address" "4")])
13976 (define_insn "*tls_dynamic_gnu2_call_64"
13977 [(set (match_operand:DI 0 "register_operand" "=a")
13978 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13979 (match_operand:DI 2 "register_operand" "0")
13982 (clobber (reg:CC FLAGS_REG))]
13983 "TARGET_64BIT && TARGET_GNU2_TLS"
13984 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13985 [(set_attr "type" "call")
13986 (set_attr "length" "2")
13987 (set_attr "length_address" "0")])
13989 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13990 [(set (match_operand:DI 0 "register_operand" "=&a")
13992 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13993 (match_operand:DI 3)
13996 (const:DI (unspec:DI
13997 [(match_operand 1 "tls_symbolic_operand")]
13999 (clobber (reg:CC FLAGS_REG))]
14000 "TARGET_64BIT && TARGET_GNU2_TLS"
14003 [(set (match_dup 0) (match_dup 4))]
14005 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14006 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14009 ;; These patterns match the binary 387 instructions for addM3, subM3,
14010 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14011 ;; SFmode. The first is the normal insn, the second the same insn but
14012 ;; with one operand a conversion, and the third the same insn but with
14013 ;; the other operand a conversion. The conversion may be SFmode or
14014 ;; SImode if the target mode DFmode, but only SImode if the target mode
14017 ;; Gcc is slightly more smart about handling normal two address instructions
14018 ;; so use special patterns for add and mull.
14020 (define_insn "*fop_<mode>_comm"
14021 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
14022 (match_operator:MODEF 3 "binary_fp_operator"
14023 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
14024 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
14025 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14026 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14027 && COMMUTATIVE_ARITH_P (operands[3])
14028 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14029 "* return output_387_binary_op (insn, operands);"
14030 [(set (attr "type")
14031 (if_then_else (eq_attr "alternative" "1,2")
14032 (if_then_else (match_operand:MODEF 3 "mult_operator")
14033 (const_string "ssemul")
14034 (const_string "sseadd"))
14035 (if_then_else (match_operand:MODEF 3 "mult_operator")
14036 (const_string "fmul")
14037 (const_string "fop"))))
14038 (set_attr "isa" "*,noavx,avx")
14039 (set_attr "prefix" "orig,orig,vex")
14040 (set_attr "mode" "<MODE>")
14041 (set (attr "enabled")
14043 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14045 (eq_attr "alternative" "0")
14046 (symbol_ref "TARGET_MIX_SSE_I387
14047 && X87_ENABLE_ARITH (<MODE>mode)")
14048 (const_string "*"))
14050 (eq_attr "alternative" "0")
14051 (symbol_ref "true")
14052 (symbol_ref "false"))))])
14054 (define_insn "*rcpsf2_sse"
14055 [(set (match_operand:SF 0 "register_operand" "=x")
14056 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14059 "%vrcpss\t{%1, %d0|%d0, %1}"
14060 [(set_attr "type" "sse")
14061 (set_attr "atom_sse_attr" "rcp")
14062 (set_attr "btver2_sse_attr" "rcp")
14063 (set_attr "prefix" "maybe_vex")
14064 (set_attr "mode" "SF")])
14066 (define_insn "*fop_<mode>_1"
14067 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
14068 (match_operator:MODEF 3 "binary_fp_operator"
14069 [(match_operand:MODEF 1
14070 "x87nonimm_ssenomem_operand" "0,fm,0,v")
14071 (match_operand:MODEF 2
14072 "nonimmediate_operand" "fm,0,xm,vm")]))]
14073 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14074 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14075 && !COMMUTATIVE_ARITH_P (operands[3])
14076 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14077 "* return output_387_binary_op (insn, operands);"
14078 [(set (attr "type")
14079 (if_then_else (eq_attr "alternative" "2,3")
14080 (if_then_else (match_operand:MODEF 3 "div_operator")
14081 (const_string "ssediv")
14082 (const_string "sseadd"))
14083 (if_then_else (match_operand:MODEF 3 "div_operator")
14084 (const_string "fdiv")
14085 (const_string "fop"))))
14086 (set_attr "isa" "*,*,noavx,avx")
14087 (set_attr "prefix" "orig,orig,orig,vex")
14088 (set_attr "mode" "<MODE>")
14089 (set (attr "enabled")
14091 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14093 (eq_attr "alternative" "0,1")
14094 (symbol_ref "TARGET_MIX_SSE_I387
14095 && X87_ENABLE_ARITH (<MODE>mode)")
14096 (const_string "*"))
14098 (eq_attr "alternative" "0,1")
14099 (symbol_ref "true")
14100 (symbol_ref "false"))))])
14102 ;; ??? Add SSE splitters for these!
14103 (define_insn "*fop_<MODEF:mode>_2_i387"
14104 [(set (match_operand:MODEF 0 "register_operand" "=f")
14105 (match_operator:MODEF 3 "binary_fp_operator"
14107 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14108 (match_operand:MODEF 2 "register_operand" "0")]))]
14109 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14110 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14111 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14112 || optimize_function_for_size_p (cfun))"
14113 "* return output_387_binary_op (insn, operands);"
14114 [(set (attr "type")
14115 (cond [(match_operand:MODEF 3 "mult_operator")
14116 (const_string "fmul")
14117 (match_operand:MODEF 3 "div_operator")
14118 (const_string "fdiv")
14120 (const_string "fop")))
14121 (set_attr "fp_int_src" "true")
14122 (set_attr "mode" "<SWI24:MODE>")])
14124 (define_insn "*fop_<MODEF:mode>_3_i387"
14125 [(set (match_operand:MODEF 0 "register_operand" "=f")
14126 (match_operator:MODEF 3 "binary_fp_operator"
14127 [(match_operand:MODEF 1 "register_operand" "0")
14129 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14130 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14131 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14132 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14133 || optimize_function_for_size_p (cfun))"
14134 "* return output_387_binary_op (insn, operands);"
14135 [(set (attr "type")
14136 (cond [(match_operand:MODEF 3 "mult_operator")
14137 (const_string "fmul")
14138 (match_operand:MODEF 3 "div_operator")
14139 (const_string "fdiv")
14141 (const_string "fop")))
14142 (set_attr "fp_int_src" "true")
14143 (set_attr "mode" "<MODE>")])
14145 (define_insn "*fop_df_4_i387"
14146 [(set (match_operand:DF 0 "register_operand" "=f,f")
14147 (match_operator:DF 3 "binary_fp_operator"
14149 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14150 (match_operand:DF 2 "register_operand" "0,f")]))]
14151 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14152 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14153 "* return output_387_binary_op (insn, operands);"
14154 [(set (attr "type")
14155 (cond [(match_operand:DF 3 "mult_operator")
14156 (const_string "fmul")
14157 (match_operand:DF 3 "div_operator")
14158 (const_string "fdiv")
14160 (const_string "fop")))
14161 (set_attr "mode" "SF")])
14163 (define_insn "*fop_df_5_i387"
14164 [(set (match_operand:DF 0 "register_operand" "=f,f")
14165 (match_operator:DF 3 "binary_fp_operator"
14166 [(match_operand:DF 1 "register_operand" "0,f")
14168 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14169 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14170 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14171 "* return output_387_binary_op (insn, operands);"
14172 [(set (attr "type")
14173 (cond [(match_operand:DF 3 "mult_operator")
14174 (const_string "fmul")
14175 (match_operand:DF 3 "div_operator")
14176 (const_string "fdiv")
14178 (const_string "fop")))
14179 (set_attr "mode" "SF")])
14181 (define_insn "*fop_df_6_i387"
14182 [(set (match_operand:DF 0 "register_operand" "=f,f")
14183 (match_operator:DF 3 "binary_fp_operator"
14185 (match_operand:SF 1 "register_operand" "0,f"))
14187 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14188 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14189 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14190 "* return output_387_binary_op (insn, operands);"
14191 [(set (attr "type")
14192 (cond [(match_operand:DF 3 "mult_operator")
14193 (const_string "fmul")
14194 (match_operand:DF 3 "div_operator")
14195 (const_string "fdiv")
14197 (const_string "fop")))
14198 (set_attr "mode" "SF")])
14200 (define_insn "*fop_xf_comm_i387"
14201 [(set (match_operand:XF 0 "register_operand" "=f")
14202 (match_operator:XF 3 "binary_fp_operator"
14203 [(match_operand:XF 1 "register_operand" "%0")
14204 (match_operand:XF 2 "register_operand" "f")]))]
14206 && COMMUTATIVE_ARITH_P (operands[3])"
14207 "* return output_387_binary_op (insn, operands);"
14208 [(set (attr "type")
14209 (if_then_else (match_operand:XF 3 "mult_operator")
14210 (const_string "fmul")
14211 (const_string "fop")))
14212 (set_attr "mode" "XF")])
14214 (define_insn "*fop_xf_1_i387"
14215 [(set (match_operand:XF 0 "register_operand" "=f,f")
14216 (match_operator:XF 3 "binary_fp_operator"
14217 [(match_operand:XF 1 "register_operand" "0,f")
14218 (match_operand:XF 2 "register_operand" "f,0")]))]
14220 && !COMMUTATIVE_ARITH_P (operands[3])"
14221 "* return output_387_binary_op (insn, operands);"
14222 [(set (attr "type")
14223 (if_then_else (match_operand:XF 3 "div_operator")
14224 (const_string "fdiv")
14225 (const_string "fop")))
14226 (set_attr "mode" "XF")])
14228 (define_insn "*fop_xf_2_i387"
14229 [(set (match_operand:XF 0 "register_operand" "=f")
14230 (match_operator:XF 3 "binary_fp_operator"
14232 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14233 (match_operand:XF 2 "register_operand" "0")]))]
14235 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14236 "* return output_387_binary_op (insn, operands);"
14237 [(set (attr "type")
14238 (cond [(match_operand:XF 3 "mult_operator")
14239 (const_string "fmul")
14240 (match_operand:XF 3 "div_operator")
14241 (const_string "fdiv")
14243 (const_string "fop")))
14244 (set_attr "fp_int_src" "true")
14245 (set_attr "mode" "<MODE>")])
14247 (define_insn "*fop_xf_3_i387"
14248 [(set (match_operand:XF 0 "register_operand" "=f")
14249 (match_operator:XF 3 "binary_fp_operator"
14250 [(match_operand:XF 1 "register_operand" "0")
14252 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14254 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14255 "* return output_387_binary_op (insn, operands);"
14256 [(set (attr "type")
14257 (cond [(match_operand:XF 3 "mult_operator")
14258 (const_string "fmul")
14259 (match_operand:XF 3 "div_operator")
14260 (const_string "fdiv")
14262 (const_string "fop")))
14263 (set_attr "fp_int_src" "true")
14264 (set_attr "mode" "<MODE>")])
14266 (define_insn "*fop_xf_4_i387"
14267 [(set (match_operand:XF 0 "register_operand" "=f,f")
14268 (match_operator:XF 3 "binary_fp_operator"
14270 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
14271 (match_operand:XF 2 "register_operand" "0,f")]))]
14273 "* return output_387_binary_op (insn, operands);"
14274 [(set (attr "type")
14275 (cond [(match_operand:XF 3 "mult_operator")
14276 (const_string "fmul")
14277 (match_operand:XF 3 "div_operator")
14278 (const_string "fdiv")
14280 (const_string "fop")))
14281 (set_attr "mode" "<MODE>")])
14283 (define_insn "*fop_xf_5_i387"
14284 [(set (match_operand:XF 0 "register_operand" "=f,f")
14285 (match_operator:XF 3 "binary_fp_operator"
14286 [(match_operand:XF 1 "register_operand" "0,f")
14288 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14290 "* return output_387_binary_op (insn, operands);"
14291 [(set (attr "type")
14292 (cond [(match_operand:XF 3 "mult_operator")
14293 (const_string "fmul")
14294 (match_operand:XF 3 "div_operator")
14295 (const_string "fdiv")
14297 (const_string "fop")))
14298 (set_attr "mode" "<MODE>")])
14300 (define_insn "*fop_xf_6_i387"
14301 [(set (match_operand:XF 0 "register_operand" "=f,f")
14302 (match_operator:XF 3 "binary_fp_operator"
14304 (match_operand:MODEF 1 "register_operand" "0,f"))
14306 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14308 "* return output_387_binary_op (insn, operands);"
14309 [(set (attr "type")
14310 (cond [(match_operand:XF 3 "mult_operator")
14311 (const_string "fmul")
14312 (match_operand:XF 3 "div_operator")
14313 (const_string "fdiv")
14315 (const_string "fop")))
14316 (set_attr "mode" "<MODE>")])
14318 ;; FPU special functions.
14320 ;; This pattern implements a no-op XFmode truncation for
14321 ;; all fancy i386 XFmode math functions.
14323 (define_insn "truncxf<mode>2_i387_noop_unspec"
14324 [(set (match_operand:MODEF 0 "register_operand" "=f")
14325 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
14326 UNSPEC_TRUNC_NOOP))]
14327 "TARGET_USE_FANCY_MATH_387"
14328 "* return output_387_reg_move (insn, operands);"
14329 [(set_attr "type" "fmov")
14330 (set_attr "mode" "<MODE>")])
14332 (define_insn "sqrtxf2"
14333 [(set (match_operand:XF 0 "register_operand" "=f")
14334 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14335 "TARGET_USE_FANCY_MATH_387"
14337 [(set_attr "type" "fpspc")
14338 (set_attr "mode" "XF")
14339 (set_attr "athlon_decode" "direct")
14340 (set_attr "amdfam10_decode" "direct")
14341 (set_attr "bdver1_decode" "direct")])
14343 (define_insn "sqrt_extend<mode>xf2_i387"
14344 [(set (match_operand:XF 0 "register_operand" "=f")
14347 (match_operand:MODEF 1 "register_operand" "0"))))]
14348 "TARGET_USE_FANCY_MATH_387"
14350 [(set_attr "type" "fpspc")
14351 (set_attr "mode" "XF")
14352 (set_attr "athlon_decode" "direct")
14353 (set_attr "amdfam10_decode" "direct")
14354 (set_attr "bdver1_decode" "direct")])
14356 (define_insn "*rsqrtsf2_sse"
14357 [(set (match_operand:SF 0 "register_operand" "=x")
14358 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14361 "%vrsqrtss\t{%1, %d0|%d0, %1}"
14362 [(set_attr "type" "sse")
14363 (set_attr "atom_sse_attr" "rcp")
14364 (set_attr "btver2_sse_attr" "rcp")
14365 (set_attr "prefix" "maybe_vex")
14366 (set_attr "mode" "SF")])
14368 (define_expand "rsqrtsf2"
14369 [(set (match_operand:SF 0 "register_operand")
14370 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
14374 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
14378 (define_insn "*sqrt<mode>2_sse"
14379 [(set (match_operand:MODEF 0 "register_operand" "=v")
14381 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
14382 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14383 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
14384 [(set_attr "type" "sse")
14385 (set_attr "atom_sse_attr" "sqrt")
14386 (set_attr "btver2_sse_attr" "sqrt")
14387 (set_attr "prefix" "maybe_vex")
14388 (set_attr "mode" "<MODE>")
14389 (set_attr "athlon_decode" "*")
14390 (set_attr "amdfam10_decode" "*")
14391 (set_attr "bdver1_decode" "*")])
14393 (define_expand "sqrt<mode>2"
14394 [(set (match_operand:MODEF 0 "register_operand")
14396 (match_operand:MODEF 1 "nonimmediate_operand")))]
14397 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
14398 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14400 if (<MODE>mode == SFmode
14402 && TARGET_RECIP_SQRT
14403 && !optimize_function_for_size_p (cfun)
14404 && flag_finite_math_only && !flag_trapping_math
14405 && flag_unsafe_math_optimizations)
14407 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
14411 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
14413 rtx op0 = gen_reg_rtx (XFmode);
14414 rtx op1 = force_reg (<MODE>mode, operands[1]);
14416 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
14417 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
14422 (define_insn "fpremxf4_i387"
14423 [(set (match_operand:XF 0 "register_operand" "=f")
14424 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14425 (match_operand:XF 3 "register_operand" "1")]
14427 (set (match_operand:XF 1 "register_operand" "=u")
14428 (unspec:XF [(match_dup 2) (match_dup 3)]
14430 (set (reg:CCFP FPSR_REG)
14431 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14433 "TARGET_USE_FANCY_MATH_387
14434 && flag_finite_math_only"
14436 [(set_attr "type" "fpspc")
14437 (set_attr "znver1_decode" "vector")
14438 (set_attr "mode" "XF")])
14440 (define_expand "fmodxf3"
14441 [(use (match_operand:XF 0 "register_operand"))
14442 (use (match_operand:XF 1 "general_operand"))
14443 (use (match_operand:XF 2 "general_operand"))]
14444 "TARGET_USE_FANCY_MATH_387
14445 && flag_finite_math_only"
14447 rtx_code_label *label = gen_label_rtx ();
14449 rtx op1 = gen_reg_rtx (XFmode);
14450 rtx op2 = gen_reg_rtx (XFmode);
14452 emit_move_insn (op2, operands[2]);
14453 emit_move_insn (op1, operands[1]);
14455 emit_label (label);
14456 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14457 ix86_emit_fp_unordered_jump (label);
14458 LABEL_NUSES (label) = 1;
14460 emit_move_insn (operands[0], op1);
14464 (define_expand "fmod<mode>3"
14465 [(use (match_operand:MODEF 0 "register_operand"))
14466 (use (match_operand:MODEF 1 "general_operand"))
14467 (use (match_operand:MODEF 2 "general_operand"))]
14468 "TARGET_USE_FANCY_MATH_387
14469 && flag_finite_math_only"
14471 rtx (*gen_truncxf) (rtx, rtx);
14473 rtx_code_label *label = gen_label_rtx ();
14475 rtx op1 = gen_reg_rtx (XFmode);
14476 rtx op2 = gen_reg_rtx (XFmode);
14478 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14479 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14481 emit_label (label);
14482 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14483 ix86_emit_fp_unordered_jump (label);
14484 LABEL_NUSES (label) = 1;
14486 /* Truncate the result properly for strict SSE math. */
14487 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14488 && !TARGET_MIX_SSE_I387)
14489 gen_truncxf = gen_truncxf<mode>2;
14491 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14493 emit_insn (gen_truncxf (operands[0], op1));
14497 (define_insn "fprem1xf4_i387"
14498 [(set (match_operand:XF 0 "register_operand" "=f")
14499 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14500 (match_operand:XF 3 "register_operand" "1")]
14502 (set (match_operand:XF 1 "register_operand" "=u")
14503 (unspec:XF [(match_dup 2) (match_dup 3)]
14505 (set (reg:CCFP FPSR_REG)
14506 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14508 "TARGET_USE_FANCY_MATH_387
14509 && flag_finite_math_only"
14511 [(set_attr "type" "fpspc")
14512 (set_attr "znver1_decode" "vector")
14513 (set_attr "mode" "XF")])
14515 (define_expand "remainderxf3"
14516 [(use (match_operand:XF 0 "register_operand"))
14517 (use (match_operand:XF 1 "general_operand"))
14518 (use (match_operand:XF 2 "general_operand"))]
14519 "TARGET_USE_FANCY_MATH_387
14520 && flag_finite_math_only"
14522 rtx_code_label *label = gen_label_rtx ();
14524 rtx op1 = gen_reg_rtx (XFmode);
14525 rtx op2 = gen_reg_rtx (XFmode);
14527 emit_move_insn (op2, operands[2]);
14528 emit_move_insn (op1, operands[1]);
14530 emit_label (label);
14531 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14532 ix86_emit_fp_unordered_jump (label);
14533 LABEL_NUSES (label) = 1;
14535 emit_move_insn (operands[0], op1);
14539 (define_expand "remainder<mode>3"
14540 [(use (match_operand:MODEF 0 "register_operand"))
14541 (use (match_operand:MODEF 1 "general_operand"))
14542 (use (match_operand:MODEF 2 "general_operand"))]
14543 "TARGET_USE_FANCY_MATH_387
14544 && flag_finite_math_only"
14546 rtx (*gen_truncxf) (rtx, rtx);
14548 rtx_code_label *label = gen_label_rtx ();
14550 rtx op1 = gen_reg_rtx (XFmode);
14551 rtx op2 = gen_reg_rtx (XFmode);
14553 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14554 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14556 emit_label (label);
14558 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14559 ix86_emit_fp_unordered_jump (label);
14560 LABEL_NUSES (label) = 1;
14562 /* Truncate the result properly for strict SSE math. */
14563 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14564 && !TARGET_MIX_SSE_I387)
14565 gen_truncxf = gen_truncxf<mode>2;
14567 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14569 emit_insn (gen_truncxf (operands[0], op1));
14573 (define_int_iterator SINCOS
14577 (define_int_attr sincos
14578 [(UNSPEC_SIN "sin")
14579 (UNSPEC_COS "cos")])
14581 (define_insn "*<sincos>xf2_i387"
14582 [(set (match_operand:XF 0 "register_operand" "=f")
14583 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14585 "TARGET_USE_FANCY_MATH_387
14586 && flag_unsafe_math_optimizations"
14588 [(set_attr "type" "fpspc")
14589 (set_attr "znver1_decode" "vector")
14590 (set_attr "mode" "XF")])
14592 (define_insn "*<sincos>_extend<mode>xf2_i387"
14593 [(set (match_operand:XF 0 "register_operand" "=f")
14594 (unspec:XF [(float_extend:XF
14595 (match_operand:MODEF 1 "register_operand" "0"))]
14597 "TARGET_USE_FANCY_MATH_387
14598 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14599 || TARGET_MIX_SSE_I387)
14600 && flag_unsafe_math_optimizations"
14602 [(set_attr "type" "fpspc")
14603 (set_attr "znver1_decode" "vector")
14604 (set_attr "mode" "XF")])
14606 ;; When sincos pattern is defined, sin and cos builtin functions will be
14607 ;; expanded to sincos pattern with one of its outputs left unused.
14608 ;; CSE pass will figure out if two sincos patterns can be combined,
14609 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14610 ;; depending on the unused output.
14612 (define_insn "sincosxf3"
14613 [(set (match_operand:XF 0 "register_operand" "=f")
14614 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14615 UNSPEC_SINCOS_COS))
14616 (set (match_operand:XF 1 "register_operand" "=u")
14617 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14618 "TARGET_USE_FANCY_MATH_387
14619 && flag_unsafe_math_optimizations"
14621 [(set_attr "type" "fpspc")
14622 (set_attr "znver1_decode" "vector")
14623 (set_attr "mode" "XF")])
14626 [(set (match_operand:XF 0 "register_operand")
14627 (unspec:XF [(match_operand:XF 2 "register_operand")]
14628 UNSPEC_SINCOS_COS))
14629 (set (match_operand:XF 1 "register_operand")
14630 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14631 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14632 && can_create_pseudo_p ()"
14633 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14636 [(set (match_operand:XF 0 "register_operand")
14637 (unspec:XF [(match_operand:XF 2 "register_operand")]
14638 UNSPEC_SINCOS_COS))
14639 (set (match_operand:XF 1 "register_operand")
14640 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14641 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14642 && can_create_pseudo_p ()"
14643 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14645 (define_insn "sincos_extend<mode>xf3_i387"
14646 [(set (match_operand:XF 0 "register_operand" "=f")
14647 (unspec:XF [(float_extend:XF
14648 (match_operand:MODEF 2 "register_operand" "0"))]
14649 UNSPEC_SINCOS_COS))
14650 (set (match_operand:XF 1 "register_operand" "=u")
14651 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14652 "TARGET_USE_FANCY_MATH_387
14653 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14654 || TARGET_MIX_SSE_I387)
14655 && flag_unsafe_math_optimizations"
14657 [(set_attr "type" "fpspc")
14658 (set_attr "znver1_decode" "vector")
14659 (set_attr "mode" "XF")])
14662 [(set (match_operand:XF 0 "register_operand")
14663 (unspec:XF [(float_extend:XF
14664 (match_operand:MODEF 2 "register_operand"))]
14665 UNSPEC_SINCOS_COS))
14666 (set (match_operand:XF 1 "register_operand")
14667 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14668 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14669 && can_create_pseudo_p ()"
14670 [(set (match_dup 1)
14671 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14674 [(set (match_operand:XF 0 "register_operand")
14675 (unspec:XF [(float_extend:XF
14676 (match_operand:MODEF 2 "register_operand"))]
14677 UNSPEC_SINCOS_COS))
14678 (set (match_operand:XF 1 "register_operand")
14679 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14680 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14681 && can_create_pseudo_p ()"
14682 [(set (match_dup 0)
14683 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14685 (define_expand "sincos<mode>3"
14686 [(use (match_operand:MODEF 0 "register_operand"))
14687 (use (match_operand:MODEF 1 "register_operand"))
14688 (use (match_operand:MODEF 2 "register_operand"))]
14689 "TARGET_USE_FANCY_MATH_387
14690 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14691 || TARGET_MIX_SSE_I387)
14692 && flag_unsafe_math_optimizations"
14694 rtx op0 = gen_reg_rtx (XFmode);
14695 rtx op1 = gen_reg_rtx (XFmode);
14697 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14698 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14699 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14703 (define_insn "fptanxf4_i387"
14704 [(set (match_operand:XF 0 "register_operand" "=f")
14705 (match_operand:XF 3 "const_double_operand" "F"))
14706 (set (match_operand:XF 1 "register_operand" "=u")
14707 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14709 "TARGET_USE_FANCY_MATH_387
14710 && flag_unsafe_math_optimizations
14711 && standard_80387_constant_p (operands[3]) == 2"
14713 [(set_attr "type" "fpspc")
14714 (set_attr "znver1_decode" "vector")
14715 (set_attr "mode" "XF")])
14717 (define_insn "fptan_extend<mode>xf4_i387"
14718 [(set (match_operand:MODEF 0 "register_operand" "=f")
14719 (match_operand:MODEF 3 "const_double_operand" "F"))
14720 (set (match_operand:XF 1 "register_operand" "=u")
14721 (unspec:XF [(float_extend:XF
14722 (match_operand:MODEF 2 "register_operand" "0"))]
14724 "TARGET_USE_FANCY_MATH_387
14725 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14726 || TARGET_MIX_SSE_I387)
14727 && flag_unsafe_math_optimizations
14728 && standard_80387_constant_p (operands[3]) == 2"
14730 [(set_attr "type" "fpspc")
14731 (set_attr "znver1_decode" "vector")
14732 (set_attr "mode" "XF")])
14734 (define_expand "tanxf2"
14735 [(use (match_operand:XF 0 "register_operand"))
14736 (use (match_operand:XF 1 "register_operand"))]
14737 "TARGET_USE_FANCY_MATH_387
14738 && flag_unsafe_math_optimizations"
14740 rtx one = gen_reg_rtx (XFmode);
14741 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14743 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14747 (define_expand "tan<mode>2"
14748 [(use (match_operand:MODEF 0 "register_operand"))
14749 (use (match_operand:MODEF 1 "register_operand"))]
14750 "TARGET_USE_FANCY_MATH_387
14751 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14752 || TARGET_MIX_SSE_I387)
14753 && flag_unsafe_math_optimizations"
14755 rtx op0 = gen_reg_rtx (XFmode);
14757 rtx one = gen_reg_rtx (<MODE>mode);
14758 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14760 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14761 operands[1], op2));
14762 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14766 (define_insn "*fpatanxf3_i387"
14767 [(set (match_operand:XF 0 "register_operand" "=f")
14768 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14769 (match_operand:XF 2 "register_operand" "u")]
14771 (clobber (match_scratch:XF 3 "=2"))]
14772 "TARGET_USE_FANCY_MATH_387
14773 && flag_unsafe_math_optimizations"
14775 [(set_attr "type" "fpspc")
14776 (set_attr "znver1_decode" "vector")
14777 (set_attr "mode" "XF")])
14779 (define_insn "fpatan_extend<mode>xf3_i387"
14780 [(set (match_operand:XF 0 "register_operand" "=f")
14781 (unspec:XF [(float_extend:XF
14782 (match_operand:MODEF 1 "register_operand" "0"))
14784 (match_operand:MODEF 2 "register_operand" "u"))]
14786 (clobber (match_scratch:XF 3 "=2"))]
14787 "TARGET_USE_FANCY_MATH_387
14788 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14789 || TARGET_MIX_SSE_I387)
14790 && flag_unsafe_math_optimizations"
14792 [(set_attr "type" "fpspc")
14793 (set_attr "znver1_decode" "vector")
14794 (set_attr "mode" "XF")])
14796 (define_expand "atan2xf3"
14797 [(parallel [(set (match_operand:XF 0 "register_operand")
14798 (unspec:XF [(match_operand:XF 2 "register_operand")
14799 (match_operand:XF 1 "register_operand")]
14801 (clobber (match_scratch:XF 3))])]
14802 "TARGET_USE_FANCY_MATH_387
14803 && flag_unsafe_math_optimizations")
14805 (define_expand "atan2<mode>3"
14806 [(use (match_operand:MODEF 0 "register_operand"))
14807 (use (match_operand:MODEF 1 "register_operand"))
14808 (use (match_operand:MODEF 2 "register_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);
14816 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14817 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14821 (define_expand "atanxf2"
14822 [(parallel [(set (match_operand:XF 0 "register_operand")
14823 (unspec:XF [(match_dup 2)
14824 (match_operand:XF 1 "register_operand")]
14826 (clobber (match_scratch:XF 3))])]
14827 "TARGET_USE_FANCY_MATH_387
14828 && flag_unsafe_math_optimizations"
14830 operands[2] = gen_reg_rtx (XFmode);
14831 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14834 (define_expand "atan<mode>2"
14835 [(use (match_operand:MODEF 0 "register_operand"))
14836 (use (match_operand:MODEF 1 "register_operand"))]
14837 "TARGET_USE_FANCY_MATH_387
14838 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14839 || TARGET_MIX_SSE_I387)
14840 && flag_unsafe_math_optimizations"
14842 rtx op0 = gen_reg_rtx (XFmode);
14844 rtx op2 = gen_reg_rtx (<MODE>mode);
14845 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14847 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14848 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14852 (define_expand "asinxf2"
14853 [(set (match_dup 2)
14854 (mult:XF (match_operand:XF 1 "register_operand")
14856 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14857 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14858 (parallel [(set (match_operand:XF 0 "register_operand")
14859 (unspec:XF [(match_dup 5) (match_dup 1)]
14861 (clobber (match_scratch:XF 6))])]
14862 "TARGET_USE_FANCY_MATH_387
14863 && flag_unsafe_math_optimizations"
14867 for (i = 2; i < 6; i++)
14868 operands[i] = gen_reg_rtx (XFmode);
14870 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14873 (define_expand "asin<mode>2"
14874 [(use (match_operand:MODEF 0 "register_operand"))
14875 (use (match_operand:MODEF 1 "general_operand"))]
14876 "TARGET_USE_FANCY_MATH_387
14877 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14878 || TARGET_MIX_SSE_I387)
14879 && flag_unsafe_math_optimizations"
14881 rtx op0 = gen_reg_rtx (XFmode);
14882 rtx op1 = gen_reg_rtx (XFmode);
14884 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14885 emit_insn (gen_asinxf2 (op0, op1));
14886 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14890 (define_expand "acosxf2"
14891 [(set (match_dup 2)
14892 (mult:XF (match_operand:XF 1 "register_operand")
14894 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14895 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14896 (parallel [(set (match_operand:XF 0 "register_operand")
14897 (unspec:XF [(match_dup 1) (match_dup 5)]
14899 (clobber (match_scratch:XF 6))])]
14900 "TARGET_USE_FANCY_MATH_387
14901 && flag_unsafe_math_optimizations"
14905 for (i = 2; i < 6; i++)
14906 operands[i] = gen_reg_rtx (XFmode);
14908 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14911 (define_expand "acos<mode>2"
14912 [(use (match_operand:MODEF 0 "register_operand"))
14913 (use (match_operand:MODEF 1 "general_operand"))]
14914 "TARGET_USE_FANCY_MATH_387
14915 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14916 || TARGET_MIX_SSE_I387)
14917 && flag_unsafe_math_optimizations"
14919 rtx op0 = gen_reg_rtx (XFmode);
14920 rtx op1 = gen_reg_rtx (XFmode);
14922 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14923 emit_insn (gen_acosxf2 (op0, op1));
14924 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14928 (define_insn "fyl2xxf3_i387"
14929 [(set (match_operand:XF 0 "register_operand" "=f")
14930 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14931 (match_operand:XF 2 "register_operand" "u")]
14933 (clobber (match_scratch:XF 3 "=2"))]
14934 "TARGET_USE_FANCY_MATH_387
14935 && flag_unsafe_math_optimizations"
14937 [(set_attr "type" "fpspc")
14938 (set_attr "znver1_decode" "vector")
14939 (set_attr "mode" "XF")])
14941 (define_insn "fyl2x_extend<mode>xf3_i387"
14942 [(set (match_operand:XF 0 "register_operand" "=f")
14943 (unspec:XF [(float_extend:XF
14944 (match_operand:MODEF 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 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14950 || TARGET_MIX_SSE_I387)
14951 && flag_unsafe_math_optimizations"
14953 [(set_attr "type" "fpspc")
14954 (set_attr "znver1_decode" "vector")
14955 (set_attr "mode" "XF")])
14957 (define_expand "logxf2"
14958 [(parallel [(set (match_operand:XF 0 "register_operand")
14959 (unspec:XF [(match_operand:XF 1 "register_operand")
14960 (match_dup 2)] UNSPEC_FYL2X))
14961 (clobber (match_scratch:XF 3))])]
14962 "TARGET_USE_FANCY_MATH_387
14963 && flag_unsafe_math_optimizations"
14965 operands[2] = gen_reg_rtx (XFmode);
14966 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14969 (define_expand "log<mode>2"
14970 [(use (match_operand:MODEF 0 "register_operand"))
14971 (use (match_operand:MODEF 1 "register_operand"))]
14972 "TARGET_USE_FANCY_MATH_387
14973 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14974 || TARGET_MIX_SSE_I387)
14975 && flag_unsafe_math_optimizations"
14977 rtx op0 = gen_reg_rtx (XFmode);
14979 rtx op2 = gen_reg_rtx (XFmode);
14980 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14982 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14983 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14987 (define_expand "log10xf2"
14988 [(parallel [(set (match_operand:XF 0 "register_operand")
14989 (unspec:XF [(match_operand:XF 1 "register_operand")
14990 (match_dup 2)] UNSPEC_FYL2X))
14991 (clobber (match_scratch:XF 3))])]
14992 "TARGET_USE_FANCY_MATH_387
14993 && flag_unsafe_math_optimizations"
14995 operands[2] = gen_reg_rtx (XFmode);
14996 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14999 (define_expand "log10<mode>2"
15000 [(use (match_operand:MODEF 0 "register_operand"))
15001 (use (match_operand:MODEF 1 "register_operand"))]
15002 "TARGET_USE_FANCY_MATH_387
15003 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15004 || TARGET_MIX_SSE_I387)
15005 && flag_unsafe_math_optimizations"
15007 rtx op0 = gen_reg_rtx (XFmode);
15009 rtx op2 = gen_reg_rtx (XFmode);
15010 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
15012 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15013 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15017 (define_expand "log2xf2"
15018 [(parallel [(set (match_operand:XF 0 "register_operand")
15019 (unspec:XF [(match_operand:XF 1 "register_operand")
15020 (match_dup 2)] UNSPEC_FYL2X))
15021 (clobber (match_scratch:XF 3))])]
15022 "TARGET_USE_FANCY_MATH_387
15023 && flag_unsafe_math_optimizations"
15025 operands[2] = gen_reg_rtx (XFmode);
15026 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15029 (define_expand "log2<mode>2"
15030 [(use (match_operand:MODEF 0 "register_operand"))
15031 (use (match_operand:MODEF 1 "register_operand"))]
15032 "TARGET_USE_FANCY_MATH_387
15033 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15034 || TARGET_MIX_SSE_I387)
15035 && flag_unsafe_math_optimizations"
15037 rtx op0 = gen_reg_rtx (XFmode);
15039 rtx op2 = gen_reg_rtx (XFmode);
15040 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15042 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15043 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15047 (define_insn "fyl2xp1xf3_i387"
15048 [(set (match_operand:XF 0 "register_operand" "=f")
15049 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15050 (match_operand:XF 2 "register_operand" "u")]
15052 (clobber (match_scratch:XF 3 "=2"))]
15053 "TARGET_USE_FANCY_MATH_387
15054 && flag_unsafe_math_optimizations"
15056 [(set_attr "type" "fpspc")
15057 (set_attr "znver1_decode" "vector")
15058 (set_attr "mode" "XF")])
15060 (define_insn "fyl2xp1_extend<mode>xf3_i387"
15061 [(set (match_operand:XF 0 "register_operand" "=f")
15062 (unspec:XF [(float_extend:XF
15063 (match_operand:MODEF 1 "register_operand" "0"))
15064 (match_operand:XF 2 "register_operand" "u")]
15066 (clobber (match_scratch:XF 3 "=2"))]
15067 "TARGET_USE_FANCY_MATH_387
15068 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15069 || TARGET_MIX_SSE_I387)
15070 && flag_unsafe_math_optimizations"
15072 [(set_attr "type" "fpspc")
15073 (set_attr "znver1_decode" "vector")
15074 (set_attr "mode" "XF")])
15076 (define_expand "log1pxf2"
15077 [(use (match_operand:XF 0 "register_operand"))
15078 (use (match_operand:XF 1 "register_operand"))]
15079 "TARGET_USE_FANCY_MATH_387
15080 && flag_unsafe_math_optimizations"
15082 ix86_emit_i387_log1p (operands[0], operands[1]);
15086 (define_expand "log1p<mode>2"
15087 [(use (match_operand:MODEF 0 "register_operand"))
15088 (use (match_operand:MODEF 1 "register_operand"))]
15089 "TARGET_USE_FANCY_MATH_387
15090 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15091 || TARGET_MIX_SSE_I387)
15092 && flag_unsafe_math_optimizations"
15096 op0 = gen_reg_rtx (XFmode);
15098 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
15100 ix86_emit_i387_log1p (op0, operands[1]);
15101 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15105 (define_insn "fxtractxf3_i387"
15106 [(set (match_operand:XF 0 "register_operand" "=f")
15107 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15108 UNSPEC_XTRACT_FRACT))
15109 (set (match_operand:XF 1 "register_operand" "=u")
15110 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15111 "TARGET_USE_FANCY_MATH_387
15112 && flag_unsafe_math_optimizations"
15114 [(set_attr "type" "fpspc")
15115 (set_attr "znver1_decode" "vector")
15116 (set_attr "mode" "XF")])
15118 (define_insn "fxtract_extend<mode>xf3_i387"
15119 [(set (match_operand:XF 0 "register_operand" "=f")
15120 (unspec:XF [(float_extend:XF
15121 (match_operand:MODEF 2 "register_operand" "0"))]
15122 UNSPEC_XTRACT_FRACT))
15123 (set (match_operand:XF 1 "register_operand" "=u")
15124 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
15125 "TARGET_USE_FANCY_MATH_387
15126 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15127 || TARGET_MIX_SSE_I387)
15128 && flag_unsafe_math_optimizations"
15130 [(set_attr "type" "fpspc")
15131 (set_attr "znver1_decode" "vector")
15132 (set_attr "mode" "XF")])
15134 (define_expand "logbxf2"
15135 [(parallel [(set (match_dup 2)
15136 (unspec:XF [(match_operand:XF 1 "register_operand")]
15137 UNSPEC_XTRACT_FRACT))
15138 (set (match_operand:XF 0 "register_operand")
15139 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15140 "TARGET_USE_FANCY_MATH_387
15141 && flag_unsafe_math_optimizations"
15142 "operands[2] = gen_reg_rtx (XFmode);")
15144 (define_expand "logb<mode>2"
15145 [(use (match_operand:MODEF 0 "register_operand"))
15146 (use (match_operand:MODEF 1 "register_operand"))]
15147 "TARGET_USE_FANCY_MATH_387
15148 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15149 || TARGET_MIX_SSE_I387)
15150 && flag_unsafe_math_optimizations"
15152 rtx op0 = gen_reg_rtx (XFmode);
15153 rtx op1 = gen_reg_rtx (XFmode);
15155 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15156 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
15160 (define_expand "ilogbxf2"
15161 [(use (match_operand:SI 0 "register_operand"))
15162 (use (match_operand:XF 1 "register_operand"))]
15163 "TARGET_USE_FANCY_MATH_387
15164 && flag_unsafe_math_optimizations"
15168 if (optimize_insn_for_size_p ())
15171 op0 = gen_reg_rtx (XFmode);
15172 op1 = gen_reg_rtx (XFmode);
15174 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
15175 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15179 (define_expand "ilogb<mode>2"
15180 [(use (match_operand:SI 0 "register_operand"))
15181 (use (match_operand:MODEF 1 "register_operand"))]
15182 "TARGET_USE_FANCY_MATH_387
15183 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15184 || TARGET_MIX_SSE_I387)
15185 && flag_unsafe_math_optimizations"
15189 if (optimize_insn_for_size_p ())
15192 op0 = gen_reg_rtx (XFmode);
15193 op1 = gen_reg_rtx (XFmode);
15195 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15196 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15200 (define_insn "*f2xm1xf2_i387"
15201 [(set (match_operand:XF 0 "register_operand" "=f")
15202 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15204 "TARGET_USE_FANCY_MATH_387
15205 && flag_unsafe_math_optimizations"
15207 [(set_attr "type" "fpspc")
15208 (set_attr "znver1_decode" "vector")
15209 (set_attr "mode" "XF")])
15211 (define_insn "fscalexf4_i387"
15212 [(set (match_operand:XF 0 "register_operand" "=f")
15213 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15214 (match_operand:XF 3 "register_operand" "1")]
15215 UNSPEC_FSCALE_FRACT))
15216 (set (match_operand:XF 1 "register_operand" "=u")
15217 (unspec:XF [(match_dup 2) (match_dup 3)]
15218 UNSPEC_FSCALE_EXP))]
15219 "TARGET_USE_FANCY_MATH_387
15220 && flag_unsafe_math_optimizations"
15222 [(set_attr "type" "fpspc")
15223 (set_attr "znver1_decode" "vector")
15224 (set_attr "mode" "XF")])
15226 (define_expand "expNcorexf3"
15227 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15228 (match_operand:XF 2 "register_operand")))
15229 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15230 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15231 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15232 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15233 (parallel [(set (match_operand:XF 0 "register_operand")
15234 (unspec:XF [(match_dup 8) (match_dup 4)]
15235 UNSPEC_FSCALE_FRACT))
15237 (unspec:XF [(match_dup 8) (match_dup 4)]
15238 UNSPEC_FSCALE_EXP))])]
15239 "TARGET_USE_FANCY_MATH_387
15240 && flag_unsafe_math_optimizations"
15244 for (i = 3; i < 10; i++)
15245 operands[i] = gen_reg_rtx (XFmode);
15247 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15250 (define_expand "expxf2"
15251 [(use (match_operand:XF 0 "register_operand"))
15252 (use (match_operand:XF 1 "register_operand"))]
15253 "TARGET_USE_FANCY_MATH_387
15254 && flag_unsafe_math_optimizations"
15258 op2 = gen_reg_rtx (XFmode);
15259 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
15261 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15265 (define_expand "exp<mode>2"
15266 [(use (match_operand:MODEF 0 "register_operand"))
15267 (use (match_operand:MODEF 1 "general_operand"))]
15268 "TARGET_USE_FANCY_MATH_387
15269 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15270 || TARGET_MIX_SSE_I387)
15271 && flag_unsafe_math_optimizations"
15275 op0 = gen_reg_rtx (XFmode);
15276 op1 = gen_reg_rtx (XFmode);
15278 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15279 emit_insn (gen_expxf2 (op0, op1));
15280 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15284 (define_expand "exp10xf2"
15285 [(use (match_operand:XF 0 "register_operand"))
15286 (use (match_operand:XF 1 "register_operand"))]
15287 "TARGET_USE_FANCY_MATH_387
15288 && flag_unsafe_math_optimizations"
15292 op2 = gen_reg_rtx (XFmode);
15293 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
15295 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15299 (define_expand "exp10<mode>2"
15300 [(use (match_operand:MODEF 0 "register_operand"))
15301 (use (match_operand:MODEF 1 "general_operand"))]
15302 "TARGET_USE_FANCY_MATH_387
15303 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15304 || TARGET_MIX_SSE_I387)
15305 && flag_unsafe_math_optimizations"
15309 op0 = gen_reg_rtx (XFmode);
15310 op1 = gen_reg_rtx (XFmode);
15312 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15313 emit_insn (gen_exp10xf2 (op0, op1));
15314 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15318 (define_expand "exp2xf2"
15319 [(use (match_operand:XF 0 "register_operand"))
15320 (use (match_operand:XF 1 "register_operand"))]
15321 "TARGET_USE_FANCY_MATH_387
15322 && flag_unsafe_math_optimizations"
15326 op2 = gen_reg_rtx (XFmode);
15327 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15329 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15333 (define_expand "exp2<mode>2"
15334 [(use (match_operand:MODEF 0 "register_operand"))
15335 (use (match_operand:MODEF 1 "general_operand"))]
15336 "TARGET_USE_FANCY_MATH_387
15337 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15338 || TARGET_MIX_SSE_I387)
15339 && flag_unsafe_math_optimizations"
15343 op0 = gen_reg_rtx (XFmode);
15344 op1 = gen_reg_rtx (XFmode);
15346 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15347 emit_insn (gen_exp2xf2 (op0, op1));
15348 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15352 (define_expand "expm1xf2"
15353 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15355 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15356 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15357 (set (match_dup 9) (float_extend:XF (match_dup 13)))
15358 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15359 (parallel [(set (match_dup 7)
15360 (unspec:XF [(match_dup 6) (match_dup 4)]
15361 UNSPEC_FSCALE_FRACT))
15363 (unspec:XF [(match_dup 6) (match_dup 4)]
15364 UNSPEC_FSCALE_EXP))])
15365 (parallel [(set (match_dup 10)
15366 (unspec:XF [(match_dup 9) (match_dup 8)]
15367 UNSPEC_FSCALE_FRACT))
15368 (set (match_dup 11)
15369 (unspec:XF [(match_dup 9) (match_dup 8)]
15370 UNSPEC_FSCALE_EXP))])
15371 (set (match_dup 12) (minus:XF (match_dup 10)
15372 (float_extend:XF (match_dup 13))))
15373 (set (match_operand:XF 0 "register_operand")
15374 (plus:XF (match_dup 12) (match_dup 7)))]
15375 "TARGET_USE_FANCY_MATH_387
15376 && flag_unsafe_math_optimizations"
15380 for (i = 2; i < 13; i++)
15381 operands[i] = gen_reg_rtx (XFmode);
15384 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
15386 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
15389 (define_expand "expm1<mode>2"
15390 [(use (match_operand:MODEF 0 "register_operand"))
15391 (use (match_operand:MODEF 1 "general_operand"))]
15392 "TARGET_USE_FANCY_MATH_387
15393 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15394 || TARGET_MIX_SSE_I387)
15395 && flag_unsafe_math_optimizations"
15399 op0 = gen_reg_rtx (XFmode);
15400 op1 = gen_reg_rtx (XFmode);
15402 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15403 emit_insn (gen_expm1xf2 (op0, op1));
15404 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15408 (define_expand "ldexpxf3"
15409 [(match_operand:XF 0 "register_operand")
15410 (match_operand:XF 1 "register_operand")
15411 (match_operand:SI 2 "register_operand")]
15412 "TARGET_USE_FANCY_MATH_387
15413 && flag_unsafe_math_optimizations"
15417 tmp1 = gen_reg_rtx (XFmode);
15418 tmp2 = gen_reg_rtx (XFmode);
15420 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
15421 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
15422 operands[1], tmp1));
15426 (define_expand "ldexp<mode>3"
15427 [(use (match_operand:MODEF 0 "register_operand"))
15428 (use (match_operand:MODEF 1 "general_operand"))
15429 (use (match_operand:SI 2 "register_operand"))]
15430 "TARGET_USE_FANCY_MATH_387
15431 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15432 || TARGET_MIX_SSE_I387)
15433 && flag_unsafe_math_optimizations"
15437 op0 = gen_reg_rtx (XFmode);
15438 op1 = gen_reg_rtx (XFmode);
15440 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15441 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15442 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15446 (define_expand "scalbxf3"
15447 [(parallel [(set (match_operand:XF 0 " register_operand")
15448 (unspec:XF [(match_operand:XF 1 "register_operand")
15449 (match_operand:XF 2 "register_operand")]
15450 UNSPEC_FSCALE_FRACT))
15452 (unspec:XF [(match_dup 1) (match_dup 2)]
15453 UNSPEC_FSCALE_EXP))])]
15454 "TARGET_USE_FANCY_MATH_387
15455 && flag_unsafe_math_optimizations"
15457 operands[3] = gen_reg_rtx (XFmode);
15460 (define_expand "scalb<mode>3"
15461 [(use (match_operand:MODEF 0 "register_operand"))
15462 (use (match_operand:MODEF 1 "general_operand"))
15463 (use (match_operand:MODEF 2 "general_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"
15471 op0 = gen_reg_rtx (XFmode);
15472 op1 = gen_reg_rtx (XFmode);
15473 op2 = gen_reg_rtx (XFmode);
15475 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15476 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15477 emit_insn (gen_scalbxf3 (op0, op1, op2));
15478 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15482 (define_expand "significandxf2"
15483 [(parallel [(set (match_operand:XF 0 "register_operand")
15484 (unspec:XF [(match_operand:XF 1 "register_operand")]
15485 UNSPEC_XTRACT_FRACT))
15487 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15488 "TARGET_USE_FANCY_MATH_387
15489 && flag_unsafe_math_optimizations"
15490 "operands[2] = gen_reg_rtx (XFmode);")
15492 (define_expand "significand<mode>2"
15493 [(use (match_operand:MODEF 0 "register_operand"))
15494 (use (match_operand:MODEF 1 "register_operand"))]
15495 "TARGET_USE_FANCY_MATH_387
15496 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15497 || TARGET_MIX_SSE_I387)
15498 && flag_unsafe_math_optimizations"
15500 rtx op0 = gen_reg_rtx (XFmode);
15501 rtx op1 = gen_reg_rtx (XFmode);
15503 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15504 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15509 (define_insn "sse4_1_round<mode>2"
15510 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
15511 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x,v")
15512 (match_operand:SI 2 "const_0_to_15_operand" "n,n")]
15516 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
15517 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15518 [(set_attr "type" "ssecvt")
15519 (set_attr "prefix_extra" "1,*")
15520 (set_attr "length_immediate" "*,1")
15521 (set_attr "prefix" "maybe_vex,evex")
15522 (set_attr "isa" "noavx512f,avx512f")
15523 (set_attr "mode" "<MODE>")])
15525 (define_insn "rintxf2"
15526 [(set (match_operand:XF 0 "register_operand" "=f")
15527 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15529 "TARGET_USE_FANCY_MATH_387"
15531 [(set_attr "type" "fpspc")
15532 (set_attr "znver1_decode" "vector")
15533 (set_attr "mode" "XF")])
15535 (define_insn "rint<mode>2_frndint"
15536 [(set (match_operand:MODEF 0 "register_operand" "=f")
15537 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "0")]
15539 "TARGET_USE_FANCY_MATH_387"
15541 [(set_attr "type" "fpspc")
15542 (set_attr "znver1_decode" "vector")
15543 (set_attr "mode" "<MODE>")])
15545 (define_expand "rint<mode>2"
15546 [(use (match_operand:MODEF 0 "register_operand"))
15547 (use (match_operand:MODEF 1 "register_operand"))]
15548 "(TARGET_USE_FANCY_MATH_387
15549 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15550 || TARGET_MIX_SSE_I387))
15551 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15553 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15556 emit_insn (gen_sse4_1_round<mode>2
15557 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
15559 ix86_expand_rint (operands[0], operands[1]);
15562 emit_insn (gen_rint<mode>2_frndint (operands[0], operands[1]));
15566 (define_expand "round<mode>2"
15567 [(match_operand:X87MODEF 0 "register_operand")
15568 (match_operand:X87MODEF 1 "nonimmediate_operand")]
15569 "(TARGET_USE_FANCY_MATH_387
15570 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15571 || TARGET_MIX_SSE_I387)
15572 && flag_unsafe_math_optimizations)
15573 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15574 && !flag_trapping_math && !flag_rounding_math)"
15576 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15577 && !flag_trapping_math && !flag_rounding_math)
15581 operands[1] = force_reg (<MODE>mode, operands[1]);
15582 ix86_expand_round_sse4 (operands[0], operands[1]);
15584 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15585 ix86_expand_round (operands[0], operands[1]);
15587 ix86_expand_rounddf_32 (operands[0], operands[1]);
15591 operands[1] = force_reg (<MODE>mode, operands[1]);
15592 ix86_emit_i387_round (operands[0], operands[1]);
15597 (define_insn_and_split "*fistdi2_1"
15598 [(set (match_operand:DI 0 "nonimmediate_operand")
15599 (unspec:DI [(match_operand:XF 1 "register_operand")]
15601 "TARGET_USE_FANCY_MATH_387
15602 && can_create_pseudo_p ()"
15607 if (memory_operand (operands[0], VOIDmode))
15608 emit_insn (gen_fistdi2 (operands[0], operands[1]));
15611 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15612 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15617 [(set_attr "type" "fpspc")
15618 (set_attr "mode" "DI")])
15620 (define_insn "fistdi2"
15621 [(set (match_operand:DI 0 "memory_operand" "=m")
15622 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15624 (clobber (match_scratch:XF 2 "=&1f"))]
15625 "TARGET_USE_FANCY_MATH_387"
15626 "* return output_fix_trunc (insn, operands, false);"
15627 [(set_attr "type" "fpspc")
15628 (set_attr "mode" "DI")])
15630 (define_insn "fistdi2_with_temp"
15631 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15632 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15634 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15635 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15636 "TARGET_USE_FANCY_MATH_387"
15638 [(set_attr "type" "fpspc")
15639 (set_attr "mode" "DI")])
15642 [(set (match_operand:DI 0 "register_operand")
15643 (unspec:DI [(match_operand:XF 1 "register_operand")]
15645 (clobber (match_operand:DI 2 "memory_operand"))
15646 (clobber (match_scratch 3))]
15648 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15649 (clobber (match_dup 3))])
15650 (set (match_dup 0) (match_dup 2))])
15653 [(set (match_operand:DI 0 "memory_operand")
15654 (unspec:DI [(match_operand:XF 1 "register_operand")]
15656 (clobber (match_operand:DI 2 "memory_operand"))
15657 (clobber (match_scratch 3))]
15659 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15660 (clobber (match_dup 3))])])
15662 (define_insn_and_split "*fist<mode>2_1"
15663 [(set (match_operand:SWI24 0 "register_operand")
15664 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15666 "TARGET_USE_FANCY_MATH_387
15667 && can_create_pseudo_p ()"
15672 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15673 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15677 [(set_attr "type" "fpspc")
15678 (set_attr "mode" "<MODE>")])
15680 (define_insn "fist<mode>2"
15681 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15682 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15684 "TARGET_USE_FANCY_MATH_387"
15685 "* return output_fix_trunc (insn, operands, false);"
15686 [(set_attr "type" "fpspc")
15687 (set_attr "mode" "<MODE>")])
15689 (define_insn "fist<mode>2_with_temp"
15690 [(set (match_operand:SWI24 0 "register_operand" "=r")
15691 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15693 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15694 "TARGET_USE_FANCY_MATH_387"
15696 [(set_attr "type" "fpspc")
15697 (set_attr "mode" "<MODE>")])
15700 [(set (match_operand:SWI24 0 "register_operand")
15701 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15703 (clobber (match_operand:SWI24 2 "memory_operand"))]
15705 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15706 (set (match_dup 0) (match_dup 2))])
15709 [(set (match_operand:SWI24 0 "memory_operand")
15710 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15712 (clobber (match_operand:SWI24 2 "memory_operand"))]
15714 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15716 (define_expand "lrintxf<mode>2"
15717 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15718 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15720 "TARGET_USE_FANCY_MATH_387")
15722 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15723 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15724 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15725 UNSPEC_FIX_NOTRUNC))]
15726 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15728 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15729 [(match_operand:SWI248x 0 "nonimmediate_operand")
15730 (match_operand:X87MODEF 1 "register_operand")]
15731 "(TARGET_USE_FANCY_MATH_387
15732 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15733 || TARGET_MIX_SSE_I387)
15734 && flag_unsafe_math_optimizations)
15735 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15736 && <SWI248x:MODE>mode != HImode
15737 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15738 && !flag_trapping_math && !flag_rounding_math)"
15740 if (optimize_insn_for_size_p ())
15743 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15744 && <SWI248x:MODE>mode != HImode
15745 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15746 && !flag_trapping_math && !flag_rounding_math)
15747 ix86_expand_lround (operands[0], operands[1]);
15749 ix86_emit_i387_round (operands[0], operands[1]);
15753 (define_int_iterator FRNDINT_ROUNDING
15754 [UNSPEC_FRNDINT_FLOOR
15755 UNSPEC_FRNDINT_CEIL
15756 UNSPEC_FRNDINT_TRUNC])
15758 (define_int_iterator FIST_ROUNDING
15762 ;; Base name for define_insn
15763 (define_int_attr rounding_insn
15764 [(UNSPEC_FRNDINT_FLOOR "floor")
15765 (UNSPEC_FRNDINT_CEIL "ceil")
15766 (UNSPEC_FRNDINT_TRUNC "btrunc")
15767 (UNSPEC_FIST_FLOOR "floor")
15768 (UNSPEC_FIST_CEIL "ceil")])
15770 (define_int_attr rounding
15771 [(UNSPEC_FRNDINT_FLOOR "floor")
15772 (UNSPEC_FRNDINT_CEIL "ceil")
15773 (UNSPEC_FRNDINT_TRUNC "trunc")
15774 (UNSPEC_FIST_FLOOR "floor")
15775 (UNSPEC_FIST_CEIL "ceil")])
15777 (define_int_attr ROUNDING
15778 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15779 (UNSPEC_FRNDINT_CEIL "CEIL")
15780 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15781 (UNSPEC_FIST_FLOOR "FLOOR")
15782 (UNSPEC_FIST_CEIL "CEIL")])
15784 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15785 (define_insn_and_split "frndint<mode>2_<rounding>"
15786 [(set (match_operand:X87MODEF 0 "register_operand")
15787 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand")]
15789 (clobber (reg:CC FLAGS_REG))]
15790 "TARGET_USE_FANCY_MATH_387
15791 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
15792 && can_create_pseudo_p ()"
15797 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15799 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15800 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15802 emit_insn (gen_frndint<mode>2_<rounding>_i387 (operands[0], operands[1],
15803 operands[2], operands[3]));
15806 [(set_attr "type" "frndint")
15807 (set_attr "i387_cw" "<rounding>")
15808 (set_attr "mode" "<MODE>")])
15810 (define_insn "frndint<mode>2_<rounding>_i387"
15811 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
15812 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand" "0")]
15814 (use (match_operand:HI 2 "memory_operand" "m"))
15815 (use (match_operand:HI 3 "memory_operand" "m"))]
15816 "TARGET_USE_FANCY_MATH_387
15817 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
15818 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15819 [(set_attr "type" "frndint")
15820 (set_attr "i387_cw" "<rounding>")
15821 (set_attr "mode" "<MODE>")])
15823 (define_expand "<rounding_insn>xf2"
15824 [(parallel [(set (match_operand:XF 0 "register_operand")
15825 (unspec:XF [(match_operand:XF 1 "register_operand")]
15827 (clobber (reg:CC FLAGS_REG))])]
15828 "TARGET_USE_FANCY_MATH_387
15829 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
15831 (define_expand "<rounding_insn><mode>2"
15832 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15833 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15835 (clobber (reg:CC FLAGS_REG))])]
15836 "(TARGET_USE_FANCY_MATH_387
15837 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15838 || TARGET_MIX_SSE_I387)
15839 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
15840 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15841 && (TARGET_ROUND || !flag_trapping_math || flag_fp_int_builtin_inexact))"
15843 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15844 && (TARGET_ROUND || !flag_trapping_math || flag_fp_int_builtin_inexact))
15847 emit_insn (gen_sse4_1_round<mode>2
15848 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>
15850 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15852 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15853 ix86_expand_floorceil (operands[0], operands[1], true);
15854 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15855 ix86_expand_floorceil (operands[0], operands[1], false);
15856 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15857 ix86_expand_trunc (operands[0], operands[1]);
15859 gcc_unreachable ();
15863 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15864 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15865 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15866 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15867 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15868 ix86_expand_truncdf_32 (operands[0], operands[1]);
15870 gcc_unreachable ();
15874 emit_insn (gen_frndint<mode>2_<rounding> (operands[0], operands[1]));
15878 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15879 (define_insn_and_split "frndintxf2_mask_pm"
15880 [(set (match_operand:XF 0 "register_operand")
15881 (unspec:XF [(match_operand:XF 1 "register_operand")]
15882 UNSPEC_FRNDINT_MASK_PM))
15883 (clobber (reg:CC FLAGS_REG))]
15884 "TARGET_USE_FANCY_MATH_387
15885 && flag_unsafe_math_optimizations
15886 && can_create_pseudo_p ()"
15891 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15893 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15894 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15896 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15897 operands[2], operands[3]));
15900 [(set_attr "type" "frndint")
15901 (set_attr "i387_cw" "mask_pm")
15902 (set_attr "mode" "XF")])
15904 (define_insn "frndintxf2_mask_pm_i387"
15905 [(set (match_operand:XF 0 "register_operand" "=f")
15906 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15907 UNSPEC_FRNDINT_MASK_PM))
15908 (use (match_operand:HI 2 "memory_operand" "m"))
15909 (use (match_operand:HI 3 "memory_operand" "m"))]
15910 "TARGET_USE_FANCY_MATH_387
15911 && flag_unsafe_math_optimizations"
15912 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15913 [(set_attr "type" "frndint")
15914 (set_attr "i387_cw" "mask_pm")
15915 (set_attr "mode" "XF")])
15917 (define_expand "nearbyintxf2"
15918 [(parallel [(set (match_operand:XF 0 "register_operand")
15919 (unspec:XF [(match_operand:XF 1 "register_operand")]
15920 UNSPEC_FRNDINT_MASK_PM))
15921 (clobber (reg:CC FLAGS_REG))])]
15922 "TARGET_USE_FANCY_MATH_387
15923 && flag_unsafe_math_optimizations")
15925 (define_expand "nearbyint<mode>2"
15926 [(use (match_operand:MODEF 0 "register_operand"))
15927 (use (match_operand:MODEF 1 "register_operand"))]
15928 "TARGET_USE_FANCY_MATH_387
15929 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15930 || TARGET_MIX_SSE_I387)
15931 && flag_unsafe_math_optimizations"
15933 rtx op0 = gen_reg_rtx (XFmode);
15934 rtx op1 = gen_reg_rtx (XFmode);
15936 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15937 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15939 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15943 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15944 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15945 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15946 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15948 (clobber (reg:CC FLAGS_REG))]
15949 "TARGET_USE_FANCY_MATH_387
15950 && flag_unsafe_math_optimizations
15951 && can_create_pseudo_p ()"
15956 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15958 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15959 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15960 if (memory_operand (operands[0], VOIDmode))
15961 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15962 operands[2], operands[3]));
15965 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15966 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15967 (operands[0], operands[1], operands[2],
15968 operands[3], operands[4]));
15972 [(set_attr "type" "fistp")
15973 (set_attr "i387_cw" "<rounding>")
15974 (set_attr "mode" "<MODE>")])
15976 (define_insn "fistdi2_<rounding>"
15977 [(set (match_operand:DI 0 "memory_operand" "=m")
15978 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15980 (use (match_operand:HI 2 "memory_operand" "m"))
15981 (use (match_operand:HI 3 "memory_operand" "m"))
15982 (clobber (match_scratch:XF 4 "=&1f"))]
15983 "TARGET_USE_FANCY_MATH_387
15984 && flag_unsafe_math_optimizations"
15985 "* return output_fix_trunc (insn, operands, false);"
15986 [(set_attr "type" "fistp")
15987 (set_attr "i387_cw" "<rounding>")
15988 (set_attr "mode" "DI")])
15990 (define_insn "fistdi2_<rounding>_with_temp"
15991 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15992 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15994 (use (match_operand:HI 2 "memory_operand" "m,m"))
15995 (use (match_operand:HI 3 "memory_operand" "m,m"))
15996 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15997 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15998 "TARGET_USE_FANCY_MATH_387
15999 && flag_unsafe_math_optimizations"
16001 [(set_attr "type" "fistp")
16002 (set_attr "i387_cw" "<rounding>")
16003 (set_attr "mode" "DI")])
16006 [(set (match_operand:DI 0 "register_operand")
16007 (unspec:DI [(match_operand:XF 1 "register_operand")]
16009 (use (match_operand:HI 2 "memory_operand"))
16010 (use (match_operand:HI 3 "memory_operand"))
16011 (clobber (match_operand:DI 4 "memory_operand"))
16012 (clobber (match_scratch 5))]
16014 [(parallel [(set (match_dup 4)
16015 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16016 (use (match_dup 2))
16017 (use (match_dup 3))
16018 (clobber (match_dup 5))])
16019 (set (match_dup 0) (match_dup 4))])
16022 [(set (match_operand:DI 0 "memory_operand")
16023 (unspec:DI [(match_operand:XF 1 "register_operand")]
16025 (use (match_operand:HI 2 "memory_operand"))
16026 (use (match_operand:HI 3 "memory_operand"))
16027 (clobber (match_operand:DI 4 "memory_operand"))
16028 (clobber (match_scratch 5))]
16030 [(parallel [(set (match_dup 0)
16031 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16032 (use (match_dup 2))
16033 (use (match_dup 3))
16034 (clobber (match_dup 5))])])
16036 (define_insn "fist<mode>2_<rounding>"
16037 [(set (match_operand:SWI24 0 "memory_operand" "=m")
16038 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16040 (use (match_operand:HI 2 "memory_operand" "m"))
16041 (use (match_operand:HI 3 "memory_operand" "m"))]
16042 "TARGET_USE_FANCY_MATH_387
16043 && flag_unsafe_math_optimizations"
16044 "* return output_fix_trunc (insn, operands, false);"
16045 [(set_attr "type" "fistp")
16046 (set_attr "i387_cw" "<rounding>")
16047 (set_attr "mode" "<MODE>")])
16049 (define_insn "fist<mode>2_<rounding>_with_temp"
16050 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
16051 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
16053 (use (match_operand:HI 2 "memory_operand" "m,m"))
16054 (use (match_operand:HI 3 "memory_operand" "m,m"))
16055 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
16056 "TARGET_USE_FANCY_MATH_387
16057 && flag_unsafe_math_optimizations"
16059 [(set_attr "type" "fistp")
16060 (set_attr "i387_cw" "<rounding>")
16061 (set_attr "mode" "<MODE>")])
16064 [(set (match_operand:SWI24 0 "register_operand")
16065 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16067 (use (match_operand:HI 2 "memory_operand"))
16068 (use (match_operand:HI 3 "memory_operand"))
16069 (clobber (match_operand:SWI24 4 "memory_operand"))]
16071 [(parallel [(set (match_dup 4)
16072 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16073 (use (match_dup 2))
16074 (use (match_dup 3))])
16075 (set (match_dup 0) (match_dup 4))])
16078 [(set (match_operand:SWI24 0 "memory_operand")
16079 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16081 (use (match_operand:HI 2 "memory_operand"))
16082 (use (match_operand:HI 3 "memory_operand"))
16083 (clobber (match_operand:SWI24 4 "memory_operand"))]
16085 [(parallel [(set (match_dup 0)
16086 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16087 (use (match_dup 2))
16088 (use (match_dup 3))])])
16090 (define_expand "l<rounding_insn>xf<mode>2"
16091 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16092 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16094 (clobber (reg:CC FLAGS_REG))])]
16095 "TARGET_USE_FANCY_MATH_387
16096 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16097 && flag_unsafe_math_optimizations")
16099 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
16100 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
16101 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16103 (clobber (reg:CC FLAGS_REG))])]
16104 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16105 && !flag_trapping_math"
16107 if (TARGET_64BIT && optimize_insn_for_size_p ())
16110 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16111 ix86_expand_lfloorceil (operands[0], operands[1], true);
16112 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16113 ix86_expand_lfloorceil (operands[0], operands[1], false);
16115 gcc_unreachable ();
16120 (define_insn "fxam<mode>2_i387"
16121 [(set (match_operand:HI 0 "register_operand" "=a")
16123 [(match_operand:X87MODEF 1 "register_operand" "f")]
16125 "TARGET_USE_FANCY_MATH_387"
16126 "fxam\n\tfnstsw\t%0"
16127 [(set_attr "type" "multi")
16128 (set_attr "length" "4")
16129 (set_attr "unit" "i387")
16130 (set_attr "mode" "<MODE>")])
16132 (define_insn_and_split "fxam<mode>2_i387_with_temp"
16133 [(set (match_operand:HI 0 "register_operand")
16135 [(match_operand:MODEF 1 "memory_operand")]
16137 "TARGET_USE_FANCY_MATH_387
16138 && can_create_pseudo_p ()"
16141 [(set (match_dup 2)(match_dup 1))
16143 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
16145 operands[2] = gen_reg_rtx (<MODE>mode);
16147 MEM_VOLATILE_P (operands[1]) = 1;
16149 [(set_attr "type" "multi")
16150 (set_attr "unit" "i387")
16151 (set_attr "mode" "<MODE>")])
16153 (define_expand "isinfxf2"
16154 [(use (match_operand:SI 0 "register_operand"))
16155 (use (match_operand:XF 1 "register_operand"))]
16156 "TARGET_USE_FANCY_MATH_387
16157 && ix86_libc_has_function (function_c99_misc)"
16159 rtx mask = GEN_INT (0x45);
16160 rtx val = GEN_INT (0x05);
16164 rtx scratch = gen_reg_rtx (HImode);
16165 rtx res = gen_reg_rtx (QImode);
16167 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16169 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
16170 emit_insn (gen_cmpqi_ext_3 (scratch, val));
16171 cond = gen_rtx_fmt_ee (EQ, QImode,
16172 gen_rtx_REG (CCmode, FLAGS_REG),
16174 emit_insn (gen_rtx_SET (res, cond));
16175 emit_insn (gen_zero_extendqisi2 (operands[0], res));
16179 (define_expand "isinf<mode>2"
16180 [(use (match_operand:SI 0 "register_operand"))
16181 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
16182 "TARGET_USE_FANCY_MATH_387
16183 && ix86_libc_has_function (function_c99_misc)
16184 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16186 rtx mask = GEN_INT (0x45);
16187 rtx val = GEN_INT (0x05);
16191 rtx scratch = gen_reg_rtx (HImode);
16192 rtx res = gen_reg_rtx (QImode);
16194 /* Remove excess precision by forcing value through memory. */
16195 if (memory_operand (operands[1], VOIDmode))
16196 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
16199 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16201 emit_move_insn (temp, operands[1]);
16202 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
16205 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
16206 emit_insn (gen_cmpqi_ext_3 (scratch, val));
16207 cond = gen_rtx_fmt_ee (EQ, QImode,
16208 gen_rtx_REG (CCmode, FLAGS_REG),
16210 emit_insn (gen_rtx_SET (res, cond));
16211 emit_insn (gen_zero_extendqisi2 (operands[0], res));
16215 (define_expand "signbitxf2"
16216 [(use (match_operand:SI 0 "register_operand"))
16217 (use (match_operand:XF 1 "register_operand"))]
16218 "TARGET_USE_FANCY_MATH_387"
16220 rtx scratch = gen_reg_rtx (HImode);
16222 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16223 emit_insn (gen_andsi3 (operands[0],
16224 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16228 (define_insn "movmsk_df"
16229 [(set (match_operand:SI 0 "register_operand" "=r")
16231 [(match_operand:DF 1 "register_operand" "x")]
16233 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
16234 "%vmovmskpd\t{%1, %0|%0, %1}"
16235 [(set_attr "type" "ssemov")
16236 (set_attr "prefix" "maybe_vex")
16237 (set_attr "mode" "DF")])
16239 ;; Use movmskpd in SSE mode to avoid store forwarding stall
16240 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
16241 (define_expand "signbitdf2"
16242 [(use (match_operand:SI 0 "register_operand"))
16243 (use (match_operand:DF 1 "register_operand"))]
16244 "TARGET_USE_FANCY_MATH_387
16245 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
16247 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
16249 emit_insn (gen_movmsk_df (operands[0], operands[1]));
16250 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
16254 rtx scratch = gen_reg_rtx (HImode);
16256 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
16257 emit_insn (gen_andsi3 (operands[0],
16258 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16263 (define_expand "signbitsf2"
16264 [(use (match_operand:SI 0 "register_operand"))
16265 (use (match_operand:SF 1 "register_operand"))]
16266 "TARGET_USE_FANCY_MATH_387
16267 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
16269 rtx scratch = gen_reg_rtx (HImode);
16271 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
16272 emit_insn (gen_andsi3 (operands[0],
16273 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16277 ;; Block operation instructions
16280 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16283 [(set_attr "length" "1")
16284 (set_attr "length_immediate" "0")
16285 (set_attr "modrm" "0")])
16287 (define_expand "movmem<mode>"
16288 [(use (match_operand:BLK 0 "memory_operand"))
16289 (use (match_operand:BLK 1 "memory_operand"))
16290 (use (match_operand:SWI48 2 "nonmemory_operand"))
16291 (use (match_operand:SWI48 3 "const_int_operand"))
16292 (use (match_operand:SI 4 "const_int_operand"))
16293 (use (match_operand:SI 5 "const_int_operand"))
16294 (use (match_operand:SI 6 ""))
16295 (use (match_operand:SI 7 ""))
16296 (use (match_operand:SI 8 ""))]
16299 if (ix86_expand_set_or_movmem (operands[0], operands[1],
16300 operands[2], NULL, operands[3],
16301 operands[4], operands[5],
16302 operands[6], operands[7],
16303 operands[8], false))
16309 ;; Most CPUs don't like single string operations
16310 ;; Handle this case here to simplify previous expander.
16312 (define_expand "strmov"
16313 [(set (match_dup 4) (match_operand 3 "memory_operand"))
16314 (set (match_operand 1 "memory_operand") (match_dup 4))
16315 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
16316 (clobber (reg:CC FLAGS_REG))])
16317 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
16318 (clobber (reg:CC FLAGS_REG))])]
16321 /* Can't use this for non-default address spaces. */
16322 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
16325 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16327 /* If .md ever supports :P for Pmode, these can be directly
16328 in the pattern above. */
16329 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16330 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16332 /* Can't use this if the user has appropriated esi or edi. */
16333 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16334 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16336 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16337 operands[2], operands[3],
16338 operands[5], operands[6]));
16342 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16345 (define_expand "strmov_singleop"
16346 [(parallel [(set (match_operand 1 "memory_operand")
16347 (match_operand 3 "memory_operand"))
16348 (set (match_operand 0 "register_operand")
16350 (set (match_operand 2 "register_operand")
16351 (match_operand 5))])]
16353 "ix86_current_function_needs_cld = 1;")
16355 (define_insn "*strmovdi_rex_1"
16356 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16357 (mem:DI (match_operand:P 3 "register_operand" "1")))
16358 (set (match_operand:P 0 "register_operand" "=D")
16359 (plus:P (match_dup 2)
16361 (set (match_operand:P 1 "register_operand" "=S")
16362 (plus:P (match_dup 3)
16365 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16366 && ix86_check_no_addr_space (insn)"
16368 [(set_attr "type" "str")
16369 (set_attr "memory" "both")
16370 (set_attr "mode" "DI")])
16372 (define_insn "*strmovsi_1"
16373 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16374 (mem:SI (match_operand:P 3 "register_operand" "1")))
16375 (set (match_operand:P 0 "register_operand" "=D")
16376 (plus:P (match_dup 2)
16378 (set (match_operand:P 1 "register_operand" "=S")
16379 (plus:P (match_dup 3)
16381 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16382 && ix86_check_no_addr_space (insn)"
16384 [(set_attr "type" "str")
16385 (set_attr "memory" "both")
16386 (set_attr "mode" "SI")])
16388 (define_insn "*strmovhi_1"
16389 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16390 (mem:HI (match_operand:P 3 "register_operand" "1")))
16391 (set (match_operand:P 0 "register_operand" "=D")
16392 (plus:P (match_dup 2)
16394 (set (match_operand:P 1 "register_operand" "=S")
16395 (plus:P (match_dup 3)
16397 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16398 && ix86_check_no_addr_space (insn)"
16400 [(set_attr "type" "str")
16401 (set_attr "memory" "both")
16402 (set_attr "mode" "HI")])
16404 (define_insn "*strmovqi_1"
16405 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16406 (mem:QI (match_operand:P 3 "register_operand" "1")))
16407 (set (match_operand:P 0 "register_operand" "=D")
16408 (plus:P (match_dup 2)
16410 (set (match_operand:P 1 "register_operand" "=S")
16411 (plus:P (match_dup 3)
16413 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16414 && ix86_check_no_addr_space (insn)"
16416 [(set_attr "type" "str")
16417 (set_attr "memory" "both")
16418 (set (attr "prefix_rex")
16420 (match_test "<P:MODE>mode == DImode")
16422 (const_string "*")))
16423 (set_attr "mode" "QI")])
16425 (define_expand "rep_mov"
16426 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16427 (set (match_operand 0 "register_operand")
16429 (set (match_operand 2 "register_operand")
16431 (set (match_operand 1 "memory_operand")
16432 (match_operand 3 "memory_operand"))
16433 (use (match_dup 4))])]
16435 "ix86_current_function_needs_cld = 1;")
16437 (define_insn "*rep_movdi_rex64"
16438 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16439 (set (match_operand:P 0 "register_operand" "=D")
16440 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16442 (match_operand:P 3 "register_operand" "0")))
16443 (set (match_operand:P 1 "register_operand" "=S")
16444 (plus:P (ashift:P (match_dup 5) (const_int 3))
16445 (match_operand:P 4 "register_operand" "1")))
16446 (set (mem:BLK (match_dup 3))
16447 (mem:BLK (match_dup 4)))
16448 (use (match_dup 5))]
16450 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16451 && ix86_check_no_addr_space (insn)"
16453 [(set_attr "type" "str")
16454 (set_attr "prefix_rep" "1")
16455 (set_attr "memory" "both")
16456 (set_attr "mode" "DI")])
16458 (define_insn "*rep_movsi"
16459 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16460 (set (match_operand:P 0 "register_operand" "=D")
16461 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16463 (match_operand:P 3 "register_operand" "0")))
16464 (set (match_operand:P 1 "register_operand" "=S")
16465 (plus:P (ashift:P (match_dup 5) (const_int 2))
16466 (match_operand:P 4 "register_operand" "1")))
16467 (set (mem:BLK (match_dup 3))
16468 (mem:BLK (match_dup 4)))
16469 (use (match_dup 5))]
16470 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16471 && ix86_check_no_addr_space (insn)"
16472 "%^rep{%;} movs{l|d}"
16473 [(set_attr "type" "str")
16474 (set_attr "prefix_rep" "1")
16475 (set_attr "memory" "both")
16476 (set_attr "mode" "SI")])
16478 (define_insn "*rep_movqi"
16479 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16480 (set (match_operand:P 0 "register_operand" "=D")
16481 (plus:P (match_operand:P 3 "register_operand" "0")
16482 (match_operand:P 5 "register_operand" "2")))
16483 (set (match_operand:P 1 "register_operand" "=S")
16484 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16485 (set (mem:BLK (match_dup 3))
16486 (mem:BLK (match_dup 4)))
16487 (use (match_dup 5))]
16488 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16489 && ix86_check_no_addr_space (insn)"
16491 [(set_attr "type" "str")
16492 (set_attr "prefix_rep" "1")
16493 (set_attr "memory" "both")
16494 (set_attr "mode" "QI")])
16496 (define_expand "setmem<mode>"
16497 [(use (match_operand:BLK 0 "memory_operand"))
16498 (use (match_operand:SWI48 1 "nonmemory_operand"))
16499 (use (match_operand:QI 2 "nonmemory_operand"))
16500 (use (match_operand 3 "const_int_operand"))
16501 (use (match_operand:SI 4 "const_int_operand"))
16502 (use (match_operand:SI 5 "const_int_operand"))
16503 (use (match_operand:SI 6 ""))
16504 (use (match_operand:SI 7 ""))
16505 (use (match_operand:SI 8 ""))]
16508 if (ix86_expand_set_or_movmem (operands[0], NULL,
16509 operands[1], operands[2],
16510 operands[3], operands[4],
16511 operands[5], operands[6],
16512 operands[7], operands[8], true))
16518 ;; Most CPUs don't like single string operations
16519 ;; Handle this case here to simplify previous expander.
16521 (define_expand "strset"
16522 [(set (match_operand 1 "memory_operand")
16523 (match_operand 2 "register_operand"))
16524 (parallel [(set (match_operand 0 "register_operand")
16526 (clobber (reg:CC FLAGS_REG))])]
16529 /* Can't use this for non-default address spaces. */
16530 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
16533 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16534 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16536 /* If .md ever supports :P for Pmode, this can be directly
16537 in the pattern above. */
16538 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16539 GEN_INT (GET_MODE_SIZE (GET_MODE
16541 /* Can't use this if the user has appropriated eax or edi. */
16542 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16543 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16545 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16551 (define_expand "strset_singleop"
16552 [(parallel [(set (match_operand 1 "memory_operand")
16553 (match_operand 2 "register_operand"))
16554 (set (match_operand 0 "register_operand")
16556 (unspec [(const_int 0)] UNSPEC_STOS)])]
16558 "ix86_current_function_needs_cld = 1;")
16560 (define_insn "*strsetdi_rex_1"
16561 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16562 (match_operand:DI 2 "register_operand" "a"))
16563 (set (match_operand:P 0 "register_operand" "=D")
16564 (plus:P (match_dup 1)
16566 (unspec [(const_int 0)] UNSPEC_STOS)]
16568 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16569 && ix86_check_no_addr_space (insn)"
16571 [(set_attr "type" "str")
16572 (set_attr "memory" "store")
16573 (set_attr "mode" "DI")])
16575 (define_insn "*strsetsi_1"
16576 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16577 (match_operand:SI 2 "register_operand" "a"))
16578 (set (match_operand:P 0 "register_operand" "=D")
16579 (plus:P (match_dup 1)
16581 (unspec [(const_int 0)] UNSPEC_STOS)]
16582 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16583 && ix86_check_no_addr_space (insn)"
16585 [(set_attr "type" "str")
16586 (set_attr "memory" "store")
16587 (set_attr "mode" "SI")])
16589 (define_insn "*strsethi_1"
16590 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16591 (match_operand:HI 2 "register_operand" "a"))
16592 (set (match_operand:P 0 "register_operand" "=D")
16593 (plus:P (match_dup 1)
16595 (unspec [(const_int 0)] UNSPEC_STOS)]
16596 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16597 && ix86_check_no_addr_space (insn)"
16599 [(set_attr "type" "str")
16600 (set_attr "memory" "store")
16601 (set_attr "mode" "HI")])
16603 (define_insn "*strsetqi_1"
16604 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16605 (match_operand:QI 2 "register_operand" "a"))
16606 (set (match_operand:P 0 "register_operand" "=D")
16607 (plus:P (match_dup 1)
16609 (unspec [(const_int 0)] UNSPEC_STOS)]
16610 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16611 && ix86_check_no_addr_space (insn)"
16613 [(set_attr "type" "str")
16614 (set_attr "memory" "store")
16615 (set (attr "prefix_rex")
16617 (match_test "<P:MODE>mode == DImode")
16619 (const_string "*")))
16620 (set_attr "mode" "QI")])
16622 (define_expand "rep_stos"
16623 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16624 (set (match_operand 0 "register_operand")
16626 (set (match_operand 2 "memory_operand") (const_int 0))
16627 (use (match_operand 3 "register_operand"))
16628 (use (match_dup 1))])]
16630 "ix86_current_function_needs_cld = 1;")
16632 (define_insn "*rep_stosdi_rex64"
16633 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16634 (set (match_operand:P 0 "register_operand" "=D")
16635 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16637 (match_operand:P 3 "register_operand" "0")))
16638 (set (mem:BLK (match_dup 3))
16640 (use (match_operand:DI 2 "register_operand" "a"))
16641 (use (match_dup 4))]
16643 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16644 && ix86_check_no_addr_space (insn)"
16646 [(set_attr "type" "str")
16647 (set_attr "prefix_rep" "1")
16648 (set_attr "memory" "store")
16649 (set_attr "mode" "DI")])
16651 (define_insn "*rep_stossi"
16652 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16653 (set (match_operand:P 0 "register_operand" "=D")
16654 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16656 (match_operand:P 3 "register_operand" "0")))
16657 (set (mem:BLK (match_dup 3))
16659 (use (match_operand:SI 2 "register_operand" "a"))
16660 (use (match_dup 4))]
16661 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16662 && ix86_check_no_addr_space (insn)"
16663 "%^rep{%;} stos{l|d}"
16664 [(set_attr "type" "str")
16665 (set_attr "prefix_rep" "1")
16666 (set_attr "memory" "store")
16667 (set_attr "mode" "SI")])
16669 (define_insn "*rep_stosqi"
16670 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16671 (set (match_operand:P 0 "register_operand" "=D")
16672 (plus:P (match_operand:P 3 "register_operand" "0")
16673 (match_operand:P 4 "register_operand" "1")))
16674 (set (mem:BLK (match_dup 3))
16676 (use (match_operand:QI 2 "register_operand" "a"))
16677 (use (match_dup 4))]
16678 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16679 && ix86_check_no_addr_space (insn)"
16681 [(set_attr "type" "str")
16682 (set_attr "prefix_rep" "1")
16683 (set_attr "memory" "store")
16684 (set (attr "prefix_rex")
16686 (match_test "<P:MODE>mode == DImode")
16688 (const_string "*")))
16689 (set_attr "mode" "QI")])
16691 (define_expand "cmpstrnsi"
16692 [(set (match_operand:SI 0 "register_operand")
16693 (compare:SI (match_operand:BLK 1 "general_operand")
16694 (match_operand:BLK 2 "general_operand")))
16695 (use (match_operand 3 "general_operand"))
16696 (use (match_operand 4 "immediate_operand"))]
16699 rtx addr1, addr2, out, outlow, count, countreg, align;
16701 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16704 /* Can't use this if the user has appropriated ecx, esi or edi. */
16705 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16710 out = gen_reg_rtx (SImode);
16712 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16713 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16714 if (addr1 != XEXP (operands[1], 0))
16715 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16716 if (addr2 != XEXP (operands[2], 0))
16717 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16719 count = operands[3];
16720 countreg = ix86_zero_extend_to_Pmode (count);
16722 /* %%% Iff we are testing strict equality, we can use known alignment
16723 to good advantage. This may be possible with combine, particularly
16724 once cc0 is dead. */
16725 align = operands[4];
16727 if (CONST_INT_P (count))
16729 if (INTVAL (count) == 0)
16731 emit_move_insn (operands[0], const0_rtx);
16734 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16735 operands[1], operands[2]));
16739 rtx (*gen_cmp) (rtx, rtx);
16741 gen_cmp = (TARGET_64BIT
16742 ? gen_cmpdi_1 : gen_cmpsi_1);
16744 emit_insn (gen_cmp (countreg, countreg));
16745 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16746 operands[1], operands[2]));
16749 outlow = gen_lowpart (QImode, out);
16750 emit_insn (gen_cmpintqi (outlow));
16751 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16753 if (operands[0] != out)
16754 emit_move_insn (operands[0], out);
16759 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16761 (define_expand "cmpintqi"
16762 [(set (match_dup 1)
16763 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16765 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16766 (parallel [(set (match_operand:QI 0 "register_operand")
16767 (minus:QI (match_dup 1)
16769 (clobber (reg:CC FLAGS_REG))])]
16772 operands[1] = gen_reg_rtx (QImode);
16773 operands[2] = gen_reg_rtx (QImode);
16776 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16777 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16779 (define_expand "cmpstrnqi_nz_1"
16780 [(parallel [(set (reg:CC FLAGS_REG)
16781 (compare:CC (match_operand 4 "memory_operand")
16782 (match_operand 5 "memory_operand")))
16783 (use (match_operand 2 "register_operand"))
16784 (use (match_operand:SI 3 "immediate_operand"))
16785 (clobber (match_operand 0 "register_operand"))
16786 (clobber (match_operand 1 "register_operand"))
16787 (clobber (match_dup 2))])]
16789 "ix86_current_function_needs_cld = 1;")
16791 (define_insn "*cmpstrnqi_nz_1"
16792 [(set (reg:CC FLAGS_REG)
16793 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16794 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16795 (use (match_operand:P 6 "register_operand" "2"))
16796 (use (match_operand:SI 3 "immediate_operand" "i"))
16797 (clobber (match_operand:P 0 "register_operand" "=S"))
16798 (clobber (match_operand:P 1 "register_operand" "=D"))
16799 (clobber (match_operand:P 2 "register_operand" "=c"))]
16800 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16801 && ix86_check_no_addr_space (insn)"
16803 [(set_attr "type" "str")
16804 (set_attr "mode" "QI")
16805 (set (attr "prefix_rex")
16807 (match_test "<P:MODE>mode == DImode")
16809 (const_string "*")))
16810 (set_attr "prefix_rep" "1")])
16812 ;; The same, but the count is not known to not be zero.
16814 (define_expand "cmpstrnqi_1"
16815 [(parallel [(set (reg:CC FLAGS_REG)
16816 (if_then_else:CC (ne (match_operand 2 "register_operand")
16818 (compare:CC (match_operand 4 "memory_operand")
16819 (match_operand 5 "memory_operand"))
16821 (use (match_operand:SI 3 "immediate_operand"))
16822 (use (reg:CC FLAGS_REG))
16823 (clobber (match_operand 0 "register_operand"))
16824 (clobber (match_operand 1 "register_operand"))
16825 (clobber (match_dup 2))])]
16827 "ix86_current_function_needs_cld = 1;")
16829 (define_insn "*cmpstrnqi_1"
16830 [(set (reg:CC FLAGS_REG)
16831 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16833 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16834 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16836 (use (match_operand:SI 3 "immediate_operand" "i"))
16837 (use (reg:CC FLAGS_REG))
16838 (clobber (match_operand:P 0 "register_operand" "=S"))
16839 (clobber (match_operand:P 1 "register_operand" "=D"))
16840 (clobber (match_operand:P 2 "register_operand" "=c"))]
16841 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16842 && ix86_check_no_addr_space (insn)"
16844 [(set_attr "type" "str")
16845 (set_attr "mode" "QI")
16846 (set (attr "prefix_rex")
16848 (match_test "<P:MODE>mode == DImode")
16850 (const_string "*")))
16851 (set_attr "prefix_rep" "1")])
16853 (define_expand "strlen<mode>"
16854 [(set (match_operand:P 0 "register_operand")
16855 (unspec:P [(match_operand:BLK 1 "general_operand")
16856 (match_operand:QI 2 "immediate_operand")
16857 (match_operand 3 "immediate_operand")]
16861 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16867 (define_expand "strlenqi_1"
16868 [(parallel [(set (match_operand 0 "register_operand")
16870 (clobber (match_operand 1 "register_operand"))
16871 (clobber (reg:CC FLAGS_REG))])]
16873 "ix86_current_function_needs_cld = 1;")
16875 (define_insn "*strlenqi_1"
16876 [(set (match_operand:P 0 "register_operand" "=&c")
16877 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16878 (match_operand:QI 2 "register_operand" "a")
16879 (match_operand:P 3 "immediate_operand" "i")
16880 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16881 (clobber (match_operand:P 1 "register_operand" "=D"))
16882 (clobber (reg:CC FLAGS_REG))]
16883 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16884 && ix86_check_no_addr_space (insn)"
16885 "%^repnz{%;} scasb"
16886 [(set_attr "type" "str")
16887 (set_attr "mode" "QI")
16888 (set (attr "prefix_rex")
16890 (match_test "<P:MODE>mode == DImode")
16892 (const_string "*")))
16893 (set_attr "prefix_rep" "1")])
16895 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16896 ;; handled in combine, but it is not currently up to the task.
16897 ;; When used for their truth value, the cmpstrn* expanders generate
16906 ;; The intermediate three instructions are unnecessary.
16908 ;; This one handles cmpstrn*_nz_1...
16911 (set (reg:CC FLAGS_REG)
16912 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16913 (mem:BLK (match_operand 5 "register_operand"))))
16914 (use (match_operand 6 "register_operand"))
16915 (use (match_operand:SI 3 "immediate_operand"))
16916 (clobber (match_operand 0 "register_operand"))
16917 (clobber (match_operand 1 "register_operand"))
16918 (clobber (match_operand 2 "register_operand"))])
16919 (set (match_operand:QI 7 "register_operand")
16920 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16921 (set (match_operand:QI 8 "register_operand")
16922 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16923 (set (reg FLAGS_REG)
16924 (compare (match_dup 7) (match_dup 8)))
16926 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16928 (set (reg:CC FLAGS_REG)
16929 (compare:CC (mem:BLK (match_dup 4))
16930 (mem:BLK (match_dup 5))))
16931 (use (match_dup 6))
16932 (use (match_dup 3))
16933 (clobber (match_dup 0))
16934 (clobber (match_dup 1))
16935 (clobber (match_dup 2))])])
16937 ;; ...and this one handles cmpstrn*_1.
16940 (set (reg:CC FLAGS_REG)
16941 (if_then_else:CC (ne (match_operand 6 "register_operand")
16943 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16944 (mem:BLK (match_operand 5 "register_operand")))
16946 (use (match_operand:SI 3 "immediate_operand"))
16947 (use (reg:CC FLAGS_REG))
16948 (clobber (match_operand 0 "register_operand"))
16949 (clobber (match_operand 1 "register_operand"))
16950 (clobber (match_operand 2 "register_operand"))])
16951 (set (match_operand:QI 7 "register_operand")
16952 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16953 (set (match_operand:QI 8 "register_operand")
16954 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16955 (set (reg FLAGS_REG)
16956 (compare (match_dup 7) (match_dup 8)))
16958 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16960 (set (reg:CC FLAGS_REG)
16961 (if_then_else:CC (ne (match_dup 6)
16963 (compare:CC (mem:BLK (match_dup 4))
16964 (mem:BLK (match_dup 5)))
16966 (use (match_dup 3))
16967 (use (reg:CC FLAGS_REG))
16968 (clobber (match_dup 0))
16969 (clobber (match_dup 1))
16970 (clobber (match_dup 2))])])
16972 ;; Conditional move instructions.
16974 (define_expand "mov<mode>cc"
16975 [(set (match_operand:SWIM 0 "register_operand")
16976 (if_then_else:SWIM (match_operand 1 "comparison_operator")
16977 (match_operand:SWIM 2 "<general_operand>")
16978 (match_operand:SWIM 3 "<general_operand>")))]
16980 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16982 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16983 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16984 ;; So just document what we're doing explicitly.
16986 (define_expand "x86_mov<mode>cc_0_m1"
16988 [(set (match_operand:SWI48 0 "register_operand")
16989 (if_then_else:SWI48
16990 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16991 [(match_operand 1 "flags_reg_operand")
16995 (clobber (reg:CC FLAGS_REG))])])
16997 (define_insn "*x86_mov<mode>cc_0_m1"
16998 [(set (match_operand:SWI48 0 "register_operand" "=r")
16999 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17000 [(reg FLAGS_REG) (const_int 0)])
17003 (clobber (reg:CC FLAGS_REG))]
17005 "sbb{<imodesuffix>}\t%0, %0"
17006 ; Since we don't have the proper number of operands for an alu insn,
17007 ; fill in all the blanks.
17008 [(set_attr "type" "alu")
17009 (set_attr "modrm_class" "op0")
17010 (set_attr "use_carry" "1")
17011 (set_attr "pent_pair" "pu")
17012 (set_attr "memory" "none")
17013 (set_attr "imm_disp" "false")
17014 (set_attr "mode" "<MODE>")
17015 (set_attr "length_immediate" "0")])
17017 (define_insn "*x86_mov<mode>cc_0_m1_se"
17018 [(set (match_operand:SWI48 0 "register_operand" "=r")
17019 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17020 [(reg FLAGS_REG) (const_int 0)])
17023 (clobber (reg:CC FLAGS_REG))]
17025 "sbb{<imodesuffix>}\t%0, %0"
17026 [(set_attr "type" "alu")
17027 (set_attr "modrm_class" "op0")
17028 (set_attr "use_carry" "1")
17029 (set_attr "pent_pair" "pu")
17030 (set_attr "memory" "none")
17031 (set_attr "imm_disp" "false")
17032 (set_attr "mode" "<MODE>")
17033 (set_attr "length_immediate" "0")])
17035 (define_insn "*x86_mov<mode>cc_0_m1_neg"
17036 [(set (match_operand:SWI48 0 "register_operand" "=r")
17037 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17038 [(reg FLAGS_REG) (const_int 0)])))
17039 (clobber (reg:CC FLAGS_REG))]
17041 "sbb{<imodesuffix>}\t%0, %0"
17042 [(set_attr "type" "alu")
17043 (set_attr "modrm_class" "op0")
17044 (set_attr "use_carry" "1")
17045 (set_attr "pent_pair" "pu")
17046 (set_attr "memory" "none")
17047 (set_attr "imm_disp" "false")
17048 (set_attr "mode" "<MODE>")
17049 (set_attr "length_immediate" "0")])
17051 (define_insn "*mov<mode>cc_noc"
17052 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
17053 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17054 [(reg FLAGS_REG) (const_int 0)])
17055 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
17056 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
17057 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17059 cmov%O2%C1\t{%2, %0|%0, %2}
17060 cmov%O2%c1\t{%3, %0|%0, %3}"
17061 [(set_attr "type" "icmov")
17062 (set_attr "mode" "<MODE>")])
17064 (define_insn "*movsicc_noc_zext"
17065 [(set (match_operand:DI 0 "register_operand" "=r,r")
17066 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17067 [(reg FLAGS_REG) (const_int 0)])
17069 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
17071 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
17073 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17075 cmov%O2%C1\t{%2, %k0|%k0, %2}
17076 cmov%O2%c1\t{%3, %k0|%k0, %3}"
17077 [(set_attr "type" "icmov")
17078 (set_attr "mode" "SI")])
17080 ;; Don't do conditional moves with memory inputs. This splitter helps
17081 ;; register starved x86_32 by forcing inputs into registers before reload.
17083 [(set (match_operand:SWI248 0 "register_operand")
17084 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17085 [(reg FLAGS_REG) (const_int 0)])
17086 (match_operand:SWI248 2 "nonimmediate_operand")
17087 (match_operand:SWI248 3 "nonimmediate_operand")))]
17088 "!TARGET_64BIT && TARGET_CMOVE
17089 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17090 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17091 && can_create_pseudo_p ()
17092 && optimize_insn_for_speed_p ()"
17093 [(set (match_dup 0)
17094 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17096 if (MEM_P (operands[2]))
17097 operands[2] = force_reg (<MODE>mode, operands[2]);
17098 if (MEM_P (operands[3]))
17099 operands[3] = force_reg (<MODE>mode, operands[3]);
17102 (define_insn "*movqicc_noc"
17103 [(set (match_operand:QI 0 "register_operand" "=r,r")
17104 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17105 [(reg FLAGS_REG) (const_int 0)])
17106 (match_operand:QI 2 "register_operand" "r,0")
17107 (match_operand:QI 3 "register_operand" "0,r")))]
17108 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17110 [(set_attr "type" "icmov")
17111 (set_attr "mode" "QI")])
17114 [(set (match_operand:SWI12 0 "register_operand")
17115 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
17116 [(reg FLAGS_REG) (const_int 0)])
17117 (match_operand:SWI12 2 "register_operand")
17118 (match_operand:SWI12 3 "register_operand")))]
17119 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
17120 && reload_completed"
17121 [(set (match_dup 0)
17122 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17124 operands[0] = gen_lowpart (SImode, operands[0]);
17125 operands[2] = gen_lowpart (SImode, operands[2]);
17126 operands[3] = gen_lowpart (SImode, operands[3]);
17129 ;; Don't do conditional moves with memory inputs
17131 [(match_scratch:SWI248 4 "r")
17132 (set (match_operand:SWI248 0 "register_operand")
17133 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17134 [(reg FLAGS_REG) (const_int 0)])
17135 (match_operand:SWI248 2 "nonimmediate_operand")
17136 (match_operand:SWI248 3 "nonimmediate_operand")))]
17137 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17138 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17139 && optimize_insn_for_speed_p ()"
17140 [(set (match_dup 4) (match_dup 5))
17142 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17144 if (MEM_P (operands[2]))
17146 operands[5] = operands[2];
17147 operands[2] = operands[4];
17149 else if (MEM_P (operands[3]))
17151 operands[5] = operands[3];
17152 operands[3] = operands[4];
17155 gcc_unreachable ();
17159 [(match_scratch:SI 4 "r")
17160 (set (match_operand:DI 0 "register_operand")
17161 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17162 [(reg FLAGS_REG) (const_int 0)])
17164 (match_operand:SI 2 "nonimmediate_operand"))
17166 (match_operand:SI 3 "nonimmediate_operand"))))]
17168 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17169 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17170 && optimize_insn_for_speed_p ()"
17171 [(set (match_dup 4) (match_dup 5))
17173 (if_then_else:DI (match_dup 1)
17174 (zero_extend:DI (match_dup 2))
17175 (zero_extend:DI (match_dup 3))))]
17177 if (MEM_P (operands[2]))
17179 operands[5] = operands[2];
17180 operands[2] = operands[4];
17182 else if (MEM_P (operands[3]))
17184 operands[5] = operands[3];
17185 operands[3] = operands[4];
17188 gcc_unreachable ();
17191 (define_expand "mov<mode>cc"
17192 [(set (match_operand:X87MODEF 0 "register_operand")
17193 (if_then_else:X87MODEF
17194 (match_operand 1 "comparison_operator")
17195 (match_operand:X87MODEF 2 "register_operand")
17196 (match_operand:X87MODEF 3 "register_operand")))]
17197 "(TARGET_80387 && TARGET_CMOVE)
17198 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17199 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
17201 (define_insn "*movxfcc_1"
17202 [(set (match_operand:XF 0 "register_operand" "=f,f")
17203 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17204 [(reg FLAGS_REG) (const_int 0)])
17205 (match_operand:XF 2 "register_operand" "f,0")
17206 (match_operand:XF 3 "register_operand" "0,f")))]
17207 "TARGET_80387 && TARGET_CMOVE"
17209 fcmov%F1\t{%2, %0|%0, %2}
17210 fcmov%f1\t{%3, %0|%0, %3}"
17211 [(set_attr "type" "fcmov")
17212 (set_attr "mode" "XF")])
17214 (define_insn "*movdfcc_1"
17215 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
17216 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17217 [(reg FLAGS_REG) (const_int 0)])
17218 (match_operand:DF 2 "nonimmediate_operand"
17220 (match_operand:DF 3 "nonimmediate_operand"
17221 "0 ,f,0 ,rm,0, rm")))]
17222 "TARGET_80387 && TARGET_CMOVE
17223 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17225 fcmov%F1\t{%2, %0|%0, %2}
17226 fcmov%f1\t{%3, %0|%0, %3}
17229 cmov%O2%C1\t{%2, %0|%0, %2}
17230 cmov%O2%c1\t{%3, %0|%0, %3}"
17231 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
17232 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
17233 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
17236 [(set (match_operand:DF 0 "general_reg_operand")
17237 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17238 [(reg FLAGS_REG) (const_int 0)])
17239 (match_operand:DF 2 "nonimmediate_operand")
17240 (match_operand:DF 3 "nonimmediate_operand")))]
17241 "!TARGET_64BIT && reload_completed"
17242 [(set (match_dup 2)
17243 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
17245 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
17247 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
17248 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
17251 (define_insn "*movsfcc_1_387"
17252 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
17253 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17254 [(reg FLAGS_REG) (const_int 0)])
17255 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
17256 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
17257 "TARGET_80387 && TARGET_CMOVE
17258 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17260 fcmov%F1\t{%2, %0|%0, %2}
17261 fcmov%f1\t{%3, %0|%0, %3}
17262 cmov%O2%C1\t{%2, %0|%0, %2}
17263 cmov%O2%c1\t{%3, %0|%0, %3}"
17264 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17265 (set_attr "mode" "SF,SF,SI,SI")])
17267 ;; Don't do conditional moves with memory inputs. This splitter helps
17268 ;; register starved x86_32 by forcing inputs into registers before reload.
17270 [(set (match_operand:MODEF 0 "register_operand")
17271 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
17272 [(reg FLAGS_REG) (const_int 0)])
17273 (match_operand:MODEF 2 "nonimmediate_operand")
17274 (match_operand:MODEF 3 "nonimmediate_operand")))]
17275 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17276 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17277 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17278 && can_create_pseudo_p ()
17279 && optimize_insn_for_speed_p ()"
17280 [(set (match_dup 0)
17281 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17283 if (MEM_P (operands[2]))
17284 operands[2] = force_reg (<MODE>mode, operands[2]);
17285 if (MEM_P (operands[3]))
17286 operands[3] = force_reg (<MODE>mode, operands[3]);
17289 ;; Don't do conditional moves with memory inputs
17291 [(match_scratch:MODEF 4 "r")
17292 (set (match_operand:MODEF 0 "general_reg_operand")
17293 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
17294 [(reg FLAGS_REG) (const_int 0)])
17295 (match_operand:MODEF 2 "nonimmediate_operand")
17296 (match_operand:MODEF 3 "nonimmediate_operand")))]
17297 "(<MODE>mode != DFmode || TARGET_64BIT)
17298 && TARGET_80387 && TARGET_CMOVE
17299 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17300 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17301 && optimize_insn_for_speed_p ()"
17302 [(set (match_dup 4) (match_dup 5))
17304 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17306 if (MEM_P (operands[2]))
17308 operands[5] = operands[2];
17309 operands[2] = operands[4];
17311 else if (MEM_P (operands[3]))
17313 operands[5] = operands[3];
17314 operands[3] = operands[4];
17317 gcc_unreachable ();
17320 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
17321 ;; the scalar versions to have only XMM registers as operands.
17323 ;; XOP conditional move
17324 (define_insn "*xop_pcmov_<mode>"
17325 [(set (match_operand:MODEF 0 "register_operand" "=x")
17326 (if_then_else:MODEF
17327 (match_operand:MODEF 1 "register_operand" "x")
17328 (match_operand:MODEF 2 "register_operand" "x")
17329 (match_operand:MODEF 3 "register_operand" "x")))]
17331 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
17332 [(set_attr "type" "sse4arg")])
17334 ;; These versions of the min/max patterns are intentionally ignorant of
17335 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17336 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17337 ;; are undefined in this condition, we're certain this is correct.
17339 (define_insn "<code><mode>3"
17340 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17342 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
17343 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
17344 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17346 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
17347 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17348 [(set_attr "isa" "noavx,avx")
17349 (set_attr "prefix" "orig,vex")
17350 (set_attr "type" "sseadd")
17351 (set_attr "mode" "<MODE>")])
17353 ;; These versions of the min/max patterns implement exactly the operations
17354 ;; min = (op1 < op2 ? op1 : op2)
17355 ;; max = (!(op1 < op2) ? op1 : op2)
17356 ;; Their operands are not commutative, and thus they may be used in the
17357 ;; presence of -0.0 and NaN.
17359 (define_int_iterator IEEE_MAXMIN
17363 (define_int_attr ieee_maxmin
17364 [(UNSPEC_IEEE_MAX "max")
17365 (UNSPEC_IEEE_MIN "min")])
17367 (define_insn "*ieee_s<ieee_maxmin><mode>3"
17368 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17370 [(match_operand:MODEF 1 "register_operand" "0,v")
17371 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
17373 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17375 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
17376 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17377 [(set_attr "isa" "noavx,avx")
17378 (set_attr "prefix" "orig,maybe_evex")
17379 (set_attr "type" "sseadd")
17380 (set_attr "mode" "<MODE>")])
17382 ;; Make two stack loads independent:
17384 ;; fld %st(0) -> fld bb
17385 ;; fmul bb fmul %st(1), %st
17387 ;; Actually we only match the last two instructions for simplicity.
17390 [(set (match_operand 0 "fp_register_operand")
17391 (match_operand 1 "fp_register_operand"))
17393 (match_operator 2 "binary_fp_operator"
17395 (match_operand 3 "memory_operand")]))]
17396 "REGNO (operands[0]) != REGNO (operands[1])"
17397 [(set (match_dup 0) (match_dup 3))
17400 [(match_dup 5) (match_dup 4)]))]
17402 operands[4] = operands[0];
17403 operands[5] = operands[1];
17405 /* The % modifier is not operational anymore in peephole2's, so we have to
17406 swap the operands manually in the case of addition and multiplication. */
17407 if (COMMUTATIVE_ARITH_P (operands[2]))
17408 std::swap (operands[4], operands[5]);
17412 [(set (match_operand 0 "fp_register_operand")
17413 (match_operand 1 "fp_register_operand"))
17415 (match_operator 2 "binary_fp_operator"
17416 [(match_operand 3 "memory_operand")
17418 "REGNO (operands[0]) != REGNO (operands[1])"
17419 [(set (match_dup 0) (match_dup 3))
17422 [(match_dup 4) (match_dup 5)]))]
17424 operands[4] = operands[0];
17425 operands[5] = operands[1];
17427 /* The % modifier is not operational anymore in peephole2's, so we have to
17428 swap the operands manually in the case of addition and multiplication. */
17429 if (COMMUTATIVE_ARITH_P (operands[2]))
17430 std::swap (operands[4], operands[5]);
17433 ;; Conditional addition patterns
17434 (define_expand "add<mode>cc"
17435 [(match_operand:SWI 0 "register_operand")
17436 (match_operand 1 "ordered_comparison_operator")
17437 (match_operand:SWI 2 "register_operand")
17438 (match_operand:SWI 3 "const_int_operand")]
17440 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17442 ;; Misc patterns (?)
17444 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17445 ;; Otherwise there will be nothing to keep
17447 ;; [(set (reg ebp) (reg esp))]
17448 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17449 ;; (clobber (eflags)]
17450 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17452 ;; in proper program order.
17454 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
17455 [(set (match_operand:P 0 "register_operand" "=r,r")
17456 (plus:P (match_operand:P 1 "register_operand" "0,r")
17457 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17458 (clobber (reg:CC FLAGS_REG))
17459 (clobber (mem:BLK (scratch)))]
17462 switch (get_attr_type (insn))
17465 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17468 gcc_assert (rtx_equal_p (operands[0], operands[1]));
17469 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17470 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17472 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17475 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17476 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17479 [(set (attr "type")
17480 (cond [(and (eq_attr "alternative" "0")
17481 (not (match_test "TARGET_OPT_AGU")))
17482 (const_string "alu")
17483 (match_operand:<MODE> 2 "const0_operand")
17484 (const_string "imov")
17486 (const_string "lea")))
17487 (set (attr "length_immediate")
17488 (cond [(eq_attr "type" "imov")
17490 (and (eq_attr "type" "alu")
17491 (match_operand 2 "const128_operand"))
17494 (const_string "*")))
17495 (set_attr "mode" "<MODE>")])
17497 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
17498 [(set (match_operand:P 0 "register_operand" "=r")
17499 (minus:P (match_operand:P 1 "register_operand" "0")
17500 (match_operand:P 2 "register_operand" "r")))
17501 (clobber (reg:CC FLAGS_REG))
17502 (clobber (mem:BLK (scratch)))]
17504 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17505 [(set_attr "type" "alu")
17506 (set_attr "mode" "<MODE>")])
17508 (define_insn "allocate_stack_worker_probe_<mode>"
17509 [(set (match_operand:P 0 "register_operand" "=a")
17510 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17511 UNSPECV_STACK_PROBE))
17512 (clobber (reg:CC FLAGS_REG))]
17513 "ix86_target_stack_probe ()"
17514 "call\t___chkstk_ms"
17515 [(set_attr "type" "multi")
17516 (set_attr "length" "5")])
17518 (define_expand "allocate_stack"
17519 [(match_operand 0 "register_operand")
17520 (match_operand 1 "general_operand")]
17521 "ix86_target_stack_probe ()"
17525 #ifndef CHECK_STACK_LIMIT
17526 #define CHECK_STACK_LIMIT 0
17529 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17530 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17534 rtx (*insn) (rtx, rtx);
17536 x = copy_to_mode_reg (Pmode, operands[1]);
17538 insn = (TARGET_64BIT
17539 ? gen_allocate_stack_worker_probe_di
17540 : gen_allocate_stack_worker_probe_si);
17542 emit_insn (insn (x, x));
17545 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17546 stack_pointer_rtx, 0, OPTAB_DIRECT);
17548 if (x != stack_pointer_rtx)
17549 emit_move_insn (stack_pointer_rtx, x);
17551 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17555 (define_expand "probe_stack"
17556 [(match_operand 0 "memory_operand")]
17559 rtx (*insn) (rtx, rtx)
17560 = (GET_MODE (operands[0]) == DImode
17561 ? gen_probe_stack_di : gen_probe_stack_si);
17563 emit_insn (insn (operands[0], const0_rtx));
17567 ;; Use OR for stack probes, this is shorter.
17568 (define_insn "probe_stack_<mode>"
17569 [(set (match_operand:W 0 "memory_operand" "=m")
17570 (unspec:W [(match_operand:W 1 "const0_operand")]
17571 UNSPEC_PROBE_STACK))
17572 (clobber (reg:CC FLAGS_REG))]
17574 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
17575 [(set_attr "type" "alu1")
17576 (set_attr "mode" "<MODE>")
17577 (set_attr "length_immediate" "1")])
17579 (define_insn "adjust_stack_and_probe<mode>"
17580 [(set (match_operand:P 0 "register_operand" "=r")
17581 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17582 UNSPECV_PROBE_STACK_RANGE))
17583 (set (reg:P SP_REG)
17584 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17585 (clobber (reg:CC FLAGS_REG))
17586 (clobber (mem:BLK (scratch)))]
17588 "* return output_adjust_stack_and_probe (operands[0]);"
17589 [(set_attr "type" "multi")])
17591 (define_insn "probe_stack_range<mode>"
17592 [(set (match_operand:P 0 "register_operand" "=r")
17593 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17594 (match_operand:P 2 "const_int_operand" "n")]
17595 UNSPECV_PROBE_STACK_RANGE))
17596 (clobber (reg:CC FLAGS_REG))]
17598 "* return output_probe_stack_range (operands[0], operands[2]);"
17599 [(set_attr "type" "multi")])
17601 (define_expand "builtin_setjmp_receiver"
17602 [(label_ref (match_operand 0))]
17603 "!TARGET_64BIT && flag_pic"
17609 rtx_code_label *label_rtx = gen_label_rtx ();
17610 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17611 xops[0] = xops[1] = pic_offset_table_rtx;
17612 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17613 ix86_expand_binary_operator (MINUS, SImode, xops);
17617 emit_insn (gen_set_got (pic_offset_table_rtx));
17621 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17622 ;; Do not split instructions with mask registers.
17624 [(set (match_operand 0 "general_reg_operand")
17625 (match_operator 3 "promotable_binary_operator"
17626 [(match_operand 1 "general_reg_operand")
17627 (match_operand 2 "aligned_operand")]))
17628 (clobber (reg:CC FLAGS_REG))]
17629 "! TARGET_PARTIAL_REG_STALL && reload_completed
17630 && ((GET_MODE (operands[0]) == HImode
17631 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17632 /* ??? next two lines just !satisfies_constraint_K (...) */
17633 || !CONST_INT_P (operands[2])
17634 || satisfies_constraint_K (operands[2])))
17635 || (GET_MODE (operands[0]) == QImode
17636 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17637 [(parallel [(set (match_dup 0)
17638 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17639 (clobber (reg:CC FLAGS_REG))])]
17641 operands[0] = gen_lowpart (SImode, operands[0]);
17642 operands[1] = gen_lowpart (SImode, operands[1]);
17643 if (GET_CODE (operands[3]) != ASHIFT)
17644 operands[2] = gen_lowpart (SImode, operands[2]);
17645 operands[3] = shallow_copy_rtx (operands[3]);
17646 PUT_MODE (operands[3], SImode);
17649 ; Promote the QImode tests, as i386 has encoding of the AND
17650 ; instruction with 32-bit sign-extended immediate and thus the
17651 ; instruction size is unchanged, except in the %eax case for
17652 ; which it is increased by one byte, hence the ! optimize_size.
17654 [(set (match_operand 0 "flags_reg_operand")
17655 (match_operator 2 "compare_operator"
17656 [(and (match_operand 3 "aligned_operand")
17657 (match_operand 4 "const_int_operand"))
17659 (set (match_operand 1 "register_operand")
17660 (and (match_dup 3) (match_dup 4)))]
17661 "! TARGET_PARTIAL_REG_STALL && reload_completed
17662 && optimize_insn_for_speed_p ()
17663 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17664 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17665 /* Ensure that the operand will remain sign-extended immediate. */
17666 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17667 [(parallel [(set (match_dup 0)
17668 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17671 (and:SI (match_dup 3) (match_dup 4)))])]
17674 = gen_int_mode (INTVAL (operands[4])
17675 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17676 operands[1] = gen_lowpart (SImode, operands[1]);
17677 operands[3] = gen_lowpart (SImode, operands[3]);
17680 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17681 ; the TEST instruction with 32-bit sign-extended immediate and thus
17682 ; the instruction size would at least double, which is not what we
17683 ; want even with ! optimize_size.
17685 [(set (match_operand 0 "flags_reg_operand")
17686 (match_operator 1 "compare_operator"
17687 [(and (match_operand:HI 2 "aligned_operand")
17688 (match_operand:HI 3 "const_int_operand"))
17690 "! TARGET_PARTIAL_REG_STALL && reload_completed
17691 && ! TARGET_FAST_PREFIX
17692 && optimize_insn_for_speed_p ()
17693 /* Ensure that the operand will remain sign-extended immediate. */
17694 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17695 [(set (match_dup 0)
17696 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17700 = gen_int_mode (INTVAL (operands[3])
17701 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17702 operands[2] = gen_lowpart (SImode, operands[2]);
17706 [(set (match_operand 0 "register_operand")
17707 (neg (match_operand 1 "register_operand")))
17708 (clobber (reg:CC FLAGS_REG))]
17709 "! TARGET_PARTIAL_REG_STALL && reload_completed
17710 && (GET_MODE (operands[0]) == HImode
17711 || (GET_MODE (operands[0]) == QImode
17712 && (TARGET_PROMOTE_QImode
17713 || optimize_insn_for_size_p ())))"
17714 [(parallel [(set (match_dup 0)
17715 (neg:SI (match_dup 1)))
17716 (clobber (reg:CC FLAGS_REG))])]
17718 operands[0] = gen_lowpart (SImode, operands[0]);
17719 operands[1] = gen_lowpart (SImode, operands[1]);
17722 ;; Do not split instructions with mask regs.
17724 [(set (match_operand 0 "general_reg_operand")
17725 (not (match_operand 1 "general_reg_operand")))]
17726 "! TARGET_PARTIAL_REG_STALL && reload_completed
17727 && (GET_MODE (operands[0]) == HImode
17728 || (GET_MODE (operands[0]) == QImode
17729 && (TARGET_PROMOTE_QImode
17730 || optimize_insn_for_size_p ())))"
17731 [(set (match_dup 0)
17732 (not:SI (match_dup 1)))]
17734 operands[0] = gen_lowpart (SImode, operands[0]);
17735 operands[1] = gen_lowpart (SImode, operands[1]);
17738 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17739 ;; transform a complex memory operation into two memory to register operations.
17741 ;; Don't push memory operands
17743 [(set (match_operand:SWI 0 "push_operand")
17744 (match_operand:SWI 1 "memory_operand"))
17745 (match_scratch:SWI 2 "<r>")]
17746 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17747 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17748 [(set (match_dup 2) (match_dup 1))
17749 (set (match_dup 0) (match_dup 2))])
17751 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17754 [(set (match_operand:SF 0 "push_operand")
17755 (match_operand:SF 1 "memory_operand"))
17756 (match_scratch:SF 2 "r")]
17757 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17758 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17759 [(set (match_dup 2) (match_dup 1))
17760 (set (match_dup 0) (match_dup 2))])
17762 ;; Don't move an immediate directly to memory when the instruction
17763 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17765 [(match_scratch:SWI124 1 "<r>")
17766 (set (match_operand:SWI124 0 "memory_operand")
17768 "optimize_insn_for_speed_p ()
17769 && ((<MODE>mode == HImode
17770 && TARGET_LCP_STALL)
17771 || (!TARGET_USE_MOV0
17772 && TARGET_SPLIT_LONG_MOVES
17773 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17774 && peep2_regno_dead_p (0, FLAGS_REG)"
17775 [(parallel [(set (match_dup 2) (const_int 0))
17776 (clobber (reg:CC FLAGS_REG))])
17777 (set (match_dup 0) (match_dup 1))]
17778 "operands[2] = gen_lowpart (SImode, operands[1]);")
17781 [(match_scratch:SWI124 2 "<r>")
17782 (set (match_operand:SWI124 0 "memory_operand")
17783 (match_operand:SWI124 1 "immediate_operand"))]
17784 "optimize_insn_for_speed_p ()
17785 && ((<MODE>mode == HImode
17786 && TARGET_LCP_STALL)
17787 || (TARGET_SPLIT_LONG_MOVES
17788 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17789 [(set (match_dup 2) (match_dup 1))
17790 (set (match_dup 0) (match_dup 2))])
17792 ;; Don't compare memory with zero, load and use a test instead.
17794 [(set (match_operand 0 "flags_reg_operand")
17795 (match_operator 1 "compare_operator"
17796 [(match_operand:SI 2 "memory_operand")
17798 (match_scratch:SI 3 "r")]
17799 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17800 [(set (match_dup 3) (match_dup 2))
17801 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17803 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17804 ;; Don't split NOTs with a displacement operand, because resulting XOR
17805 ;; will not be pairable anyway.
17807 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17808 ;; represented using a modRM byte. The XOR replacement is long decoded,
17809 ;; so this split helps here as well.
17811 ;; Note: Can't do this as a regular split because we can't get proper
17812 ;; lifetime information then.
17815 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
17816 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
17817 "optimize_insn_for_speed_p ()
17818 && ((TARGET_NOT_UNPAIRABLE
17819 && (!MEM_P (operands[0])
17820 || !memory_displacement_operand (operands[0], <MODE>mode)))
17821 || (TARGET_NOT_VECTORMODE
17822 && long_memory_operand (operands[0], <MODE>mode)))
17823 && peep2_regno_dead_p (0, FLAGS_REG)"
17824 [(parallel [(set (match_dup 0)
17825 (xor:SWI124 (match_dup 1) (const_int -1)))
17826 (clobber (reg:CC FLAGS_REG))])])
17828 ;; Non pairable "test imm, reg" instructions can be translated to
17829 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17830 ;; byte opcode instead of two, have a short form for byte operands),
17831 ;; so do it for other CPUs as well. Given that the value was dead,
17832 ;; this should not create any new dependencies. Pass on the sub-word
17833 ;; versions if we're concerned about partial register stalls.
17836 [(set (match_operand 0 "flags_reg_operand")
17837 (match_operator 1 "compare_operator"
17838 [(and:SI (match_operand:SI 2 "register_operand")
17839 (match_operand:SI 3 "immediate_operand"))
17841 "ix86_match_ccmode (insn, CCNOmode)
17842 && (REGNO (operands[2]) != AX_REG
17843 || satisfies_constraint_K (operands[3]))
17844 && peep2_reg_dead_p (1, operands[2])"
17846 [(set (match_dup 0)
17847 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17850 (and:SI (match_dup 2) (match_dup 3)))])])
17852 ;; We don't need to handle HImode case, because it will be promoted to SImode
17853 ;; on ! TARGET_PARTIAL_REG_STALL
17856 [(set (match_operand 0 "flags_reg_operand")
17857 (match_operator 1 "compare_operator"
17858 [(and:QI (match_operand:QI 2 "register_operand")
17859 (match_operand:QI 3 "immediate_operand"))
17861 "! TARGET_PARTIAL_REG_STALL
17862 && ix86_match_ccmode (insn, CCNOmode)
17863 && REGNO (operands[2]) != AX_REG
17864 && peep2_reg_dead_p (1, operands[2])"
17866 [(set (match_dup 0)
17867 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17870 (and:QI (match_dup 2) (match_dup 3)))])])
17873 [(set (match_operand 0 "flags_reg_operand")
17874 (match_operator 1 "compare_operator"
17877 (match_operand 2 "QIreg_operand")
17880 (match_operand 3 "const_int_operand"))
17882 "! TARGET_PARTIAL_REG_STALL
17883 && ix86_match_ccmode (insn, CCNOmode)
17884 && REGNO (operands[2]) != AX_REG
17885 && peep2_reg_dead_p (1, operands[2])"
17886 [(parallel [(set (match_dup 0)
17895 (set (zero_extract:SI (match_dup 2)
17903 (match_dup 3)))])])
17905 ;; Don't do logical operations with memory inputs.
17907 [(match_scratch:SWI 2 "<r>")
17908 (parallel [(set (match_operand:SWI 0 "register_operand")
17909 (match_operator:SWI 3 "arith_or_logical_operator"
17911 (match_operand:SWI 1 "memory_operand")]))
17912 (clobber (reg:CC FLAGS_REG))])]
17913 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17914 [(set (match_dup 2) (match_dup 1))
17915 (parallel [(set (match_dup 0)
17916 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17917 (clobber (reg:CC FLAGS_REG))])])
17920 [(match_scratch:SWI 2 "<r>")
17921 (parallel [(set (match_operand:SWI 0 "register_operand")
17922 (match_operator:SWI 3 "arith_or_logical_operator"
17923 [(match_operand:SWI 1 "memory_operand")
17925 (clobber (reg:CC FLAGS_REG))])]
17926 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17927 [(set (match_dup 2) (match_dup 1))
17928 (parallel [(set (match_dup 0)
17929 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17930 (clobber (reg:CC FLAGS_REG))])])
17932 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
17933 ;; the memory address refers to the destination of the load!
17936 [(set (match_operand:SWI 0 "general_reg_operand")
17937 (match_operand:SWI 1 "general_reg_operand"))
17938 (parallel [(set (match_dup 0)
17939 (match_operator:SWI 3 "commutative_operator"
17941 (match_operand:SWI 2 "memory_operand")]))
17942 (clobber (reg:CC FLAGS_REG))])]
17943 "REGNO (operands[0]) != REGNO (operands[1])
17944 && (<MODE>mode != QImode
17945 || any_QIreg_operand (operands[1], QImode))"
17946 [(set (match_dup 0) (match_dup 4))
17947 (parallel [(set (match_dup 0)
17948 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17949 (clobber (reg:CC FLAGS_REG))])]
17950 "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
17953 [(set (match_operand 0 "mmx_reg_operand")
17954 (match_operand 1 "mmx_reg_operand"))
17956 (match_operator 3 "commutative_operator"
17958 (match_operand 2 "memory_operand")]))]
17959 "REGNO (operands[0]) != REGNO (operands[1])"
17960 [(set (match_dup 0) (match_dup 2))
17962 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17965 [(set (match_operand 0 "sse_reg_operand")
17966 (match_operand 1 "sse_reg_operand"))
17968 (match_operator 3 "commutative_operator"
17970 (match_operand 2 "memory_operand")]))]
17971 "REGNO (operands[0]) != REGNO (operands[1])"
17972 [(set (match_dup 0) (match_dup 2))
17974 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17976 ; Don't do logical operations with memory outputs
17978 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17979 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17980 ; the same decoder scheduling characteristics as the original.
17983 [(match_scratch:SWI 2 "<r>")
17984 (parallel [(set (match_operand:SWI 0 "memory_operand")
17985 (match_operator:SWI 3 "arith_or_logical_operator"
17987 (match_operand:SWI 1 "<nonmemory_operand>")]))
17988 (clobber (reg:CC FLAGS_REG))])]
17989 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
17990 [(set (match_dup 2) (match_dup 0))
17991 (parallel [(set (match_dup 2)
17992 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17993 (clobber (reg:CC FLAGS_REG))])
17994 (set (match_dup 0) (match_dup 2))])
17997 [(match_scratch:SWI 2 "<r>")
17998 (parallel [(set (match_operand:SWI 0 "memory_operand")
17999 (match_operator:SWI 3 "arith_or_logical_operator"
18000 [(match_operand:SWI 1 "<nonmemory_operand>")
18002 (clobber (reg:CC FLAGS_REG))])]
18003 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18004 [(set (match_dup 2) (match_dup 0))
18005 (parallel [(set (match_dup 2)
18006 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18007 (clobber (reg:CC FLAGS_REG))])
18008 (set (match_dup 0) (match_dup 2))])
18010 ;; Attempt to use arith or logical operations with memory outputs with
18011 ;; setting of flags.
18013 [(set (match_operand:SWI 0 "register_operand")
18014 (match_operand:SWI 1 "memory_operand"))
18015 (parallel [(set (match_dup 0)
18016 (match_operator:SWI 3 "plusminuslogic_operator"
18018 (match_operand:SWI 2 "<nonmemory_operand>")]))
18019 (clobber (reg:CC FLAGS_REG))])
18020 (set (match_dup 1) (match_dup 0))
18021 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18022 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18023 && peep2_reg_dead_p (4, operands[0])
18024 && !reg_overlap_mentioned_p (operands[0], operands[1])
18025 && !reg_overlap_mentioned_p (operands[0], operands[2])
18026 && (<MODE>mode != QImode
18027 || immediate_operand (operands[2], QImode)
18028 || any_QIreg_operand (operands[2], QImode))
18029 && ix86_match_ccmode (peep2_next_insn (3),
18030 (GET_CODE (operands[3]) == PLUS
18031 || GET_CODE (operands[3]) == MINUS)
18032 ? CCGOCmode : CCNOmode)"
18033 [(parallel [(set (match_dup 4) (match_dup 6))
18034 (set (match_dup 1) (match_dup 5))])]
18036 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18038 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18039 copy_rtx (operands[1]),
18042 = gen_rtx_COMPARE (GET_MODE (operands[4]),
18043 copy_rtx (operands[5]),
18047 ;; Likewise for instances where we have a lea pattern.
18049 [(set (match_operand:SWI 0 "register_operand")
18050 (match_operand:SWI 1 "memory_operand"))
18051 (set (match_operand:SWI 3 "register_operand")
18052 (plus:SWI (match_dup 0)
18053 (match_operand:SWI 2 "<nonmemory_operand>")))
18054 (set (match_dup 1) (match_dup 3))
18055 (set (reg FLAGS_REG) (compare (match_dup 3) (const_int 0)))]
18056 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18057 && peep2_reg_dead_p (4, operands[3])
18058 && (rtx_equal_p (operands[0], operands[3])
18059 || peep2_reg_dead_p (2, operands[0]))
18060 && !reg_overlap_mentioned_p (operands[0], operands[1])
18061 && !reg_overlap_mentioned_p (operands[3], operands[1])
18062 && !reg_overlap_mentioned_p (operands[0], operands[2])
18063 && (<MODE>mode != QImode
18064 || immediate_operand (operands[2], QImode)
18065 || any_QIreg_operand (operands[2], QImode))
18066 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
18067 [(parallel [(set (match_dup 4) (match_dup 6))
18068 (set (match_dup 1) (match_dup 5))])]
18070 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18072 = gen_rtx_PLUS (<MODE>mode,
18073 copy_rtx (operands[1]),
18076 = gen_rtx_COMPARE (GET_MODE (operands[4]),
18077 copy_rtx (operands[5]),
18082 [(parallel [(set (match_operand:SWI 0 "register_operand")
18083 (match_operator:SWI 2 "plusminuslogic_operator"
18085 (match_operand:SWI 1 "memory_operand")]))
18086 (clobber (reg:CC FLAGS_REG))])
18087 (set (match_dup 1) (match_dup 0))
18088 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18089 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18090 && GET_CODE (operands[2]) != MINUS
18091 && peep2_reg_dead_p (3, operands[0])
18092 && !reg_overlap_mentioned_p (operands[0], operands[1])
18093 && ix86_match_ccmode (peep2_next_insn (2),
18094 GET_CODE (operands[2]) == PLUS
18095 ? CCGOCmode : CCNOmode)"
18096 [(parallel [(set (match_dup 3) (match_dup 5))
18097 (set (match_dup 1) (match_dup 4))])]
18099 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
18101 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18102 copy_rtx (operands[1]),
18105 = gen_rtx_COMPARE (GET_MODE (operands[3]),
18106 copy_rtx (operands[4]),
18111 [(set (match_operand:SWI12 0 "register_operand")
18112 (match_operand:SWI12 1 "memory_operand"))
18113 (parallel [(set (match_operand:SI 4 "register_operand")
18114 (match_operator:SI 3 "plusminuslogic_operator"
18116 (match_operand:SI 2 "nonmemory_operand")]))
18117 (clobber (reg:CC FLAGS_REG))])
18118 (set (match_dup 1) (match_dup 0))
18119 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18120 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18121 && REGNO (operands[0]) == REGNO (operands[4])
18122 && peep2_reg_dead_p (4, operands[0])
18123 && (<MODE>mode != QImode
18124 || immediate_operand (operands[2], SImode)
18125 || any_QIreg_operand (operands[2], SImode))
18126 && !reg_overlap_mentioned_p (operands[0], operands[1])
18127 && !reg_overlap_mentioned_p (operands[0], operands[2])
18128 && ix86_match_ccmode (peep2_next_insn (3),
18129 (GET_CODE (operands[3]) == PLUS
18130 || GET_CODE (operands[3]) == MINUS)
18131 ? CCGOCmode : CCNOmode)"
18132 [(parallel [(set (match_dup 4) (match_dup 6))
18133 (set (match_dup 1) (match_dup 5))])]
18135 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18137 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18138 copy_rtx (operands[1]),
18139 gen_lowpart (<MODE>mode, operands[2]));
18141 = gen_rtx_COMPARE (GET_MODE (operands[4]),
18142 copy_rtx (operands[5]),
18146 ;; Attempt to always use XOR for zeroing registers (including FP modes).
18148 [(set (match_operand 0 "general_reg_operand")
18149 (match_operand 1 "const0_operand"))]
18150 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18151 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18152 && peep2_regno_dead_p (0, FLAGS_REG)"
18153 [(parallel [(set (match_dup 0) (const_int 0))
18154 (clobber (reg:CC FLAGS_REG))])]
18155 "operands[0] = gen_lowpart (word_mode, operands[0]);")
18158 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
18160 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18161 && peep2_regno_dead_p (0, FLAGS_REG)"
18162 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18163 (clobber (reg:CC FLAGS_REG))])])
18165 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
18167 [(set (match_operand:SWI248 0 "general_reg_operand")
18169 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
18170 && peep2_regno_dead_p (0, FLAGS_REG)"
18171 [(parallel [(set (match_dup 0) (const_int -1))
18172 (clobber (reg:CC FLAGS_REG))])]
18174 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
18175 operands[0] = gen_lowpart (SImode, operands[0]);
18178 ;; Attempt to convert simple lea to add/shift.
18179 ;; These can be created by move expanders.
18180 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
18181 ;; relevant lea instructions were already split.
18184 [(set (match_operand:SWI48 0 "register_operand")
18185 (plus:SWI48 (match_dup 0)
18186 (match_operand:SWI48 1 "<nonmemory_operand>")))]
18188 && peep2_regno_dead_p (0, FLAGS_REG)"
18189 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18190 (clobber (reg:CC FLAGS_REG))])])
18193 [(set (match_operand:SWI48 0 "register_operand")
18194 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
18197 && peep2_regno_dead_p (0, FLAGS_REG)"
18198 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18199 (clobber (reg:CC FLAGS_REG))])])
18202 [(set (match_operand:DI 0 "register_operand")
18204 (plus:SI (match_operand:SI 1 "register_operand")
18205 (match_operand:SI 2 "nonmemory_operand"))))]
18206 "TARGET_64BIT && !TARGET_OPT_AGU
18207 && REGNO (operands[0]) == REGNO (operands[1])
18208 && peep2_regno_dead_p (0, FLAGS_REG)"
18209 [(parallel [(set (match_dup 0)
18210 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
18211 (clobber (reg:CC FLAGS_REG))])])
18214 [(set (match_operand:DI 0 "register_operand")
18216 (plus:SI (match_operand:SI 1 "nonmemory_operand")
18217 (match_operand:SI 2 "register_operand"))))]
18218 "TARGET_64BIT && !TARGET_OPT_AGU
18219 && REGNO (operands[0]) == REGNO (operands[2])
18220 && peep2_regno_dead_p (0, FLAGS_REG)"
18221 [(parallel [(set (match_dup 0)
18222 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
18223 (clobber (reg:CC FLAGS_REG))])])
18226 [(set (match_operand:SWI48 0 "register_operand")
18227 (mult:SWI48 (match_dup 0)
18228 (match_operand:SWI48 1 "const_int_operand")))]
18229 "exact_log2 (INTVAL (operands[1])) >= 0
18230 && peep2_regno_dead_p (0, FLAGS_REG)"
18231 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
18232 (clobber (reg:CC FLAGS_REG))])]
18233 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18236 [(set (match_operand:DI 0 "register_operand")
18238 (mult:SI (match_operand:SI 1 "register_operand")
18239 (match_operand:SI 2 "const_int_operand"))))]
18241 && exact_log2 (INTVAL (operands[2])) >= 0
18242 && REGNO (operands[0]) == REGNO (operands[1])
18243 && peep2_regno_dead_p (0, FLAGS_REG)"
18244 [(parallel [(set (match_dup 0)
18245 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
18246 (clobber (reg:CC FLAGS_REG))])]
18247 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18249 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18250 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
18251 ;; On many CPUs it is also faster, since special hardware to avoid esp
18252 ;; dependencies is present.
18254 ;; While some of these conversions may be done using splitters, we use
18255 ;; peepholes in order to allow combine_stack_adjustments pass to see
18256 ;; nonobfuscated RTL.
18258 ;; Convert prologue esp subtractions to push.
18259 ;; We need register to push. In order to keep verify_flow_info happy we have
18261 ;; - use scratch and clobber it in order to avoid dependencies
18262 ;; - use already live register
18263 ;; We can't use the second way right now, since there is no reliable way how to
18264 ;; verify that given register is live. First choice will also most likely in
18265 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18266 ;; call clobbered registers are dead. We may want to use base pointer as an
18267 ;; alternative when no register is available later.
18270 [(match_scratch:W 1 "r")
18271 (parallel [(set (reg:P SP_REG)
18272 (plus:P (reg:P SP_REG)
18273 (match_operand:P 0 "const_int_operand")))
18274 (clobber (reg:CC FLAGS_REG))
18275 (clobber (mem:BLK (scratch)))])]
18276 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18277 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
18278 && !ix86_using_red_zone ()"
18279 [(clobber (match_dup 1))
18280 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18281 (clobber (mem:BLK (scratch)))])])
18284 [(match_scratch:W 1 "r")
18285 (parallel [(set (reg:P SP_REG)
18286 (plus:P (reg:P SP_REG)
18287 (match_operand:P 0 "const_int_operand")))
18288 (clobber (reg:CC FLAGS_REG))
18289 (clobber (mem:BLK (scratch)))])]
18290 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
18291 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
18292 && !ix86_using_red_zone ()"
18293 [(clobber (match_dup 1))
18294 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18295 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18296 (clobber (mem:BLK (scratch)))])])
18298 ;; Convert esp subtractions to push.
18300 [(match_scratch:W 1 "r")
18301 (parallel [(set (reg:P SP_REG)
18302 (plus:P (reg:P SP_REG)
18303 (match_operand:P 0 "const_int_operand")))
18304 (clobber (reg:CC FLAGS_REG))])]
18305 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18306 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
18307 && !ix86_using_red_zone ()"
18308 [(clobber (match_dup 1))
18309 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
18312 [(match_scratch:W 1 "r")
18313 (parallel [(set (reg:P SP_REG)
18314 (plus:P (reg:P SP_REG)
18315 (match_operand:P 0 "const_int_operand")))
18316 (clobber (reg:CC FLAGS_REG))])]
18317 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
18318 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
18319 && !ix86_using_red_zone ()"
18320 [(clobber (match_dup 1))
18321 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18322 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
18324 ;; Convert epilogue deallocator to pop.
18326 [(match_scratch:W 1 "r")
18327 (parallel [(set (reg:P SP_REG)
18328 (plus:P (reg:P SP_REG)
18329 (match_operand:P 0 "const_int_operand")))
18330 (clobber (reg:CC FLAGS_REG))
18331 (clobber (mem:BLK (scratch)))])]
18332 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
18333 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
18334 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18335 (clobber (mem:BLK (scratch)))])])
18337 ;; Two pops case is tricky, since pop causes dependency
18338 ;; on destination register. We use two registers if available.
18340 [(match_scratch:W 1 "r")
18341 (match_scratch:W 2 "r")
18342 (parallel [(set (reg:P SP_REG)
18343 (plus:P (reg:P SP_REG)
18344 (match_operand:P 0 "const_int_operand")))
18345 (clobber (reg:CC FLAGS_REG))
18346 (clobber (mem:BLK (scratch)))])]
18347 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
18348 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18349 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18350 (clobber (mem:BLK (scratch)))])
18351 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
18354 [(match_scratch:W 1 "r")
18355 (parallel [(set (reg:P SP_REG)
18356 (plus:P (reg:P SP_REG)
18357 (match_operand:P 0 "const_int_operand")))
18358 (clobber (reg:CC FLAGS_REG))
18359 (clobber (mem:BLK (scratch)))])]
18360 "optimize_insn_for_size_p ()
18361 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18362 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18363 (clobber (mem:BLK (scratch)))])
18364 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18366 ;; Convert esp additions to pop.
18368 [(match_scratch:W 1 "r")
18369 (parallel [(set (reg:P SP_REG)
18370 (plus:P (reg:P SP_REG)
18371 (match_operand:P 0 "const_int_operand")))
18372 (clobber (reg:CC FLAGS_REG))])]
18373 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
18374 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18376 ;; Two pops case is tricky, since pop causes dependency
18377 ;; on destination register. We use two registers if available.
18379 [(match_scratch:W 1 "r")
18380 (match_scratch:W 2 "r")
18381 (parallel [(set (reg:P SP_REG)
18382 (plus:P (reg:P SP_REG)
18383 (match_operand:P 0 "const_int_operand")))
18384 (clobber (reg:CC FLAGS_REG))])]
18385 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18386 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18387 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
18390 [(match_scratch:W 1 "r")
18391 (parallel [(set (reg:P SP_REG)
18392 (plus:P (reg:P SP_REG)
18393 (match_operand:P 0 "const_int_operand")))
18394 (clobber (reg:CC FLAGS_REG))])]
18395 "optimize_insn_for_size_p ()
18396 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18397 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18398 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18400 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18401 ;; required and register dies. Similarly for 128 to -128.
18403 [(set (match_operand 0 "flags_reg_operand")
18404 (match_operator 1 "compare_operator"
18405 [(match_operand 2 "register_operand")
18406 (match_operand 3 "const_int_operand")]))]
18407 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
18408 && incdec_operand (operands[3], GET_MODE (operands[3])))
18409 || (!TARGET_FUSE_CMP_AND_BRANCH
18410 && INTVAL (operands[3]) == 128))
18411 && ix86_match_ccmode (insn, CCGCmode)
18412 && peep2_reg_dead_p (1, operands[2])"
18413 [(parallel [(set (match_dup 0)
18414 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18415 (clobber (match_dup 2))])])
18417 ;; Convert imul by three, five and nine into lea
18420 [(set (match_operand:SWI48 0 "register_operand")
18421 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
18422 (match_operand:SWI48 2 "const359_operand")))
18423 (clobber (reg:CC FLAGS_REG))])]
18424 "!TARGET_PARTIAL_REG_STALL
18425 || <MODE>mode == SImode
18426 || optimize_function_for_size_p (cfun)"
18427 [(set (match_dup 0)
18428 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
18430 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18434 [(set (match_operand:SWI48 0 "register_operand")
18435 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
18436 (match_operand:SWI48 2 "const359_operand")))
18437 (clobber (reg:CC FLAGS_REG))])]
18438 "optimize_insn_for_speed_p ()
18439 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
18440 [(set (match_dup 0) (match_dup 1))
18442 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
18444 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18446 ;; imul $32bit_imm, mem, reg is vector decoded, while
18447 ;; imul $32bit_imm, reg, reg is direct decoded.
18449 [(match_scratch:SWI48 3 "r")
18450 (parallel [(set (match_operand:SWI48 0 "register_operand")
18451 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
18452 (match_operand:SWI48 2 "immediate_operand")))
18453 (clobber (reg:CC FLAGS_REG))])]
18454 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18455 && !satisfies_constraint_K (operands[2])"
18456 [(set (match_dup 3) (match_dup 1))
18457 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
18458 (clobber (reg:CC FLAGS_REG))])])
18461 [(match_scratch:SI 3 "r")
18462 (parallel [(set (match_operand:DI 0 "register_operand")
18464 (mult:SI (match_operand:SI 1 "memory_operand")
18465 (match_operand:SI 2 "immediate_operand"))))
18466 (clobber (reg:CC FLAGS_REG))])]
18468 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18469 && !satisfies_constraint_K (operands[2])"
18470 [(set (match_dup 3) (match_dup 1))
18471 (parallel [(set (match_dup 0)
18472 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18473 (clobber (reg:CC FLAGS_REG))])])
18475 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18476 ;; Convert it into imul reg, reg
18477 ;; It would be better to force assembler to encode instruction using long
18478 ;; immediate, but there is apparently no way to do so.
18480 [(parallel [(set (match_operand:SWI248 0 "register_operand")
18482 (match_operand:SWI248 1 "nonimmediate_operand")
18483 (match_operand:SWI248 2 "const_int_operand")))
18484 (clobber (reg:CC FLAGS_REG))])
18485 (match_scratch:SWI248 3 "r")]
18486 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18487 && satisfies_constraint_K (operands[2])"
18488 [(set (match_dup 3) (match_dup 2))
18489 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
18490 (clobber (reg:CC FLAGS_REG))])]
18492 if (!rtx_equal_p (operands[0], operands[1]))
18493 emit_move_insn (operands[0], operands[1]);
18496 ;; After splitting up read-modify operations, array accesses with memory
18497 ;; operands might end up in form:
18499 ;; movl 4(%esp), %edx
18501 ;; instead of pre-splitting:
18503 ;; addl 4(%esp), %eax
18505 ;; movl 4(%esp), %edx
18506 ;; leal (%edx,%eax,4), %eax
18509 [(match_scratch:W 5 "r")
18510 (parallel [(set (match_operand 0 "register_operand")
18511 (ashift (match_operand 1 "register_operand")
18512 (match_operand 2 "const_int_operand")))
18513 (clobber (reg:CC FLAGS_REG))])
18514 (parallel [(set (match_operand 3 "register_operand")
18515 (plus (match_dup 0)
18516 (match_operand 4 "x86_64_general_operand")))
18517 (clobber (reg:CC FLAGS_REG))])]
18518 "IN_RANGE (INTVAL (operands[2]), 1, 3)
18519 /* Validate MODE for lea. */
18520 && ((!TARGET_PARTIAL_REG_STALL
18521 && (GET_MODE (operands[0]) == QImode
18522 || GET_MODE (operands[0]) == HImode))
18523 || GET_MODE (operands[0]) == SImode
18524 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18525 && (rtx_equal_p (operands[0], operands[3])
18526 || peep2_reg_dead_p (2, operands[0]))
18527 /* We reorder load and the shift. */
18528 && !reg_overlap_mentioned_p (operands[0], operands[4])"
18529 [(set (match_dup 5) (match_dup 4))
18530 (set (match_dup 0) (match_dup 1))]
18532 machine_mode op1mode = GET_MODE (operands[1]);
18533 machine_mode mode = op1mode == DImode ? DImode : SImode;
18534 int scale = 1 << INTVAL (operands[2]);
18535 rtx index = gen_lowpart (word_mode, operands[1]);
18536 rtx base = gen_lowpart (word_mode, operands[5]);
18537 rtx dest = gen_lowpart (mode, operands[3]);
18539 operands[1] = gen_rtx_PLUS (word_mode, base,
18540 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
18541 if (mode != word_mode)
18542 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18544 operands[5] = base;
18545 if (op1mode != word_mode)
18546 operands[5] = gen_lowpart (op1mode, operands[5]);
18548 operands[0] = dest;
18551 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18552 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18553 ;; caught for use by garbage collectors and the like. Using an insn that
18554 ;; maps to SIGILL makes it more likely the program will rightfully die.
18555 ;; Keeping with tradition, "6" is in honor of #UD.
18556 (define_insn "trap"
18557 [(trap_if (const_int 1) (const_int 6))]
18560 #ifdef HAVE_AS_IX86_UD2
18563 return ASM_SHORT "0x0b0f";
18566 [(set_attr "length" "2")])
18568 (define_expand "prefetch"
18569 [(prefetch (match_operand 0 "address_operand")
18570 (match_operand:SI 1 "const_int_operand")
18571 (match_operand:SI 2 "const_int_operand"))]
18572 "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18574 bool write = INTVAL (operands[1]) != 0;
18575 int locality = INTVAL (operands[2]);
18577 gcc_assert (IN_RANGE (locality, 0, 3));
18579 /* Use 3dNOW prefetch in case we are asking for write prefetch not
18580 supported by SSE counterpart or the SSE prefetch is not available
18581 (K6 machines). Otherwise use SSE prefetch as it allows specifying
18583 if (TARGET_PREFETCHWT1 && write && locality <= 2)
18584 operands[2] = const2_rtx;
18585 else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
18586 operands[2] = GEN_INT (3);
18588 operands[1] = const0_rtx;
18591 (define_insn "*prefetch_sse"
18592 [(prefetch (match_operand 0 "address_operand" "p")
18594 (match_operand:SI 1 "const_int_operand"))]
18595 "TARGET_PREFETCH_SSE"
18597 static const char * const patterns[4] = {
18598 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18601 int locality = INTVAL (operands[1]);
18602 gcc_assert (IN_RANGE (locality, 0, 3));
18604 return patterns[locality];
18606 [(set_attr "type" "sse")
18607 (set_attr "atom_sse_attr" "prefetch")
18608 (set (attr "length_address")
18609 (symbol_ref "memory_address_length (operands[0], false)"))
18610 (set_attr "memory" "none")])
18612 (define_insn "*prefetch_3dnow"
18613 [(prefetch (match_operand 0 "address_operand" "p")
18614 (match_operand:SI 1 "const_int_operand" "n")
18618 if (INTVAL (operands[1]) == 0)
18619 return "prefetch\t%a0";
18621 return "prefetchw\t%a0";
18623 [(set_attr "type" "mmx")
18624 (set (attr "length_address")
18625 (symbol_ref "memory_address_length (operands[0], false)"))
18626 (set_attr "memory" "none")])
18628 (define_insn "*prefetch_prefetchwt1"
18629 [(prefetch (match_operand 0 "address_operand" "p")
18632 "TARGET_PREFETCHWT1"
18633 "prefetchwt1\t%a0";
18634 [(set_attr "type" "sse")
18635 (set (attr "length_address")
18636 (symbol_ref "memory_address_length (operands[0], false)"))
18637 (set_attr "memory" "none")])
18639 (define_expand "stack_protect_set"
18640 [(match_operand 0 "memory_operand")
18641 (match_operand 1 "memory_operand")]
18642 "TARGET_SSP_TLS_GUARD"
18644 rtx (*insn)(rtx, rtx);
18646 #ifdef TARGET_THREAD_SSP_OFFSET
18647 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18648 insn = (TARGET_LP64
18649 ? gen_stack_tls_protect_set_di
18650 : gen_stack_tls_protect_set_si);
18652 insn = (TARGET_LP64
18653 ? gen_stack_protect_set_di
18654 : gen_stack_protect_set_si);
18657 emit_insn (insn (operands[0], operands[1]));
18661 (define_insn "stack_protect_set_<mode>"
18662 [(set (match_operand:PTR 0 "memory_operand" "=m")
18663 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18665 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18666 (clobber (reg:CC FLAGS_REG))]
18667 "TARGET_SSP_TLS_GUARD"
18668 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18669 [(set_attr "type" "multi")])
18671 (define_insn "stack_tls_protect_set_<mode>"
18672 [(set (match_operand:PTR 0 "memory_operand" "=m")
18673 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
18674 UNSPEC_SP_TLS_SET))
18675 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18676 (clobber (reg:CC FLAGS_REG))]
18678 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18679 [(set_attr "type" "multi")])
18681 (define_expand "stack_protect_test"
18682 [(match_operand 0 "memory_operand")
18683 (match_operand 1 "memory_operand")
18685 "TARGET_SSP_TLS_GUARD"
18687 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18689 rtx (*insn)(rtx, rtx, rtx);
18691 #ifdef TARGET_THREAD_SSP_OFFSET
18692 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18693 insn = (TARGET_LP64
18694 ? gen_stack_tls_protect_test_di
18695 : gen_stack_tls_protect_test_si);
18697 insn = (TARGET_LP64
18698 ? gen_stack_protect_test_di
18699 : gen_stack_protect_test_si);
18702 emit_insn (insn (flags, operands[0], operands[1]));
18704 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18705 flags, const0_rtx, operands[2]));
18709 (define_insn "stack_protect_test_<mode>"
18710 [(set (match_operand:CCZ 0 "flags_reg_operand")
18711 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18712 (match_operand:PTR 2 "memory_operand" "m")]
18714 (clobber (match_scratch:PTR 3 "=&r"))]
18715 "TARGET_SSP_TLS_GUARD"
18716 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18717 [(set_attr "type" "multi")])
18719 (define_insn "stack_tls_protect_test_<mode>"
18720 [(set (match_operand:CCZ 0 "flags_reg_operand")
18721 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18722 (match_operand:PTR 2 "const_int_operand" "i")]
18723 UNSPEC_SP_TLS_TEST))
18724 (clobber (match_scratch:PTR 3 "=r"))]
18726 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18727 [(set_attr "type" "multi")])
18729 (define_insn "sse4_2_crc32<mode>"
18730 [(set (match_operand:SI 0 "register_operand" "=r")
18732 [(match_operand:SI 1 "register_operand" "0")
18733 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18735 "TARGET_SSE4_2 || TARGET_CRC32"
18736 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18737 [(set_attr "type" "sselog1")
18738 (set_attr "prefix_rep" "1")
18739 (set_attr "prefix_extra" "1")
18740 (set (attr "prefix_data16")
18741 (if_then_else (match_operand:HI 2)
18743 (const_string "*")))
18744 (set (attr "prefix_rex")
18745 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18747 (const_string "*")))
18748 (set_attr "mode" "SI")])
18750 (define_insn "sse4_2_crc32di"
18751 [(set (match_operand:DI 0 "register_operand" "=r")
18753 [(match_operand:DI 1 "register_operand" "0")
18754 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18756 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18757 "crc32{q}\t{%2, %0|%0, %2}"
18758 [(set_attr "type" "sselog1")
18759 (set_attr "prefix_rep" "1")
18760 (set_attr "prefix_extra" "1")
18761 (set_attr "mode" "DI")])
18763 (define_insn "rdpmc"
18764 [(set (match_operand:DI 0 "register_operand" "=A")
18765 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18769 [(set_attr "type" "other")
18770 (set_attr "length" "2")])
18772 (define_insn "rdpmc_rex64"
18773 [(set (match_operand:DI 0 "register_operand" "=a")
18774 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18776 (set (match_operand:DI 1 "register_operand" "=d")
18777 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18780 [(set_attr "type" "other")
18781 (set_attr "length" "2")])
18783 (define_insn "rdtsc"
18784 [(set (match_operand:DI 0 "register_operand" "=A")
18785 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18788 [(set_attr "type" "other")
18789 (set_attr "length" "2")])
18791 (define_insn "rdtsc_rex64"
18792 [(set (match_operand:DI 0 "register_operand" "=a")
18793 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18794 (set (match_operand:DI 1 "register_operand" "=d")
18795 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18798 [(set_attr "type" "other")
18799 (set_attr "length" "2")])
18801 (define_insn "rdtscp"
18802 [(set (match_operand:DI 0 "register_operand" "=A")
18803 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18804 (set (match_operand:SI 1 "register_operand" "=c")
18805 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18808 [(set_attr "type" "other")
18809 (set_attr "length" "3")])
18811 (define_insn "rdtscp_rex64"
18812 [(set (match_operand:DI 0 "register_operand" "=a")
18813 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18814 (set (match_operand:DI 1 "register_operand" "=d")
18815 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18816 (set (match_operand:SI 2 "register_operand" "=c")
18817 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18820 [(set_attr "type" "other")
18821 (set_attr "length" "3")])
18823 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18825 ;; FXSR, XSAVE and XSAVEOPT instructions
18827 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18829 (define_insn "fxsave"
18830 [(set (match_operand:BLK 0 "memory_operand" "=m")
18831 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18834 [(set_attr "type" "other")
18835 (set_attr "memory" "store")
18836 (set (attr "length")
18837 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18839 (define_insn "fxsave64"
18840 [(set (match_operand:BLK 0 "memory_operand" "=m")
18841 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18842 "TARGET_64BIT && TARGET_FXSR"
18844 [(set_attr "type" "other")
18845 (set_attr "memory" "store")
18846 (set (attr "length")
18847 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18849 (define_insn "fxrstor"
18850 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18854 [(set_attr "type" "other")
18855 (set_attr "memory" "load")
18856 (set (attr "length")
18857 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18859 (define_insn "fxrstor64"
18860 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18861 UNSPECV_FXRSTOR64)]
18862 "TARGET_64BIT && TARGET_FXSR"
18864 [(set_attr "type" "other")
18865 (set_attr "memory" "load")
18866 (set (attr "length")
18867 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18869 (define_int_iterator ANY_XSAVE
18871 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18872 (UNSPECV_XSAVEC "TARGET_XSAVEC")
18873 (UNSPECV_XSAVES "TARGET_XSAVES")])
18875 (define_int_iterator ANY_XSAVE64
18877 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18878 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18879 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18881 (define_int_attr xsave
18882 [(UNSPECV_XSAVE "xsave")
18883 (UNSPECV_XSAVE64 "xsave64")
18884 (UNSPECV_XSAVEOPT "xsaveopt")
18885 (UNSPECV_XSAVEOPT64 "xsaveopt64")
18886 (UNSPECV_XSAVEC "xsavec")
18887 (UNSPECV_XSAVEC64 "xsavec64")
18888 (UNSPECV_XSAVES "xsaves")
18889 (UNSPECV_XSAVES64 "xsaves64")])
18891 (define_int_iterator ANY_XRSTOR
18893 (UNSPECV_XRSTORS "TARGET_XSAVES")])
18895 (define_int_iterator ANY_XRSTOR64
18897 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18899 (define_int_attr xrstor
18900 [(UNSPECV_XRSTOR "xrstor")
18901 (UNSPECV_XRSTOR64 "xrstor")
18902 (UNSPECV_XRSTORS "xrstors")
18903 (UNSPECV_XRSTORS64 "xrstors")])
18905 (define_insn "<xsave>"
18906 [(set (match_operand:BLK 0 "memory_operand" "=m")
18907 (unspec_volatile:BLK
18908 [(match_operand:DI 1 "register_operand" "A")]
18910 "!TARGET_64BIT && TARGET_XSAVE"
18912 [(set_attr "type" "other")
18913 (set_attr "memory" "store")
18914 (set (attr "length")
18915 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18917 (define_insn "<xsave>_rex64"
18918 [(set (match_operand:BLK 0 "memory_operand" "=m")
18919 (unspec_volatile:BLK
18920 [(match_operand:SI 1 "register_operand" "a")
18921 (match_operand:SI 2 "register_operand" "d")]
18923 "TARGET_64BIT && TARGET_XSAVE"
18925 [(set_attr "type" "other")
18926 (set_attr "memory" "store")
18927 (set (attr "length")
18928 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18930 (define_insn "<xsave>"
18931 [(set (match_operand:BLK 0 "memory_operand" "=m")
18932 (unspec_volatile:BLK
18933 [(match_operand:SI 1 "register_operand" "a")
18934 (match_operand:SI 2 "register_operand" "d")]
18936 "TARGET_64BIT && TARGET_XSAVE"
18938 [(set_attr "type" "other")
18939 (set_attr "memory" "store")
18940 (set (attr "length")
18941 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18943 (define_insn "<xrstor>"
18944 [(unspec_volatile:BLK
18945 [(match_operand:BLK 0 "memory_operand" "m")
18946 (match_operand:DI 1 "register_operand" "A")]
18948 "!TARGET_64BIT && TARGET_XSAVE"
18950 [(set_attr "type" "other")
18951 (set_attr "memory" "load")
18952 (set (attr "length")
18953 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18955 (define_insn "<xrstor>_rex64"
18956 [(unspec_volatile:BLK
18957 [(match_operand:BLK 0 "memory_operand" "m")
18958 (match_operand:SI 1 "register_operand" "a")
18959 (match_operand:SI 2 "register_operand" "d")]
18961 "TARGET_64BIT && TARGET_XSAVE"
18963 [(set_attr "type" "other")
18964 (set_attr "memory" "load")
18965 (set (attr "length")
18966 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18968 (define_insn "<xrstor>64"
18969 [(unspec_volatile:BLK
18970 [(match_operand:BLK 0 "memory_operand" "m")
18971 (match_operand:SI 1 "register_operand" "a")
18972 (match_operand:SI 2 "register_operand" "d")]
18974 "TARGET_64BIT && TARGET_XSAVE"
18976 [(set_attr "type" "other")
18977 (set_attr "memory" "load")
18978 (set (attr "length")
18979 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18981 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18983 ;; Floating-point instructions for atomic compound assignments
18985 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18987 ; Clobber all floating-point registers on environment save and restore
18988 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18989 (define_insn "fnstenv"
18990 [(set (match_operand:BLK 0 "memory_operand" "=m")
18991 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18992 (clobber (reg:HI FPCR_REG))
18993 (clobber (reg:XF ST0_REG))
18994 (clobber (reg:XF ST1_REG))
18995 (clobber (reg:XF ST2_REG))
18996 (clobber (reg:XF ST3_REG))
18997 (clobber (reg:XF ST4_REG))
18998 (clobber (reg:XF ST5_REG))
18999 (clobber (reg:XF ST6_REG))
19000 (clobber (reg:XF ST7_REG))]
19003 [(set_attr "type" "other")
19004 (set_attr "memory" "store")
19005 (set (attr "length")
19006 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19008 (define_insn "fldenv"
19009 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19011 (clobber (reg:CCFP FPSR_REG))
19012 (clobber (reg:HI FPCR_REG))
19013 (clobber (reg:XF ST0_REG))
19014 (clobber (reg:XF ST1_REG))
19015 (clobber (reg:XF ST2_REG))
19016 (clobber (reg:XF ST3_REG))
19017 (clobber (reg:XF ST4_REG))
19018 (clobber (reg:XF ST5_REG))
19019 (clobber (reg:XF ST6_REG))
19020 (clobber (reg:XF ST7_REG))]
19023 [(set_attr "type" "other")
19024 (set_attr "memory" "load")
19025 (set (attr "length")
19026 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19028 (define_insn "fnstsw"
19029 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
19030 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
19033 [(set_attr "type" "other,other")
19034 (set_attr "memory" "none,store")
19035 (set (attr "length")
19036 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19038 (define_insn "fnclex"
19039 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
19042 [(set_attr "type" "other")
19043 (set_attr "memory" "none")
19044 (set_attr "length" "2")])
19046 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19048 ;; LWP instructions
19050 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19052 (define_expand "lwp_llwpcb"
19053 [(unspec_volatile [(match_operand 0 "register_operand")]
19054 UNSPECV_LLWP_INTRINSIC)]
19057 (define_insn "*lwp_llwpcb<mode>1"
19058 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
19059 UNSPECV_LLWP_INTRINSIC)]
19062 [(set_attr "type" "lwp")
19063 (set_attr "mode" "<MODE>")
19064 (set_attr "length" "5")])
19066 (define_expand "lwp_slwpcb"
19067 [(set (match_operand 0 "register_operand")
19068 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19073 insn = (Pmode == DImode
19075 : gen_lwp_slwpcbsi);
19077 emit_insn (insn (operands[0]));
19081 (define_insn "lwp_slwpcb<mode>"
19082 [(set (match_operand:P 0 "register_operand" "=r")
19083 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19086 [(set_attr "type" "lwp")
19087 (set_attr "mode" "<MODE>")
19088 (set_attr "length" "5")])
19090 (define_expand "lwp_lwpval<mode>3"
19091 [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
19092 (match_operand:SI 2 "nonimmediate_operand")
19093 (match_operand:SI 3 "const_int_operand")]
19094 UNSPECV_LWPVAL_INTRINSIC)]
19096 ;; Avoid unused variable warning.
19097 "(void) operands[0];")
19099 (define_insn "*lwp_lwpval<mode>3_1"
19100 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
19101 (match_operand:SI 1 "nonimmediate_operand" "rm")
19102 (match_operand:SI 2 "const_int_operand" "i")]
19103 UNSPECV_LWPVAL_INTRINSIC)]
19105 "lwpval\t{%2, %1, %0|%0, %1, %2}"
19106 [(set_attr "type" "lwp")
19107 (set_attr "mode" "<MODE>")
19108 (set (attr "length")
19109 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19111 (define_expand "lwp_lwpins<mode>3"
19112 [(set (reg:CCC FLAGS_REG)
19113 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
19114 (match_operand:SI 2 "nonimmediate_operand")
19115 (match_operand:SI 3 "const_int_operand")]
19116 UNSPECV_LWPINS_INTRINSIC))
19117 (set (match_operand:QI 0 "nonimmediate_operand")
19118 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
19121 (define_insn "*lwp_lwpins<mode>3_1"
19122 [(set (reg:CCC FLAGS_REG)
19123 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
19124 (match_operand:SI 1 "nonimmediate_operand" "rm")
19125 (match_operand:SI 2 "const_int_operand" "i")]
19126 UNSPECV_LWPINS_INTRINSIC))]
19128 "lwpins\t{%2, %1, %0|%0, %1, %2}"
19129 [(set_attr "type" "lwp")
19130 (set_attr "mode" "<MODE>")
19131 (set (attr "length")
19132 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19134 (define_int_iterator RDFSGSBASE
19138 (define_int_iterator WRFSGSBASE
19142 (define_int_attr fsgs
19143 [(UNSPECV_RDFSBASE "fs")
19144 (UNSPECV_RDGSBASE "gs")
19145 (UNSPECV_WRFSBASE "fs")
19146 (UNSPECV_WRGSBASE "gs")])
19148 (define_insn "rd<fsgs>base<mode>"
19149 [(set (match_operand:SWI48 0 "register_operand" "=r")
19150 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
19151 "TARGET_64BIT && TARGET_FSGSBASE"
19153 [(set_attr "type" "other")
19154 (set_attr "prefix_extra" "2")])
19156 (define_insn "wr<fsgs>base<mode>"
19157 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
19159 "TARGET_64BIT && TARGET_FSGSBASE"
19161 [(set_attr "type" "other")
19162 (set_attr "prefix_extra" "2")])
19164 (define_insn "rdrand<mode>_1"
19165 [(set (match_operand:SWI248 0 "register_operand" "=r")
19166 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
19167 (set (reg:CCC FLAGS_REG)
19168 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
19171 [(set_attr "type" "other")
19172 (set_attr "prefix_extra" "1")])
19174 (define_insn "rdseed<mode>_1"
19175 [(set (match_operand:SWI248 0 "register_operand" "=r")
19176 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
19177 (set (reg:CCC FLAGS_REG)
19178 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
19181 [(set_attr "type" "other")
19182 (set_attr "prefix_extra" "1")])
19184 (define_expand "pause"
19185 [(set (match_dup 0)
19186 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19189 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
19190 MEM_VOLATILE_P (operands[0]) = 1;
19193 ;; Use "rep; nop", instead of "pause", to support older assemblers.
19194 ;; They have the same encoding.
19195 (define_insn "*pause"
19196 [(set (match_operand:BLK 0)
19197 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19200 [(set_attr "length" "2")
19201 (set_attr "memory" "unknown")])
19203 (define_expand "xbegin"
19204 [(set (match_operand:SI 0 "register_operand")
19205 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
19208 rtx_code_label *label = gen_label_rtx ();
19210 /* xbegin is emitted as jump_insn, so reload won't be able
19211 to reload its operand. Force the value into AX hard register. */
19212 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
19213 emit_move_insn (ax_reg, constm1_rtx);
19215 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
19217 emit_label (label);
19218 LABEL_NUSES (label) = 1;
19220 emit_move_insn (operands[0], ax_reg);
19225 (define_insn "xbegin_1"
19227 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
19229 (label_ref (match_operand 1))
19231 (set (match_operand:SI 0 "register_operand" "+a")
19232 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
19235 [(set_attr "type" "other")
19236 (set_attr "length" "6")])
19238 (define_insn "xend"
19239 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
19242 [(set_attr "type" "other")
19243 (set_attr "length" "3")])
19245 (define_insn "xabort"
19246 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
19250 [(set_attr "type" "other")
19251 (set_attr "length" "3")])
19253 (define_expand "xtest"
19254 [(set (match_operand:QI 0 "register_operand")
19255 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
19258 emit_insn (gen_xtest_1 ());
19260 ix86_expand_setcc (operands[0], NE,
19261 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
19265 (define_insn "xtest_1"
19266 [(set (reg:CCZ FLAGS_REG)
19267 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
19270 [(set_attr "type" "other")
19271 (set_attr "length" "3")])
19273 (define_insn "pcommit"
19274 [(unspec_volatile [(const_int 0)] UNSPECV_PCOMMIT)]
19277 [(set_attr "type" "other")
19278 (set_attr "length" "4")])
19280 (define_insn "clwb"
19281 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
19285 [(set_attr "type" "sse")
19286 (set_attr "atom_sse_attr" "fence")
19287 (set_attr "memory" "unknown")])
19289 (define_insn "clflushopt"
19290 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
19291 UNSPECV_CLFLUSHOPT)]
19292 "TARGET_CLFLUSHOPT"
19294 [(set_attr "type" "sse")
19295 (set_attr "atom_sse_attr" "fence")
19296 (set_attr "memory" "unknown")])
19298 ;; MONITORX and MWAITX
19299 (define_insn "mwaitx"
19300 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
19301 (match_operand:SI 1 "register_operand" "a")
19302 (match_operand:SI 2 "register_operand" "b")]
19305 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
19306 ;; Since 32bit register operands are implicitly zero extended to 64bit,
19307 ;; we only need to set up 32bit registers.
19309 [(set_attr "length" "3")])
19311 (define_insn "monitorx_<mode>"
19312 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
19313 (match_operand:SI 1 "register_operand" "c")
19314 (match_operand:SI 2 "register_operand" "d")]
19317 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
19318 ;; RCX and RDX are used. Since 32bit register operands are implicitly
19319 ;; zero extended to 64bit, we only need to set up 32bit registers.
19321 [(set (attr "length")
19322 (symbol_ref ("(Pmode != word_mode) + 3")))])
19325 (define_insn "clzero_<mode>"
19326 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
19330 [(set_attr "length" "3")
19331 (set_attr "memory" "unknown")])
19333 ;; MPX instructions
19335 (define_expand "<mode>_mk"
19336 [(set (match_operand:BND 0 "register_operand")
19340 [(match_operand:<bnd_ptr> 1 "register_operand")
19341 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
19345 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
19347 UNSPEC_BNDMK_ADDR);
19350 (define_insn "*<mode>_mk"
19351 [(set (match_operand:BND 0 "register_operand" "=w")
19353 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19355 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
19356 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
19357 UNSPEC_BNDMK_ADDR)])]
19360 "bndmk\t{%3, %0|%0, %3}"
19361 [(set_attr "type" "mpxmk")])
19363 (define_expand "mov<mode>"
19364 [(set (match_operand:BND 0 "general_operand")
19365 (match_operand:BND 1 "general_operand"))]
19367 "ix86_expand_move (<MODE>mode, operands); DONE;")
19369 (define_insn "*mov<mode>_internal_mpx"
19370 [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
19371 (match_operand:BND 1 "general_operand" "wm,w"))]
19373 "bndmov\t{%1, %0|%0, %1}"
19374 [(set_attr "type" "mpxmov")])
19376 (define_expand "<mode>_<bndcheck>"
19379 [(match_operand:BND 0 "register_operand")
19380 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
19382 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
19385 operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
19386 MEM_VOLATILE_P (operands[2]) = 1;
19389 (define_insn "*<mode>_<bndcheck>"
19391 [(match_operand:BND 0 "register_operand" "w")
19392 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
19393 (set (match_operand:BLK 2 "bnd_mem_operator")
19394 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))]
19396 "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
19397 [(set_attr "type" "mpxchk")])
19399 (define_expand "<mode>_ldx"
19401 [(set (match_operand:BND 0 "register_operand")
19405 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
19406 (match_operand:<bnd_ptr> 2 "register_operand")]))]
19408 (use (mem:BLK (match_dup 1)))])]
19411 /* Avoid registers which cannot be used as index. */
19412 if (!index_register_operand (operands[2], Pmode))
19413 operands[2] = copy_addr_to_reg (operands[2]);
19415 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
19417 UNSPEC_BNDLDX_ADDR);
19420 (define_insn "*<mode>_ldx"
19421 [(set (match_operand:BND 0 "register_operand" "=w")
19423 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19425 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
19426 (match_operand:<bnd_ptr> 2 "register_operand" "l")]
19427 UNSPEC_BNDLDX_ADDR)])]
19429 (use (mem:BLK (match_dup 1)))]
19431 "bndldx\t{%3, %0|%0, %3}"
19432 [(set_attr "type" "mpxld")])
19434 (define_expand "<mode>_stx"
19439 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
19440 (match_operand:<bnd_ptr> 1 "register_operand")]))
19441 (match_operand:BND 2 "register_operand")]
19444 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
19447 /* Avoid registers which cannot be used as index. */
19448 if (!index_register_operand (operands[1], Pmode))
19449 operands[1] = copy_addr_to_reg (operands[1]);
19451 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
19453 UNSPEC_BNDLDX_ADDR);
19454 operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
19455 MEM_VOLATILE_P (operands[4]) = 1;
19458 (define_insn "*<mode>_stx"
19460 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19462 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
19463 (match_operand:<bnd_ptr> 1 "register_operand" "l")]
19464 UNSPEC_BNDLDX_ADDR)])
19465 (match_operand:BND 2 "register_operand" "w")]
19467 (set (match_operand:BLK 4 "bnd_mem_operator")
19468 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))]
19470 "bndstx\t{%2, %3|%3, %2}"
19471 [(set_attr "type" "mpxst")])
19473 (define_insn "move_size_reloc_<mode>"
19474 [(set (match_operand:SWI48 0 "register_operand" "=r")
19476 [(match_operand:SWI48 1 "symbol_operand")]
19480 if (x86_64_immediate_size_operand (operands[1], VOIDmode))
19481 return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
19483 return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
19485 [(set_attr "type" "imov")
19486 (set_attr "mode" "<MODE>")])
19488 ;; RDPKRU and WRPKRU
19490 (define_expand "rdpkru"
19492 [(set (match_operand:SI 0 "register_operand")
19493 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
19494 (set (match_dup 2) (const_int 0))])]
19497 operands[1] = force_reg (SImode, const0_rtx);
19498 operands[2] = gen_reg_rtx (SImode);
19501 (define_insn "*rdpkru"
19502 [(set (match_operand:SI 0 "register_operand" "=a")
19503 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
19505 (set (match_operand:SI 1 "register_operand" "=d")
19509 [(set_attr "type" "other")])
19511 (define_expand "wrpkru"
19512 [(unspec_volatile:SI
19513 [(match_operand:SI 0 "register_operand")
19514 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
19517 operands[1] = force_reg (SImode, const0_rtx);
19518 operands[2] = force_reg (SImode, const0_rtx);
19521 (define_insn "*wrpkru"
19522 [(unspec_volatile:SI
19523 [(match_operand:SI 0 "register_operand" "a")
19524 (match_operand:SI 1 "register_operand" "d")
19525 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
19528 [(set_attr "type" "other")])
19532 (include "sync.md")