1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2017 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
4 ;; x86_64 support added by Jan Hubicka
6 ;; This file is part of GCC.
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>. */
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; The special asm out single letter directives following a '%' are:
28 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29 ;; C -- print opcode suffix for set/cmov insn.
30 ;; c -- like C, but print reversed condition
31 ;; F,f -- likewise, but for floating-point.
32 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
34 ;; R -- print the prefix for register names.
35 ;; z -- print the opcode suffix for the size of the current operand.
36 ;; Z -- likewise, with special suffixes for x87 instructions.
37 ;; * -- print a star (in certain assembler syntax)
38 ;; A -- print an absolute memory reference.
39 ;; E -- print address with DImode register names if TARGET_64BIT.
40 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41 ;; s -- print a shift double count, followed by the assemblers argument
43 ;; b -- print the QImode name of the register for the indicated operand.
44 ;; %b0 would print %al if operands[0] is reg 0.
45 ;; w -- likewise, print the HImode name of the register.
46 ;; k -- likewise, print the SImode name of the register.
47 ;; q -- likewise, print the DImode name of the register.
48 ;; x -- likewise, print the V4SFmode name of the register.
49 ;; t -- likewise, print the V8SFmode name of the register.
50 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; y -- print "st(0)" instead of "st" as a register.
52 ;; d -- print duplicated register operand for AVX instruction.
53 ;; D -- print condition for SSE cmp instruction.
54 ;; P -- if PIC, print an @PLT suffix.
55 ;; p -- print raw symbol name.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; K -- print HLE lock prefix
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
65 ;; ! -- print MPX prefix for jxx/call/ret instructions if required.
67 (define_c_enum "unspec" [
68 ;; Relocation specifiers
79 UNSPEC_MACHOPIC_OFFSET
88 UNSPEC_MEMORY_BLOCKAGE
98 ;; Other random patterns
106 UNSPEC_LD_MPIC ; load_macho_picbase
108 UNSPEC_DIV_ALREADY_SPLIT
114 UNSPEC_INSN_FALSE_DEP
116 ;; For SSE/MMX support:
124 ;; Generic math support
126 UNSPEC_IEEE_MIN ; not commutative
127 UNSPEC_IEEE_MAX ; not commutative
129 ;; x87 Floating point
145 UNSPEC_FRNDINT_MASK_PM
149 ;; x87 Double output FP
174 ;; For LZCNT suppoprt
196 UNSPEC_INTERRUPT_RETURN
199 (define_c_enum "unspecv" [
203 UNSPECV_PROBE_STACK_RANGE
206 UNSPECV_SPLIT_STACK_RETURN
212 UNSPECV_LLWP_INTRINSIC
213 UNSPECV_SLWP_INTRINSIC
214 UNSPECV_LWPVAL_INTRINSIC
215 UNSPECV_LWPINS_INTRINSIC
239 ;; For atomic compound assignments.
245 ;; For RDRAND support
248 ;; For RDSEED support
262 ;; For CLFLUSHOPT support
265 ;; For MONITORX and MWAITX support
269 ;; For CLZERO support
272 ;; 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,x64_avx512bw"
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" "x64_avx512bw")
816 (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
817 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
818 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
819 (eq_attr "isa" "sse2_noavx")
820 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
821 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
822 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
823 (eq_attr "isa" "sse4_noavx")
824 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
825 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
826 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
827 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
828 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
829 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
830 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
831 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
832 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
833 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
834 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
835 (eq_attr "isa" "fma_avx512f")
836 (symbol_ref "TARGET_FMA || TARGET_AVX512F")
837 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
838 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
839 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
840 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
841 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
842 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
846 (define_attr "preferred_for_size" "" (const_int 1))
847 (define_attr "preferred_for_speed" "" (const_int 1))
849 ;; Describe a user's asm statement.
850 (define_asm_attributes
851 [(set_attr "length" "128")
852 (set_attr "type" "multi")])
854 (define_code_iterator plusminus [plus minus])
856 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
858 (define_code_iterator multdiv [mult div])
860 ;; Base name for define_insn
861 (define_code_attr plusminus_insn
862 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
863 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
865 ;; Base name for insn mnemonic.
866 (define_code_attr plusminus_mnemonic
867 [(plus "add") (ss_plus "adds") (us_plus "addus")
868 (minus "sub") (ss_minus "subs") (us_minus "subus")])
869 (define_code_attr multdiv_mnemonic
870 [(mult "mul") (div "div")])
872 ;; Mark commutative operators as such in constraints.
873 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
874 (minus "") (ss_minus "") (us_minus "")])
876 ;; Mapping of max and min
877 (define_code_iterator maxmin [smax smin umax umin])
879 ;; Mapping of signed max and min
880 (define_code_iterator smaxmin [smax smin])
882 ;; Mapping of unsigned max and min
883 (define_code_iterator umaxmin [umax umin])
885 ;; Base name for integer and FP insn mnemonic
886 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
887 (umax "maxu") (umin "minu")])
888 (define_code_attr maxmin_float [(smax "max") (smin "min")])
890 (define_int_iterator IEEE_MAXMIN
894 (define_int_attr ieee_maxmin
895 [(UNSPEC_IEEE_MAX "max")
896 (UNSPEC_IEEE_MIN "min")])
898 ;; Mapping of logic operators
899 (define_code_iterator any_logic [and ior xor])
900 (define_code_iterator any_or [ior xor])
901 (define_code_iterator fpint_logic [and xor])
903 ;; Base name for insn mnemonic.
904 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
906 ;; Mapping of logic-shift operators
907 (define_code_iterator any_lshift [ashift lshiftrt])
909 ;; Mapping of shift-right operators
910 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
912 ;; Mapping of all shift operators
913 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
915 ;; Base name for define_insn
916 (define_code_attr shift_insn
917 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
919 ;; Base name for insn mnemonic.
920 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
921 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
923 ;; Mapping of rotate operators
924 (define_code_iterator any_rotate [rotate rotatert])
926 ;; Base name for define_insn
927 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
929 ;; Base name for insn mnemonic.
930 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
932 ;; Mapping of abs neg operators
933 (define_code_iterator absneg [abs neg])
935 ;; Base name for x87 insn mnemonic.
936 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
938 ;; Used in signed and unsigned widening multiplications.
939 (define_code_iterator any_extend [sign_extend zero_extend])
941 ;; Prefix for insn menmonic.
942 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
944 ;; Prefix for define_insn
945 (define_code_attr u [(sign_extend "") (zero_extend "u")])
946 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
947 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
949 ;; Used in signed and unsigned truncations.
950 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
951 ;; Instruction suffix for truncations.
952 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
954 ;; Used in signed and unsigned fix.
955 (define_code_iterator any_fix [fix unsigned_fix])
956 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
958 ;; Used in signed and unsigned float.
959 (define_code_iterator any_float [float unsigned_float])
960 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
962 ;; All integer modes.
963 (define_mode_iterator SWI1248x [QI HI SI DI])
965 ;; All integer modes without QImode.
966 (define_mode_iterator SWI248x [HI SI DI])
968 ;; All integer modes without QImode and HImode.
969 (define_mode_iterator SWI48x [SI DI])
971 ;; All integer modes without SImode and DImode.
972 (define_mode_iterator SWI12 [QI HI])
974 ;; All integer modes without DImode.
975 (define_mode_iterator SWI124 [QI HI SI])
977 ;; All integer modes without QImode and DImode.
978 (define_mode_iterator SWI24 [HI SI])
980 ;; Single word integer modes.
981 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
983 ;; Single word integer modes without QImode.
984 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
986 ;; Single word integer modes without QImode and HImode.
987 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
989 ;; All math-dependant single and double word integer modes.
990 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
991 (HI "TARGET_HIMODE_MATH")
992 SI DI (TI "TARGET_64BIT")])
994 ;; Math-dependant single word integer modes.
995 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
996 (HI "TARGET_HIMODE_MATH")
997 SI (DI "TARGET_64BIT")])
999 ;; Math-dependant integer modes without DImode.
1000 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1001 (HI "TARGET_HIMODE_MATH")
1004 ;; Math-dependant integer modes with DImode.
1005 (define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH")
1006 (HI "TARGET_HIMODE_MATH")
1007 SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")])
1009 ;; Math-dependant single word integer modes without QImode.
1010 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1011 SI (DI "TARGET_64BIT")])
1013 ;; Double word integer modes.
1014 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1015 (TI "TARGET_64BIT")])
1017 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1018 ;; compile time constant, it is faster to use <MODE_SIZE> than
1019 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1020 ;; command line options just use GET_MODE_SIZE macro.
1021 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1022 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1023 (V16QI "16") (V32QI "32") (V64QI "64")
1024 (V8HI "16") (V16HI "32") (V32HI "64")
1025 (V4SI "16") (V8SI "32") (V16SI "64")
1026 (V2DI "16") (V4DI "32") (V8DI "64")
1027 (V1TI "16") (V2TI "32") (V4TI "64")
1028 (V2DF "16") (V4DF "32") (V8DF "64")
1029 (V4SF "16") (V8SF "32") (V16SF "64")])
1031 ;; Double word integer modes as mode attribute.
1032 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1033 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1035 ;; LEA mode corresponding to an integer mode
1036 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1038 ;; Half mode for double word integer modes.
1039 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1040 (DI "TARGET_64BIT")])
1043 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1044 (BND64 "TARGET_LP64")])
1046 ;; Pointer mode corresponding to bound mode.
1047 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1050 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1053 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1055 (UNSPEC_BNDCN "cn")])
1057 ;; Instruction suffix for integer modes.
1058 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1060 ;; Instruction suffix for masks.
1061 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1063 ;; Pointer size prefix for integer modes (Intel asm dialect)
1064 (define_mode_attr iptrsize [(QI "BYTE")
1069 ;; Register class for integer modes.
1070 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1072 ;; Immediate operand constraint for integer modes.
1073 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1075 ;; General operand constraint for word modes.
1076 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1078 ;; Immediate operand constraint for double integer modes.
1079 (define_mode_attr di [(SI "nF") (DI "Wd")])
1081 ;; Immediate operand constraint for shifts.
1082 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1084 ;; Print register name in the specified mode.
1085 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1087 ;; General operand predicate for integer modes.
1088 (define_mode_attr general_operand
1089 [(QI "general_operand")
1090 (HI "general_operand")
1091 (SI "x86_64_general_operand")
1092 (DI "x86_64_general_operand")
1093 (TI "x86_64_general_operand")])
1095 ;; General operand predicate for integer modes, where for TImode
1096 ;; we need both words of the operand to be general operands.
1097 (define_mode_attr general_hilo_operand
1098 [(QI "general_operand")
1099 (HI "general_operand")
1100 (SI "x86_64_general_operand")
1101 (DI "x86_64_general_operand")
1102 (TI "x86_64_hilo_general_operand")])
1104 ;; General sign extend operand predicate for integer modes,
1105 ;; which disallows VOIDmode operands and thus it is suitable
1106 ;; for use inside sign_extend.
1107 (define_mode_attr general_sext_operand
1108 [(QI "sext_operand")
1110 (SI "x86_64_sext_operand")
1111 (DI "x86_64_sext_operand")])
1113 ;; General sign/zero extend operand predicate for integer modes.
1114 (define_mode_attr general_szext_operand
1115 [(QI "general_operand")
1116 (HI "general_operand")
1117 (SI "x86_64_szext_general_operand")
1118 (DI "x86_64_szext_general_operand")])
1120 ;; Immediate operand predicate for integer modes.
1121 (define_mode_attr immediate_operand
1122 [(QI "immediate_operand")
1123 (HI "immediate_operand")
1124 (SI "x86_64_immediate_operand")
1125 (DI "x86_64_immediate_operand")])
1127 ;; Nonmemory operand predicate for integer modes.
1128 (define_mode_attr nonmemory_operand
1129 [(QI "nonmemory_operand")
1130 (HI "nonmemory_operand")
1131 (SI "x86_64_nonmemory_operand")
1132 (DI "x86_64_nonmemory_operand")])
1134 ;; Operand predicate for shifts.
1135 (define_mode_attr shift_operand
1136 [(QI "nonimmediate_operand")
1137 (HI "nonimmediate_operand")
1138 (SI "nonimmediate_operand")
1139 (DI "shiftdi_operand")
1140 (TI "register_operand")])
1142 ;; Operand predicate for shift argument.
1143 (define_mode_attr shift_immediate_operand
1144 [(QI "const_1_to_31_operand")
1145 (HI "const_1_to_31_operand")
1146 (SI "const_1_to_31_operand")
1147 (DI "const_1_to_63_operand")])
1149 ;; Input operand predicate for arithmetic left shifts.
1150 (define_mode_attr ashl_input_operand
1151 [(QI "nonimmediate_operand")
1152 (HI "nonimmediate_operand")
1153 (SI "nonimmediate_operand")
1154 (DI "ashldi_input_operand")
1155 (TI "reg_or_pm1_operand")])
1157 ;; SSE and x87 SFmode and DFmode floating point modes
1158 (define_mode_iterator MODEF [SF DF])
1160 ;; All x87 floating point modes
1161 (define_mode_iterator X87MODEF [SF DF XF])
1163 ;; SSE instruction suffix for various modes
1164 (define_mode_attr ssemodesuffix
1165 [(SF "ss") (DF "sd")
1166 (V16SF "ps") (V8DF "pd")
1167 (V8SF "ps") (V4DF "pd")
1168 (V4SF "ps") (V2DF "pd")
1169 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1170 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1171 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1173 ;; SSE vector suffix for floating point modes
1174 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1176 ;; SSE vector mode corresponding to a scalar mode
1177 (define_mode_attr ssevecmode
1178 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1179 (define_mode_attr ssevecmodelower
1180 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1182 ;; AVX512F vector mode corresponding to a scalar mode
1183 (define_mode_attr avx512fvecmode
1184 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1186 ;; Instruction suffix for REX 64bit operators.
1187 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1189 ;; This mode iterator allows :P to be used for patterns that operate on
1190 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1191 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1193 ;; This mode iterator allows :W to be used for patterns that operate on
1194 ;; word_mode sized quantities.
1195 (define_mode_iterator W
1196 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1198 ;; This mode iterator allows :PTR to be used for patterns that operate on
1199 ;; ptr_mode sized quantities.
1200 (define_mode_iterator PTR
1201 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1203 ;; Scheduling descriptions
1205 (include "pentium.md")
1208 (include "athlon.md")
1209 (include "bdver1.md")
1210 (include "bdver3.md")
1211 (include "btver2.md")
1212 (include "znver1.md")
1213 (include "geode.md")
1216 (include "core2.md")
1217 (include "haswell.md")
1220 ;; Operand and operator predicates and constraints
1222 (include "predicates.md")
1223 (include "constraints.md")
1226 ;; Compare and branch/compare and store instructions.
1228 (define_expand "cbranch<mode>4"
1229 [(set (reg:CC FLAGS_REG)
1230 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1231 (match_operand:SDWIM 2 "<general_operand>")))
1232 (set (pc) (if_then_else
1233 (match_operator 0 "ordered_comparison_operator"
1234 [(reg:CC FLAGS_REG) (const_int 0)])
1235 (label_ref (match_operand 3))
1239 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1240 operands[1] = force_reg (<MODE>mode, operands[1]);
1241 ix86_expand_branch (GET_CODE (operands[0]),
1242 operands[1], operands[2], operands[3]);
1246 (define_expand "cstore<mode>4"
1247 [(set (reg:CC FLAGS_REG)
1248 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1249 (match_operand:SWIM 3 "<general_operand>")))
1250 (set (match_operand:QI 0 "register_operand")
1251 (match_operator 1 "ordered_comparison_operator"
1252 [(reg:CC FLAGS_REG) (const_int 0)]))]
1255 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1256 operands[2] = force_reg (<MODE>mode, operands[2]);
1257 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1258 operands[2], operands[3]);
1262 (define_expand "cmp<mode>_1"
1263 [(set (reg:CC FLAGS_REG)
1264 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1265 (match_operand:SWI48 1 "<general_operand>")))])
1267 (define_insn "*cmp<mode>_ccno_1"
1268 [(set (reg FLAGS_REG)
1269 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1270 (match_operand:SWI 1 "const0_operand")))]
1271 "ix86_match_ccmode (insn, CCNOmode)"
1273 test{<imodesuffix>}\t%0, %0
1274 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1275 [(set_attr "type" "test,icmp")
1276 (set_attr "length_immediate" "0,1")
1277 (set_attr "modrm_class" "op0,unknown")
1278 (set_attr "mode" "<MODE>")])
1280 (define_insn "*cmp<mode>_1"
1281 [(set (reg FLAGS_REG)
1282 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1283 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1284 "ix86_match_ccmode (insn, CCmode)"
1285 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1286 [(set_attr "type" "icmp")
1287 (set_attr "mode" "<MODE>")])
1289 (define_insn "*cmp<mode>_minus_1"
1290 [(set (reg FLAGS_REG)
1292 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1293 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1295 "ix86_match_ccmode (insn, CCGOCmode)"
1296 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1297 [(set_attr "type" "icmp")
1298 (set_attr "mode" "<MODE>")])
1300 (define_insn "*cmpqi_ext_1"
1301 [(set (reg FLAGS_REG)
1303 (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1306 (match_operand 1 "ext_register_operand" "Q,Q")
1308 (const_int 8)) 0)))]
1309 "ix86_match_ccmode (insn, CCmode)"
1310 "cmp{b}\t{%h1, %0|%0, %h1}"
1311 [(set_attr "isa" "*,nox64")
1312 (set_attr "type" "icmp")
1313 (set_attr "mode" "QI")])
1315 (define_insn "*cmpqi_ext_2"
1316 [(set (reg FLAGS_REG)
1320 (match_operand 0 "ext_register_operand" "Q")
1323 (match_operand:QI 1 "const0_operand")))]
1324 "ix86_match_ccmode (insn, CCNOmode)"
1326 [(set_attr "type" "test")
1327 (set_attr "length_immediate" "0")
1328 (set_attr "mode" "QI")])
1330 (define_expand "cmpqi_ext_3"
1331 [(set (reg:CC FLAGS_REG)
1335 (match_operand 0 "ext_register_operand")
1338 (match_operand:QI 1 "const_int_operand")))])
1340 (define_insn "*cmpqi_ext_3"
1341 [(set (reg FLAGS_REG)
1345 (match_operand 0 "ext_register_operand" "Q,Q")
1348 (match_operand:QI 1 "general_operand" "QnBc,m")))]
1349 "ix86_match_ccmode (insn, CCmode)"
1350 "cmp{b}\t{%1, %h0|%h0, %1}"
1351 [(set_attr "isa" "*,nox64")
1352 (set_attr "type" "icmp")
1353 (set_attr "mode" "QI")])
1355 (define_insn "*cmpqi_ext_4"
1356 [(set (reg FLAGS_REG)
1360 (match_operand 0 "ext_register_operand" "Q")
1365 (match_operand 1 "ext_register_operand" "Q")
1367 (const_int 8)) 0)))]
1368 "ix86_match_ccmode (insn, CCmode)"
1369 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1370 [(set_attr "type" "icmp")
1371 (set_attr "mode" "QI")])
1373 ;; These implement float point compares.
1374 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1375 ;; which would allow mix and match FP modes on the compares. Which is what
1376 ;; the old patterns did, but with many more of them.
1378 (define_expand "cbranchxf4"
1379 [(set (reg:CC FLAGS_REG)
1380 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1381 (match_operand:XF 2 "nonmemory_operand")))
1382 (set (pc) (if_then_else
1383 (match_operator 0 "ix86_fp_comparison_operator"
1386 (label_ref (match_operand 3))
1390 ix86_expand_branch (GET_CODE (operands[0]),
1391 operands[1], operands[2], operands[3]);
1395 (define_expand "cstorexf4"
1396 [(set (reg:CC FLAGS_REG)
1397 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1398 (match_operand:XF 3 "nonmemory_operand")))
1399 (set (match_operand:QI 0 "register_operand")
1400 (match_operator 1 "ix86_fp_comparison_operator"
1405 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1406 operands[2], operands[3]);
1410 (define_expand "cbranch<mode>4"
1411 [(set (reg:CC FLAGS_REG)
1412 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1413 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1414 (set (pc) (if_then_else
1415 (match_operator 0 "ix86_fp_comparison_operator"
1418 (label_ref (match_operand 3))
1420 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1422 ix86_expand_branch (GET_CODE (operands[0]),
1423 operands[1], operands[2], operands[3]);
1427 (define_expand "cstore<mode>4"
1428 [(set (reg:CC FLAGS_REG)
1429 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1430 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1431 (set (match_operand:QI 0 "register_operand")
1432 (match_operator 1 "ix86_fp_comparison_operator"
1435 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1437 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1438 operands[2], operands[3]);
1442 (define_expand "cbranchcc4"
1443 [(set (pc) (if_then_else
1444 (match_operator 0 "comparison_operator"
1445 [(match_operand 1 "flags_reg_operand")
1446 (match_operand 2 "const0_operand")])
1447 (label_ref (match_operand 3))
1451 ix86_expand_branch (GET_CODE (operands[0]),
1452 operands[1], operands[2], operands[3]);
1456 (define_expand "cstorecc4"
1457 [(set (match_operand:QI 0 "register_operand")
1458 (match_operator 1 "comparison_operator"
1459 [(match_operand 2 "flags_reg_operand")
1460 (match_operand 3 "const0_operand")]))]
1463 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1464 operands[2], operands[3]);
1469 ;; FP compares, step 1:
1470 ;; Set the FP condition codes.
1472 ;; CCFPmode compare with exceptions
1473 ;; CCFPUmode compare with no exceptions
1475 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1476 ;; used to manage the reg stack popping would not be preserved.
1478 (define_insn "*cmp<mode>_0_i387"
1479 [(set (match_operand:HI 0 "register_operand" "=a")
1482 (match_operand:X87MODEF 1 "register_operand" "f")
1483 (match_operand:X87MODEF 2 "const0_operand"))]
1486 "* return output_fp_compare (insn, operands, false, false);"
1487 [(set_attr "type" "multi")
1488 (set_attr "unit" "i387")
1489 (set_attr "mode" "<MODE>")])
1491 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1492 [(set (reg:CCFP FLAGS_REG)
1494 (match_operand:X87MODEF 1 "register_operand" "f")
1495 (match_operand:X87MODEF 2 "const0_operand")))
1496 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1497 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1499 "&& reload_completed"
1502 [(compare:CCFP (match_dup 1)(match_dup 2))]
1504 (set (reg:CC FLAGS_REG)
1505 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1507 [(set_attr "type" "multi")
1508 (set_attr "unit" "i387")
1509 (set_attr "mode" "<MODE>")])
1511 (define_insn "*cmpxf_i387"
1512 [(set (match_operand:HI 0 "register_operand" "=a")
1515 (match_operand:XF 1 "register_operand" "f")
1516 (match_operand:XF 2 "register_operand" "f"))]
1519 "* return output_fp_compare (insn, operands, false, false);"
1520 [(set_attr "type" "multi")
1521 (set_attr "unit" "i387")
1522 (set_attr "mode" "XF")])
1524 (define_insn_and_split "*cmpxf_cc_i387"
1525 [(set (reg:CCFP FLAGS_REG)
1527 (match_operand:XF 1 "register_operand" "f")
1528 (match_operand:XF 2 "register_operand" "f")))
1529 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1530 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1532 "&& reload_completed"
1535 [(compare:CCFP (match_dup 1)(match_dup 2))]
1537 (set (reg:CC FLAGS_REG)
1538 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1540 [(set_attr "type" "multi")
1541 (set_attr "unit" "i387")
1542 (set_attr "mode" "XF")])
1544 (define_insn "*cmp<mode>_i387"
1545 [(set (match_operand:HI 0 "register_operand" "=a")
1548 (match_operand:MODEF 1 "register_operand" "f")
1549 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1552 "* return output_fp_compare (insn, operands, false, false);"
1553 [(set_attr "type" "multi")
1554 (set_attr "unit" "i387")
1555 (set_attr "mode" "<MODE>")])
1557 (define_insn_and_split "*cmp<mode>_cc_i387"
1558 [(set (reg:CCFP FLAGS_REG)
1560 (match_operand:MODEF 1 "register_operand" "f")
1561 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1562 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1563 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1565 "&& reload_completed"
1568 [(compare:CCFP (match_dup 1)(match_dup 2))]
1570 (set (reg:CC FLAGS_REG)
1571 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1573 [(set_attr "type" "multi")
1574 (set_attr "unit" "i387")
1575 (set_attr "mode" "<MODE>")])
1577 (define_insn "*cmpu<mode>_i387"
1578 [(set (match_operand:HI 0 "register_operand" "=a")
1581 (match_operand:X87MODEF 1 "register_operand" "f")
1582 (match_operand:X87MODEF 2 "register_operand" "f"))]
1585 "* return output_fp_compare (insn, operands, false, true);"
1586 [(set_attr "type" "multi")
1587 (set_attr "unit" "i387")
1588 (set_attr "mode" "<MODE>")])
1590 (define_insn_and_split "*cmpu<mode>_cc_i387"
1591 [(set (reg:CCFPU FLAGS_REG)
1593 (match_operand:X87MODEF 1 "register_operand" "f")
1594 (match_operand:X87MODEF 2 "register_operand" "f")))
1595 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1596 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1598 "&& reload_completed"
1601 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1603 (set (reg:CC FLAGS_REG)
1604 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1606 [(set_attr "type" "multi")
1607 (set_attr "unit" "i387")
1608 (set_attr "mode" "<MODE>")])
1610 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1611 [(set (match_operand:HI 0 "register_operand" "=a")
1614 (match_operand:X87MODEF 1 "register_operand" "f")
1615 (match_operator:X87MODEF 3 "float_operator"
1616 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1619 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1620 || optimize_function_for_size_p (cfun))"
1621 "* return output_fp_compare (insn, operands, false, false);"
1622 [(set_attr "type" "multi")
1623 (set_attr "unit" "i387")
1624 (set_attr "fp_int_src" "true")
1625 (set_attr "mode" "<SWI24:MODE>")])
1627 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1628 [(set (reg:CCFP FLAGS_REG)
1630 (match_operand:X87MODEF 1 "register_operand" "f")
1631 (match_operator:X87MODEF 3 "float_operator"
1632 [(match_operand:SWI24 2 "memory_operand" "m")])))
1633 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1634 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1635 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1636 || optimize_function_for_size_p (cfun))"
1638 "&& reload_completed"
1643 (match_op_dup 3 [(match_dup 2)]))]
1645 (set (reg:CC FLAGS_REG)
1646 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1648 [(set_attr "type" "multi")
1649 (set_attr "unit" "i387")
1650 (set_attr "fp_int_src" "true")
1651 (set_attr "mode" "<SWI24:MODE>")])
1653 ;; FP compares, step 2
1654 ;; Move the fpsw to ax.
1656 (define_insn "x86_fnstsw_1"
1657 [(set (match_operand:HI 0 "register_operand" "=a")
1658 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1661 [(set_attr "length" "2")
1662 (set_attr "mode" "SI")
1663 (set_attr "unit" "i387")])
1665 ;; FP compares, step 3
1666 ;; Get ax into flags, general case.
1668 (define_insn "x86_sahf_1"
1669 [(set (reg:CC FLAGS_REG)
1670 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1674 #ifndef HAVE_AS_IX86_SAHF
1676 return ASM_BYTE "0x9e";
1681 [(set_attr "length" "1")
1682 (set_attr "athlon_decode" "vector")
1683 (set_attr "amdfam10_decode" "direct")
1684 (set_attr "bdver1_decode" "direct")
1685 (set_attr "mode" "SI")])
1687 ;; Pentium Pro can do steps 1 through 3 in one go.
1688 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1689 ;; (these i387 instructions set flags directly)
1691 (define_mode_iterator FPCMP [CCFP CCFPU])
1692 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1694 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>"
1695 [(set (reg:FPCMP FLAGS_REG)
1697 (match_operand:MODEF 0 "register_operand" "f,v")
1698 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1699 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1700 || (TARGET_80387 && TARGET_CMOVE)"
1701 "* return output_fp_compare (insn, operands, true,
1702 <FPCMP:MODE>mode == CCFPUmode);"
1703 [(set_attr "type" "fcmp,ssecomi")
1704 (set_attr "prefix" "orig,maybe_vex")
1705 (set_attr "mode" "<MODEF:MODE>")
1706 (set_attr "prefix_rep" "*,0")
1707 (set (attr "prefix_data16")
1708 (cond [(eq_attr "alternative" "0")
1710 (eq_attr "mode" "DF")
1713 (const_string "0")))
1714 (set_attr "athlon_decode" "vector")
1715 (set_attr "amdfam10_decode" "direct")
1716 (set_attr "bdver1_decode" "double")
1717 (set_attr "znver1_decode" "double")
1718 (set (attr "enabled")
1720 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1722 (eq_attr "alternative" "0")
1723 (symbol_ref "TARGET_MIX_SSE_I387")
1724 (symbol_ref "true"))
1726 (eq_attr "alternative" "0")
1728 (symbol_ref "false"))))])
1730 (define_insn "*cmpi<unord>xf_i387"
1731 [(set (reg:FPCMP FLAGS_REG)
1733 (match_operand:XF 0 "register_operand" "f")
1734 (match_operand:XF 1 "register_operand" "f")))]
1735 "TARGET_80387 && TARGET_CMOVE"
1736 "* return output_fp_compare (insn, operands, true,
1737 <MODE>mode == CCFPUmode);"
1738 [(set_attr "type" "fcmp")
1739 (set_attr "mode" "XF")
1740 (set_attr "athlon_decode" "vector")
1741 (set_attr "amdfam10_decode" "direct")
1742 (set_attr "bdver1_decode" "double")
1743 (set_attr "znver1_decode" "double")])
1745 ;; Push/pop instructions.
1747 (define_insn "*push<mode>2"
1748 [(set (match_operand:DWI 0 "push_operand" "=<")
1749 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1752 [(set_attr "type" "multi")
1753 (set_attr "mode" "<MODE>")])
1756 [(set (match_operand:DWI 0 "push_operand")
1757 (match_operand:DWI 1 "general_gr_operand"))]
1760 "ix86_split_long_move (operands); DONE;")
1762 (define_insn "*pushdi2_rex64"
1763 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1764 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1769 [(set_attr "type" "push,multi")
1770 (set_attr "mode" "DI")])
1772 ;; Convert impossible pushes of immediate to existing instructions.
1773 ;; First try to get scratch register and go through it. In case this
1774 ;; fails, push sign extended lower part first and then overwrite
1775 ;; upper part by 32bit move.
1777 [(match_scratch:DI 2 "r")
1778 (set (match_operand:DI 0 "push_operand")
1779 (match_operand:DI 1 "immediate_operand"))]
1780 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1781 && !x86_64_immediate_operand (operands[1], DImode)"
1782 [(set (match_dup 2) (match_dup 1))
1783 (set (match_dup 0) (match_dup 2))])
1785 ;; We need to define this as both peepholer and splitter for case
1786 ;; peephole2 pass is not run.
1787 ;; "&& 1" is needed to keep it from matching the previous pattern.
1789 [(set (match_operand:DI 0 "push_operand")
1790 (match_operand:DI 1 "immediate_operand"))]
1791 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1792 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1793 [(set (match_dup 0) (match_dup 1))
1794 (set (match_dup 2) (match_dup 3))]
1796 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1798 operands[1] = gen_lowpart (DImode, operands[2]);
1799 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1804 [(set (match_operand:DI 0 "push_operand")
1805 (match_operand:DI 1 "immediate_operand"))]
1806 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1807 ? epilogue_completed : reload_completed)
1808 && !symbolic_operand (operands[1], DImode)
1809 && !x86_64_immediate_operand (operands[1], DImode)"
1810 [(set (match_dup 0) (match_dup 1))
1811 (set (match_dup 2) (match_dup 3))]
1813 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1815 operands[1] = gen_lowpart (DImode, operands[2]);
1816 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1820 (define_insn "*pushsi2"
1821 [(set (match_operand:SI 0 "push_operand" "=<")
1822 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1825 [(set_attr "type" "push")
1826 (set_attr "mode" "SI")])
1828 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1829 ;; "push a byte/word". But actually we use pushl, which has the effect
1830 ;; of rounding the amount pushed up to a word.
1832 ;; For TARGET_64BIT we always round up to 8 bytes.
1833 (define_insn "*push<mode>2_rex64"
1834 [(set (match_operand:SWI124 0 "push_operand" "=X")
1835 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1838 [(set_attr "type" "push")
1839 (set_attr "mode" "DI")])
1841 (define_insn "*push<mode>2"
1842 [(set (match_operand:SWI12 0 "push_operand" "=X")
1843 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1846 [(set_attr "type" "push")
1847 (set_attr "mode" "SI")])
1849 (define_insn "*push<mode>2_prologue"
1850 [(set (match_operand:W 0 "push_operand" "=<")
1851 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1852 (clobber (mem:BLK (scratch)))]
1854 "push{<imodesuffix>}\t%1"
1855 [(set_attr "type" "push")
1856 (set_attr "mode" "<MODE>")])
1858 (define_insn "*pop<mode>1"
1859 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1860 (match_operand:W 1 "pop_operand" ">"))]
1862 "pop{<imodesuffix>}\t%0"
1863 [(set_attr "type" "pop")
1864 (set_attr "mode" "<MODE>")])
1866 (define_insn "*pop<mode>1_epilogue"
1867 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1868 (match_operand:W 1 "pop_operand" ">"))
1869 (clobber (mem:BLK (scratch)))]
1871 "pop{<imodesuffix>}\t%0"
1872 [(set_attr "type" "pop")
1873 (set_attr "mode" "<MODE>")])
1875 (define_insn "*pushfl<mode>2"
1876 [(set (match_operand:W 0 "push_operand" "=<")
1877 (match_operand:W 1 "flags_reg_operand"))]
1879 "pushf{<imodesuffix>}"
1880 [(set_attr "type" "push")
1881 (set_attr "mode" "<MODE>")])
1883 (define_insn "*popfl<mode>1"
1884 [(set (match_operand:W 0 "flags_reg_operand")
1885 (match_operand:W 1 "pop_operand" ">"))]
1887 "popf{<imodesuffix>}"
1888 [(set_attr "type" "pop")
1889 (set_attr "mode" "<MODE>")])
1892 ;; Reload patterns to support multi-word load/store
1893 ;; with non-offsetable address.
1894 (define_expand "reload_noff_store"
1895 [(parallel [(match_operand 0 "memory_operand" "=m")
1896 (match_operand 1 "register_operand" "r")
1897 (match_operand:DI 2 "register_operand" "=&r")])]
1900 rtx mem = operands[0];
1901 rtx addr = XEXP (mem, 0);
1903 emit_move_insn (operands[2], addr);
1904 mem = replace_equiv_address_nv (mem, operands[2]);
1906 emit_insn (gen_rtx_SET (mem, operands[1]));
1910 (define_expand "reload_noff_load"
1911 [(parallel [(match_operand 0 "register_operand" "=r")
1912 (match_operand 1 "memory_operand" "m")
1913 (match_operand:DI 2 "register_operand" "=r")])]
1916 rtx mem = operands[1];
1917 rtx addr = XEXP (mem, 0);
1919 emit_move_insn (operands[2], addr);
1920 mem = replace_equiv_address_nv (mem, operands[2]);
1922 emit_insn (gen_rtx_SET (operands[0], mem));
1926 ;; Move instructions.
1928 (define_expand "movxi"
1929 [(set (match_operand:XI 0 "nonimmediate_operand")
1930 (match_operand:XI 1 "general_operand"))]
1932 "ix86_expand_vector_move (XImode, operands); DONE;")
1934 (define_expand "movoi"
1935 [(set (match_operand:OI 0 "nonimmediate_operand")
1936 (match_operand:OI 1 "general_operand"))]
1938 "ix86_expand_vector_move (OImode, operands); DONE;")
1940 (define_expand "movti"
1941 [(set (match_operand:TI 0 "nonimmediate_operand")
1942 (match_operand:TI 1 "general_operand"))]
1943 "TARGET_64BIT || TARGET_SSE"
1946 ix86_expand_move (TImode, operands);
1948 ix86_expand_vector_move (TImode, operands);
1952 ;; This expands to what emit_move_complex would generate if we didn't
1953 ;; have a movti pattern. Having this avoids problems with reload on
1954 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1955 ;; to have around all the time.
1956 (define_expand "movcdi"
1957 [(set (match_operand:CDI 0 "nonimmediate_operand")
1958 (match_operand:CDI 1 "general_operand"))]
1961 if (push_operand (operands[0], CDImode))
1962 emit_move_complex_push (CDImode, operands[0], operands[1]);
1964 emit_move_complex_parts (operands[0], operands[1]);
1968 (define_expand "mov<mode>"
1969 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1970 (match_operand:SWI1248x 1 "general_operand"))]
1972 "ix86_expand_move (<MODE>mode, operands); DONE;")
1974 (define_insn "*mov<mode>_xor"
1975 [(set (match_operand:SWI48 0 "register_operand" "=r")
1976 (match_operand:SWI48 1 "const0_operand"))
1977 (clobber (reg:CC FLAGS_REG))]
1980 [(set_attr "type" "alu1")
1981 (set_attr "modrm_class" "op0")
1982 (set_attr "mode" "SI")
1983 (set_attr "length_immediate" "0")])
1985 (define_insn "*mov<mode>_or"
1986 [(set (match_operand:SWI48 0 "register_operand" "=r")
1987 (match_operand:SWI48 1 "constm1_operand"))
1988 (clobber (reg:CC FLAGS_REG))]
1990 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1991 [(set_attr "type" "alu1")
1992 (set_attr "mode" "<MODE>")
1993 (set_attr "length_immediate" "1")])
1995 (define_insn "*movxi_internal_avx512f"
1996 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m")
1997 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
1999 && (register_operand (operands[0], XImode)
2000 || register_operand (operands[1], XImode))"
2002 switch (get_attr_type (insn))
2005 return standard_sse_constant_opcode (insn, operands[1]);
2008 if (misaligned_operand (operands[0], XImode)
2009 || misaligned_operand (operands[1], XImode))
2010 return "vmovdqu32\t{%1, %0|%0, %1}";
2012 return "vmovdqa32\t{%1, %0|%0, %1}";
2018 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2019 (set_attr "prefix" "evex")
2020 (set_attr "mode" "XI")])
2022 (define_insn "*movoi_internal_avx"
2023 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m")
2024 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2026 && (register_operand (operands[0], OImode)
2027 || register_operand (operands[1], OImode))"
2029 switch (get_attr_type (insn))
2032 return standard_sse_constant_opcode (insn, operands[1]);
2035 if (misaligned_operand (operands[0], OImode)
2036 || misaligned_operand (operands[1], OImode))
2038 if (get_attr_mode (insn) == MODE_V8SF)
2039 return "vmovups\t{%1, %0|%0, %1}";
2040 else if (get_attr_mode (insn) == MODE_XI)
2041 return "vmovdqu32\t{%1, %0|%0, %1}";
2043 return "vmovdqu\t{%1, %0|%0, %1}";
2047 if (get_attr_mode (insn) == MODE_V8SF)
2048 return "vmovaps\t{%1, %0|%0, %1}";
2049 else if (get_attr_mode (insn) == MODE_XI)
2050 return "vmovdqa32\t{%1, %0|%0, %1}";
2052 return "vmovdqa\t{%1, %0|%0, %1}";
2059 [(set_attr "isa" "*,avx2,*,*")
2060 (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2061 (set_attr "prefix" "vex")
2063 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2064 (match_operand 1 "ext_sse_reg_operand"))
2066 (and (eq_attr "alternative" "1")
2067 (match_test "TARGET_AVX512VL"))
2069 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2070 (and (eq_attr "alternative" "3")
2071 (match_test "TARGET_SSE_TYPELESS_STORES")))
2072 (const_string "V8SF")
2074 (const_string "OI")))])
2076 (define_insn "*movti_internal"
2077 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
2078 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v,Ye,r"))]
2080 && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2082 && nonimmediate_or_sse_const_operand (operands[1], TImode)
2083 && (register_operand (operands[0], TImode)
2084 || register_operand (operands[1], TImode)))"
2086 switch (get_attr_type (insn))
2092 return standard_sse_constant_opcode (insn, operands[1]);
2095 /* TDmode values are passed as TImode on the stack. Moving them
2096 to stack may result in unaligned memory access. */
2097 if (misaligned_operand (operands[0], TImode)
2098 || misaligned_operand (operands[1], TImode))
2100 if (get_attr_mode (insn) == MODE_V4SF)
2101 return "%vmovups\t{%1, %0|%0, %1}";
2102 else if (get_attr_mode (insn) == MODE_XI)
2103 return "vmovdqu32\t{%1, %0|%0, %1}";
2105 return "%vmovdqu\t{%1, %0|%0, %1}";
2109 if (get_attr_mode (insn) == MODE_V4SF)
2110 return "%vmovaps\t{%1, %0|%0, %1}";
2111 else if (get_attr_mode (insn) == MODE_XI)
2112 return "vmovdqa32\t{%1, %0|%0, %1}";
2114 return "%vmovdqa\t{%1, %0|%0, %1}";
2122 (cond [(eq_attr "alternative" "0,1,6,7")
2123 (const_string "x64")
2124 (eq_attr "alternative" "3")
2125 (const_string "sse2")
2127 (const_string "*")))
2129 (cond [(eq_attr "alternative" "0,1,6,7")
2130 (const_string "multi")
2131 (eq_attr "alternative" "2,3")
2132 (const_string "sselog1")
2134 (const_string "ssemov")))
2135 (set (attr "prefix")
2136 (if_then_else (eq_attr "type" "sselog1,ssemov")
2137 (const_string "maybe_vex")
2138 (const_string "orig")))
2140 (cond [(eq_attr "alternative" "0,1")
2142 (ior (match_operand 0 "ext_sse_reg_operand")
2143 (match_operand 1 "ext_sse_reg_operand"))
2145 (and (eq_attr "alternative" "3")
2146 (match_test "TARGET_AVX512VL"))
2148 (ior (not (match_test "TARGET_SSE2"))
2149 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2150 (and (eq_attr "alternative" "5")
2151 (match_test "TARGET_SSE_TYPELESS_STORES"))))
2152 (const_string "V4SF")
2153 (match_test "TARGET_AVX")
2155 (match_test "optimize_function_for_size_p (cfun)")
2156 (const_string "V4SF")
2158 (const_string "TI")))])
2161 [(set (match_operand:TI 0 "sse_reg_operand")
2162 (match_operand:TI 1 "general_reg_operand"))]
2163 "TARGET_64BIT && TARGET_SSE4_1 && TARGET_INTER_UNIT_MOVES_TO_VEC
2164 && reload_completed"
2167 (vec_duplicate:V2DI (match_dup 3))
2171 operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2172 operands[3] = gen_highpart (DImode, operands[1]);
2174 emit_move_insn (gen_lowpart (DImode, operands[0]),
2175 gen_lowpart (DImode, operands[1]));
2178 (define_insn "*movdi_internal"
2179 [(set (match_operand:DI 0 "nonimmediate_operand"
2180 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,m,?r ,?*Yd,?r ,?*Yi,?*Ym,?*Yi,*k,*k ,*r,*m")
2181 (match_operand:DI 1 "general_operand"
2182 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,v,*Ye,r ,*Yj,r ,*Yj ,*Yn ,*r,*km,*k,*k"))]
2183 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2185 switch (get_attr_type (insn))
2188 return "kmovq\t{%1, %0|%0, %1}";
2194 return "pxor\t%0, %0";
2197 /* Handle broken assemblers that require movd instead of movq. */
2198 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2199 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2200 return "movd\t{%1, %0|%0, %1}";
2201 return "movq\t{%1, %0|%0, %1}";
2204 return standard_sse_constant_opcode (insn, operands[1]);
2207 switch (get_attr_mode (insn))
2210 /* Handle broken assemblers that require movd instead of movq. */
2211 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2212 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2213 return "%vmovd\t{%1, %0|%0, %1}";
2214 return "%vmovq\t{%1, %0|%0, %1}";
2216 return "%vmovdqa\t{%1, %0|%0, %1}";
2218 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2221 gcc_assert (!TARGET_AVX);
2222 return "movlps\t{%1, %0|%0, %1}";
2224 return "%vmovaps\t{%1, %0|%0, %1}";
2231 if (SSE_REG_P (operands[0]))
2232 return "movq2dq\t{%1, %0|%0, %1}";
2234 return "movdq2q\t{%1, %0|%0, %1}";
2237 return "lea{q}\t{%E1, %0|%0, %E1}";
2240 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2241 if (get_attr_mode (insn) == MODE_SI)
2242 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2243 else if (which_alternative == 4)
2244 return "movabs{q}\t{%1, %0|%0, %1}";
2245 else if (ix86_use_lea_for_mov (insn, operands))
2246 return "lea{q}\t{%E1, %0|%0, %E1}";
2248 return "mov{q}\t{%1, %0|%0, %1}";
2255 (cond [(eq_attr "alternative" "0,1,17,18")
2256 (const_string "nox64")
2257 (eq_attr "alternative" "2,3,4,5,10,11,19,20,23,25")
2258 (const_string "x64")
2260 (const_string "*")))
2262 (cond [(eq_attr "alternative" "0,1,17,18")
2263 (const_string "multi")
2264 (eq_attr "alternative" "6")
2265 (const_string "mmx")
2266 (eq_attr "alternative" "7,8,9,10,11")
2267 (const_string "mmxmov")
2268 (eq_attr "alternative" "12")
2269 (const_string "sselog1")
2270 (eq_attr "alternative" "13,14,15,16,19,20")
2271 (const_string "ssemov")
2272 (eq_attr "alternative" "21,22")
2273 (const_string "ssecvt")
2274 (eq_attr "alternative" "23,24,25,26")
2275 (const_string "mskmov")
2276 (and (match_operand 0 "register_operand")
2277 (match_operand 1 "pic_32bit_operand"))
2278 (const_string "lea")
2280 (const_string "imov")))
2283 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2285 (const_string "*")))
2286 (set (attr "length_immediate")
2288 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2290 (const_string "*")))
2291 (set (attr "prefix_rex")
2293 (eq_attr "alternative" "10,11,19,20")
2295 (const_string "*")))
2296 (set (attr "prefix")
2297 (if_then_else (eq_attr "type" "sselog1,ssemov")
2298 (const_string "maybe_vex")
2299 (const_string "orig")))
2300 (set (attr "prefix_data16")
2301 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2303 (const_string "*")))
2305 (cond [(eq_attr "alternative" "2")
2307 (eq_attr "alternative" "12,13")
2308 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2309 (match_operand 1 "ext_sse_reg_operand"))
2311 (ior (not (match_test "TARGET_SSE2"))
2312 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2313 (const_string "V4SF")
2314 (match_test "TARGET_AVX")
2316 (match_test "optimize_function_for_size_p (cfun)")
2317 (const_string "V4SF")
2319 (const_string "TI"))
2321 (and (eq_attr "alternative" "14,15,16")
2322 (not (match_test "TARGET_SSE2")))
2323 (const_string "V2SF")
2325 (const_string "DI")))
2326 (set (attr "enabled")
2327 (cond [(eq_attr "alternative" "15")
2329 (match_test "TARGET_STV && TARGET_SSE2")
2330 (symbol_ref "false")
2332 (eq_attr "alternative" "16")
2334 (match_test "TARGET_STV && TARGET_SSE2")
2336 (symbol_ref "false"))
2338 (const_string "*")))])
2341 [(set (match_operand:<DWI> 0 "general_reg_operand")
2342 (match_operand:<DWI> 1 "sse_reg_operand"))]
2343 "TARGET_SSE4_1 && TARGET_INTER_UNIT_MOVES_FROM_VEC
2344 && reload_completed"
2348 (parallel [(const_int 1)])))]
2350 operands[2] = gen_highpart (<MODE>mode, operands[0]);
2351 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2353 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2354 gen_lowpart (<MODE>mode, operands[1]));
2358 [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2359 (match_operand:DWI 1 "general_gr_operand"))]
2362 "ix86_split_long_move (operands); DONE;")
2365 [(set (match_operand:DI 0 "sse_reg_operand")
2366 (match_operand:DI 1 "general_reg_operand"))]
2367 "!TARGET_64BIT && TARGET_SSE4_1 && TARGET_INTER_UNIT_MOVES_TO_VEC
2368 && reload_completed"
2371 (vec_duplicate:V4SI (match_dup 3))
2375 operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2376 operands[3] = gen_highpart (SImode, operands[1]);
2378 emit_move_insn (gen_lowpart (SImode, operands[0]),
2379 gen_lowpart (SImode, operands[1]));
2382 (define_insn "*movsi_internal"
2383 [(set (match_operand:SI 0 "nonimmediate_operand"
2384 "=r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?*Yi,*k,*k ,*rm")
2385 (match_operand:SI 1 "general_operand"
2386 "g ,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,*Yj,r ,*r,*km,*k"))]
2387 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2389 switch (get_attr_type (insn))
2392 return standard_sse_constant_opcode (insn, operands[1]);
2395 return "kmovd\t{%1, %0|%0, %1}";
2398 switch (get_attr_mode (insn))
2401 return "%vmovd\t{%1, %0|%0, %1}";
2403 return "%vmovdqa\t{%1, %0|%0, %1}";
2405 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2408 return "%vmovaps\t{%1, %0|%0, %1}";
2411 gcc_assert (!TARGET_AVX);
2412 return "movss\t{%1, %0|%0, %1}";
2419 return "pxor\t%0, %0";
2422 switch (get_attr_mode (insn))
2425 return "movq\t{%1, %0|%0, %1}";
2427 return "movd\t{%1, %0|%0, %1}";
2434 return "lea{l}\t{%E1, %0|%0, %E1}";
2437 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2438 if (ix86_use_lea_for_mov (insn, operands))
2439 return "lea{l}\t{%E1, %0|%0, %E1}";
2441 return "mov{l}\t{%1, %0|%0, %1}";
2448 (cond [(eq_attr "alternative" "2")
2449 (const_string "mmx")
2450 (eq_attr "alternative" "3,4,5,6,7")
2451 (const_string "mmxmov")
2452 (eq_attr "alternative" "8")
2453 (const_string "sselog1")
2454 (eq_attr "alternative" "9,10,11,12,13")
2455 (const_string "ssemov")
2456 (eq_attr "alternative" "14,15,16")
2457 (const_string "mskmov")
2458 (and (match_operand 0 "register_operand")
2459 (match_operand 1 "pic_32bit_operand"))
2460 (const_string "lea")
2462 (const_string "imov")))
2463 (set (attr "prefix")
2464 (if_then_else (eq_attr "type" "sselog1,ssemov")
2465 (const_string "maybe_vex")
2466 (const_string "orig")))
2467 (set (attr "prefix_data16")
2468 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2470 (const_string "*")))
2472 (cond [(eq_attr "alternative" "2,3")
2474 (eq_attr "alternative" "8,9")
2475 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2476 (match_operand 1 "ext_sse_reg_operand"))
2478 (ior (not (match_test "TARGET_SSE2"))
2479 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2480 (const_string "V4SF")
2481 (match_test "TARGET_AVX")
2483 (match_test "optimize_function_for_size_p (cfun)")
2484 (const_string "V4SF")
2486 (const_string "TI"))
2488 (and (eq_attr "alternative" "10,11")
2489 (not (match_test "TARGET_SSE2")))
2492 (const_string "SI")))])
2494 (define_insn "*movhi_internal"
2495 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m")
2496 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,r,km,k,k"))]
2497 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2499 switch (get_attr_type (insn))
2502 /* movzwl is faster than movw on p2 due to partial word stalls,
2503 though not as fast as an aligned movl. */
2504 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2507 switch (which_alternative)
2510 return "kmovw\t{%k1, %0|%0, %k1}";
2512 return "kmovw\t{%1, %k0|%k0, %1}";
2515 return "kmovw\t{%1, %0|%0, %1}";
2521 if (get_attr_mode (insn) == MODE_SI)
2522 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2524 return "mov{w}\t{%1, %0|%0, %1}";
2528 (cond [(eq_attr "alternative" "4,5,6,7")
2529 (const_string "mskmov")
2530 (match_test "optimize_function_for_size_p (cfun)")
2531 (const_string "imov")
2532 (and (eq_attr "alternative" "0")
2533 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2534 (not (match_test "TARGET_HIMODE_MATH"))))
2535 (const_string "imov")
2536 (and (eq_attr "alternative" "1,2")
2537 (match_operand:HI 1 "aligned_operand"))
2538 (const_string "imov")
2539 (and (match_test "TARGET_MOVX")
2540 (eq_attr "alternative" "0,2"))
2541 (const_string "imovx")
2543 (const_string "imov")))
2544 (set (attr "prefix")
2545 (if_then_else (eq_attr "alternative" "4,5,6,7")
2546 (const_string "vex")
2547 (const_string "orig")))
2549 (cond [(eq_attr "type" "imovx")
2551 (and (eq_attr "alternative" "1,2")
2552 (match_operand:HI 1 "aligned_operand"))
2554 (and (eq_attr "alternative" "0")
2555 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2556 (not (match_test "TARGET_HIMODE_MATH"))))
2559 (const_string "HI")))])
2561 ;; Situation is quite tricky about when to choose full sized (SImode) move
2562 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2563 ;; partial register dependency machines (such as AMD Athlon), where QImode
2564 ;; moves issue extra dependency and for partial register stalls machines
2565 ;; that don't use QImode patterns (and QImode move cause stall on the next
2568 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2569 ;; register stall machines with, where we use QImode instructions, since
2570 ;; partial register stall can be caused there. Then we use movzx.
2572 (define_insn "*movqi_internal"
2573 [(set (match_operand:QI 0 "nonimmediate_operand"
2574 "=q,q ,q ,r,r ,?r,m ,k,k,r,m,k")
2575 (match_operand:QI 1 "general_operand"
2576 "q ,qn,qm,q,rn,qm,qn,r,k,k,k,m"))]
2577 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2579 static char buf[128];
2583 switch (get_attr_type (insn))
2586 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2587 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2590 switch (which_alternative)
2593 ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
2596 ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
2600 gcc_assert (TARGET_AVX512DQ);
2603 ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
2609 suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
2611 snprintf (buf, sizeof (buf), ops, suffix);
2615 if (get_attr_mode (insn) == MODE_SI)
2616 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2618 return "mov{b}\t{%1, %0|%0, %1}";
2622 (if_then_else (eq_attr "alternative" "10,11")
2623 (const_string "avx512dq")
2624 (const_string "*")))
2626 (cond [(eq_attr "alternative" "7,8,9,10,11")
2627 (const_string "mskmov")
2628 (and (eq_attr "alternative" "5")
2629 (not (match_operand:QI 1 "aligned_operand")))
2630 (const_string "imovx")
2631 (match_test "optimize_function_for_size_p (cfun)")
2632 (const_string "imov")
2633 (and (eq_attr "alternative" "3")
2634 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2635 (not (match_test "TARGET_QIMODE_MATH"))))
2636 (const_string "imov")
2637 (eq_attr "alternative" "3,5")
2638 (const_string "imovx")
2639 (and (match_test "TARGET_MOVX")
2640 (eq_attr "alternative" "2"))
2641 (const_string "imovx")
2643 (const_string "imov")))
2644 (set (attr "prefix")
2645 (if_then_else (eq_attr "alternative" "7,8,9")
2646 (const_string "vex")
2647 (const_string "orig")))
2649 (cond [(eq_attr "alternative" "3,4,5")
2651 (eq_attr "alternative" "6")
2653 (and (eq_attr "alternative" "7,8,9")
2654 (not (match_test "TARGET_AVX512DQ")))
2656 (eq_attr "type" "imovx")
2658 (and (eq_attr "type" "imov")
2659 (and (eq_attr "alternative" "0,1")
2660 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2661 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2662 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2664 ;; Avoid partial register stalls when not using QImode arithmetic
2665 (and (eq_attr "type" "imov")
2666 (and (eq_attr "alternative" "0,1")
2667 (and (match_test "TARGET_PARTIAL_REG_STALL")
2668 (not (match_test "TARGET_QIMODE_MATH")))))
2671 (const_string "QI")))])
2673 ;; Stores and loads of ax to arbitrary constant address.
2674 ;; We fake an second form of instruction to force reload to load address
2675 ;; into register when rax is not available
2676 (define_insn "*movabs<mode>_1"
2677 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2678 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2679 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2681 /* Recover the full memory rtx. */
2682 operands[0] = SET_DEST (PATTERN (insn));
2683 switch (which_alternative)
2686 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
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" "store")
2698 (set_attr "mode" "<MODE>")])
2700 (define_insn "*movabs<mode>_2"
2701 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2702 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2703 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2705 /* Recover the full memory rtx. */
2706 operands[1] = SET_SRC (PATTERN (insn));
2707 switch (which_alternative)
2710 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2712 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2717 [(set_attr "type" "imov")
2718 (set_attr "modrm" "0,*")
2719 (set_attr "length_address" "8,0")
2720 (set_attr "length_immediate" "0")
2721 (set_attr "memory" "load")
2722 (set_attr "mode" "<MODE>")])
2724 (define_insn "*swap<mode>"
2725 [(set (match_operand:SWI48 0 "register_operand" "+r")
2726 (match_operand:SWI48 1 "register_operand" "+r"))
2730 "xchg{<imodesuffix>}\t%1, %0"
2731 [(set_attr "type" "imov")
2732 (set_attr "mode" "<MODE>")
2733 (set_attr "pent_pair" "np")
2734 (set_attr "athlon_decode" "vector")
2735 (set_attr "amdfam10_decode" "double")
2736 (set_attr "bdver1_decode" "double")])
2738 (define_insn "*swap<mode>"
2739 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2740 (match_operand:SWI12 1 "register_operand" "+<r>,r"))
2745 xchg{<imodesuffix>}\t%1, %0
2747 [(set_attr "type" "imov")
2748 (set_attr "mode" "<MODE>,SI")
2749 (set (attr "preferred_for_size")
2750 (cond [(eq_attr "alternative" "0")
2751 (symbol_ref "false")]
2752 (symbol_ref "true")))
2753 ;; Potential partial reg stall on alternative 1.
2754 (set (attr "preferred_for_speed")
2755 (cond [(eq_attr "alternative" "1")
2756 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2757 (symbol_ref "true")))
2758 (set_attr "pent_pair" "np")
2759 (set_attr "athlon_decode" "vector")
2760 (set_attr "amdfam10_decode" "double")
2761 (set_attr "bdver1_decode" "double")])
2763 (define_expand "movstrict<mode>"
2764 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2765 (match_operand:SWI12 1 "general_operand"))]
2768 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2770 if (SUBREG_P (operands[0])
2771 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2773 /* Don't generate memory->memory moves, go through a register */
2774 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2775 operands[1] = force_reg (<MODE>mode, operands[1]);
2778 (define_insn "*movstrict<mode>_1"
2779 [(set (strict_low_part
2780 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2781 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2782 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2783 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2784 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2785 [(set_attr "type" "imov")
2786 (set_attr "mode" "<MODE>")])
2788 (define_insn "*movstrict<mode>_xor"
2789 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2790 (match_operand:SWI12 1 "const0_operand"))
2791 (clobber (reg:CC FLAGS_REG))]
2793 "xor{<imodesuffix>}\t%0, %0"
2794 [(set_attr "type" "alu1")
2795 (set_attr "modrm_class" "op0")
2796 (set_attr "mode" "<MODE>")
2797 (set_attr "length_immediate" "0")])
2799 (define_expand "extv<mode>"
2800 [(set (match_operand:SWI24 0 "register_operand")
2801 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2802 (match_operand:SI 2 "const_int_operand")
2803 (match_operand:SI 3 "const_int_operand")))]
2806 /* Handle extractions from %ah et al. */
2807 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2810 unsigned int regno = reg_or_subregno (operands[1]);
2812 /* Be careful to expand only with registers having upper parts. */
2813 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2814 operands[1] = copy_to_reg (operands[1]);
2817 (define_insn "*extv<mode>"
2818 [(set (match_operand:SWI24 0 "register_operand" "=R")
2819 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2823 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2824 [(set_attr "type" "imovx")
2825 (set_attr "mode" "SI")])
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 unsigned int regno = reg_or_subregno (operands[1]);
2843 /* Be careful to expand only with registers having upper parts. */
2844 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2845 operands[1] = copy_to_reg (operands[1]);
2848 (define_insn "*extzvqi_mem_rex64"
2849 [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
2851 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2854 "TARGET_64BIT && reload_completed"
2855 "mov{b}\t{%h1, %0|%0, %h1}"
2856 [(set_attr "type" "imov")
2857 (set_attr "mode" "QI")])
2859 (define_insn "*extzv<mode>"
2860 [(set (match_operand:SWI248 0 "register_operand" "=R")
2861 (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2865 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2866 [(set_attr "type" "imovx")
2867 (set_attr "mode" "SI")])
2869 (define_insn "*extzvqi"
2870 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
2872 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2877 switch (get_attr_type (insn))
2880 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2882 return "mov{b}\t{%h1, %0|%0, %h1}";
2885 [(set_attr "isa" "*,*,nox64")
2887 (if_then_else (and (match_operand:QI 0 "register_operand")
2888 (ior (not (match_operand:QI 0 "QIreg_operand"))
2889 (match_test "TARGET_MOVX")))
2890 (const_string "imovx")
2891 (const_string "imov")))
2893 (if_then_else (eq_attr "type" "imovx")
2895 (const_string "QI")))])
2898 [(set (match_operand:QI 0 "register_operand")
2900 (zero_extract:SI (match_operand 1 "ext_register_operand")
2903 (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
2905 && peep2_reg_dead_p (2, operands[0])"
2908 (zero_extract:SI (match_dup 1)
2910 (const_int 8)) 0))])
2912 (define_expand "insv<mode>"
2913 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
2914 (match_operand:SI 1 "const_int_operand")
2915 (match_operand:SI 2 "const_int_operand"))
2916 (match_operand:SWI248 3 "register_operand"))]
2921 if (ix86_expand_pinsr (operands))
2924 /* Handle insertions to %ah et al. */
2925 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
2928 unsigned int regno = reg_or_subregno (operands[0]);
2930 /* Be careful to expand only with registers having upper parts. */
2931 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2932 dst = copy_to_reg (operands[0]);
2936 emit_insn (gen_insv<mode>_1 (dst, operands[3]));
2938 /* Fix up the destination if needed. */
2939 if (dst != operands[0])
2940 emit_move_insn (operands[0], dst);
2945 (define_insn "*insvqi_1_mem_rex64"
2946 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2950 (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
2951 "TARGET_64BIT && reload_completed"
2952 "mov{b}\t{%1, %h0|%h0, %1}"
2953 [(set_attr "type" "imov")
2954 (set_attr "mode" "QI")])
2956 (define_insn "insv<mode>_1"
2957 [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
2960 (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
2963 if (CONST_INT_P (operands[1]))
2964 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
2965 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2967 [(set_attr "isa" "*,nox64")
2968 (set_attr "type" "imov")
2969 (set_attr "mode" "QI")])
2971 (define_insn "*insvqi_1"
2972 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
2976 (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
2978 "mov{b}\t{%1, %h0|%h0, %1}"
2979 [(set_attr "isa" "*,nox64")
2980 (set_attr "type" "imov")
2981 (set_attr "mode" "QI")])
2984 [(set (match_operand:QI 0 "register_operand")
2985 (match_operand:QI 1 "norex_memory_operand"))
2986 (set (zero_extract:SI (match_operand 2 "ext_register_operand")
2989 (subreg:SI (match_dup 0) 0))]
2991 && peep2_reg_dead_p (2, operands[0])"
2992 [(set (zero_extract:SI (match_dup 2)
2995 (subreg:SI (match_dup 1) 0))])
2997 (define_code_iterator any_extract [sign_extract zero_extract])
2999 (define_insn "*insvqi_2"
3000 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3003 (any_extract:SI (match_operand 1 "ext_register_operand" "Q")
3007 "mov{b}\t{%h1, %h0|%h0, %h1}"
3008 [(set_attr "type" "imov")
3009 (set_attr "mode" "QI")])
3011 (define_insn "*insvqi_3"
3012 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3015 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "Q")
3018 "mov{b}\t{%h1, %h0|%h0, %h1}"
3019 [(set_attr "type" "imov")
3020 (set_attr "mode" "QI")])
3022 ;; Floating point push instructions.
3024 (define_insn "*pushtf"
3025 [(set (match_operand:TF 0 "push_operand" "=<,<")
3026 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3027 "TARGET_64BIT || TARGET_SSE"
3029 /* This insn should be already split before reg-stack. */
3032 [(set_attr "isa" "*,x64")
3033 (set_attr "type" "multi")
3034 (set_attr "unit" "sse,*")
3035 (set_attr "mode" "TF,DI")])
3037 ;; %%% Kill this when call knows how to work this out.
3039 [(set (match_operand:TF 0 "push_operand")
3040 (match_operand:TF 1 "sse_reg_operand"))]
3041 "TARGET_SSE && reload_completed"
3042 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3043 (set (match_dup 0) (match_dup 1))]
3045 /* Preserve memory attributes. */
3046 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3049 (define_insn_and_split "*pushxf_rounded"
3053 (plus:P (reg:P SP_REG) (const_int -16))))
3054 (match_operand:XF 0 "nonmemory_no_elim_operand" "f,r,*r,C"))]
3058 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3059 (set (match_dup 1) (match_dup 0))]
3061 rtx pat = PATTERN (curr_insn);
3062 operands[1] = SET_DEST (pat);
3064 /* Preserve memory attributes. */
3065 operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
3067 [(set_attr "type" "multi")
3068 (set_attr "unit" "i387,*,*,*")
3070 (cond [(eq_attr "alternative" "1,2,3")
3073 (const_string "XF")))
3074 (set (attr "preferred_for_size")
3075 (cond [(eq_attr "alternative" "1")
3076 (symbol_ref "false")]
3077 (symbol_ref "true")))])
3079 (define_insn "*pushxf"
3080 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3081 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3084 /* This insn should be already split before reg-stack. */
3087 [(set_attr "isa" "*,*,*,nox64,x64")
3088 (set_attr "type" "multi")
3089 (set_attr "unit" "i387,*,*,*,*")
3091 (cond [(eq_attr "alternative" "1,2,3,4")
3092 (if_then_else (match_test "TARGET_64BIT")
3094 (const_string "SI"))
3096 (const_string "XF")))
3097 (set (attr "preferred_for_size")
3098 (cond [(eq_attr "alternative" "1")
3099 (symbol_ref "false")]
3100 (symbol_ref "true")))])
3102 ;; %%% Kill this when call knows how to work this out.
3104 [(set (match_operand:XF 0 "push_operand")
3105 (match_operand:XF 1 "fp_register_operand"))]
3107 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3108 (set (match_dup 0) (match_dup 1))]
3110 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3111 /* Preserve memory attributes. */
3112 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3115 (define_insn "*pushdf"
3116 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3117 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,x"))]
3120 /* This insn should be already split before reg-stack. */
3123 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3124 (set_attr "type" "multi")
3125 (set_attr "unit" "i387,*,*,*,*,sse")
3126 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3127 (set (attr "preferred_for_size")
3128 (cond [(eq_attr "alternative" "1")
3129 (symbol_ref "false")]
3130 (symbol_ref "true")))
3131 (set (attr "preferred_for_speed")
3132 (cond [(eq_attr "alternative" "1")
3133 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3134 (symbol_ref "true")))])
3136 ;; %%% Kill this when call knows how to work this out.
3138 [(set (match_operand:DF 0 "push_operand")
3139 (match_operand:DF 1 "any_fp_register_operand"))]
3141 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3142 (set (match_dup 0) (match_dup 1))]
3144 /* Preserve memory attributes. */
3145 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3148 (define_insn "*pushsf_rex64"
3149 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3150 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3153 /* Anything else should be already split before reg-stack. */
3154 gcc_assert (which_alternative == 1);
3155 return "push{q}\t%q1";
3157 [(set_attr "type" "multi,push,multi")
3158 (set_attr "unit" "i387,*,*")
3159 (set_attr "mode" "SF,DI,SF")])
3161 (define_insn "*pushsf"
3162 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3163 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3166 /* Anything else should be already split before reg-stack. */
3167 gcc_assert (which_alternative == 1);
3168 return "push{l}\t%1";
3170 [(set_attr "type" "multi,push,multi")
3171 (set_attr "unit" "i387,*,*")
3172 (set_attr "mode" "SF,SI,SF")])
3174 ;; %%% Kill this when call knows how to work this out.
3176 [(set (match_operand:SF 0 "push_operand")
3177 (match_operand:SF 1 "any_fp_register_operand"))]
3179 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3180 (set (match_dup 0) (match_dup 1))]
3182 rtx op = XEXP (operands[0], 0);
3183 if (GET_CODE (op) == PRE_DEC)
3185 gcc_assert (!TARGET_64BIT);
3190 op = XEXP (XEXP (op, 1), 1);
3191 gcc_assert (CONST_INT_P (op));
3194 /* Preserve memory attributes. */
3195 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3199 [(set (match_operand:SF 0 "push_operand")
3200 (match_operand:SF 1 "memory_operand"))]
3202 && find_constant_src (insn)"
3203 [(set (match_dup 0) (match_dup 2))]
3204 "operands[2] = find_constant_src (curr_insn);")
3207 [(set (match_operand 0 "push_operand")
3208 (match_operand 1 "general_gr_operand"))]
3210 && (GET_MODE (operands[0]) == TFmode
3211 || GET_MODE (operands[0]) == XFmode
3212 || GET_MODE (operands[0]) == DFmode)"
3214 "ix86_split_long_move (operands); DONE;")
3216 ;; Floating point move instructions.
3218 (define_expand "movtf"
3219 [(set (match_operand:TF 0 "nonimmediate_operand")
3220 (match_operand:TF 1 "nonimmediate_operand"))]
3221 "TARGET_64BIT || TARGET_SSE"
3222 "ix86_expand_move (TFmode, operands); DONE;")
3224 (define_expand "mov<mode>"
3225 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3226 (match_operand:X87MODEF 1 "general_operand"))]
3228 "ix86_expand_move (<MODE>mode, operands); DONE;")
3230 (define_insn "*movtf_internal"
3231 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3232 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3233 "(TARGET_64BIT || TARGET_SSE)
3234 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3235 && (lra_in_progress || reload_completed
3236 || !CONST_DOUBLE_P (operands[1])
3237 || ((optimize_function_for_size_p (cfun)
3238 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3239 && standard_sse_constant_p (operands[1], TFmode) == 1
3240 && !memory_operand (operands[0], TFmode))
3241 || (!TARGET_MEMORY_MISMATCH_STALL
3242 && memory_operand (operands[0], TFmode)))"
3244 switch (get_attr_type (insn))
3247 return standard_sse_constant_opcode (insn, operands[1]);
3250 /* Handle misaligned load/store since we
3251 don't have movmisaligntf pattern. */
3252 if (misaligned_operand (operands[0], TFmode)
3253 || misaligned_operand (operands[1], TFmode))
3255 if (get_attr_mode (insn) == MODE_V4SF)
3256 return "%vmovups\t{%1, %0|%0, %1}";
3257 else if (TARGET_AVX512VL
3258 && (EXT_REX_SSE_REG_P (operands[0])
3259 || EXT_REX_SSE_REG_P (operands[1])))
3260 return "vmovdqu64\t{%1, %0|%0, %1}";
3262 return "%vmovdqu\t{%1, %0|%0, %1}";
3266 if (get_attr_mode (insn) == MODE_V4SF)
3267 return "%vmovaps\t{%1, %0|%0, %1}";
3268 else if (TARGET_AVX512VL
3269 && (EXT_REX_SSE_REG_P (operands[0])
3270 || EXT_REX_SSE_REG_P (operands[1])))
3271 return "vmovdqa64\t{%1, %0|%0, %1}";
3273 return "%vmovdqa\t{%1, %0|%0, %1}";
3283 [(set_attr "isa" "*,*,*,x64,x64")
3284 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3285 (set (attr "prefix")
3286 (if_then_else (eq_attr "type" "sselog1,ssemov")
3287 (const_string "maybe_vex")
3288 (const_string "orig")))
3290 (cond [(eq_attr "alternative" "3,4")
3292 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3293 (const_string "V4SF")
3294 (and (eq_attr "alternative" "2")
3295 (match_test "TARGET_SSE_TYPELESS_STORES"))
3296 (const_string "V4SF")
3297 (match_test "TARGET_AVX")
3299 (ior (not (match_test "TARGET_SSE2"))
3300 (match_test "optimize_function_for_size_p (cfun)"))
3301 (const_string "V4SF")
3303 (const_string "TI")))])
3306 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3307 (match_operand:TF 1 "general_gr_operand"))]
3310 "ix86_split_long_move (operands); DONE;")
3312 ;; Possible store forwarding (partial memory) stall
3313 ;; in alternatives 4, 6, 7 and 8.
3314 (define_insn "*movxf_internal"
3315 [(set (match_operand:XF 0 "nonimmediate_operand"
3316 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o")
3317 (match_operand:XF 1 "general_operand"
3318 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3319 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3320 && (lra_in_progress || reload_completed
3321 || !CONST_DOUBLE_P (operands[1])
3322 || ((optimize_function_for_size_p (cfun)
3323 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3324 && standard_80387_constant_p (operands[1]) > 0
3325 && !memory_operand (operands[0], XFmode))
3326 || (!TARGET_MEMORY_MISMATCH_STALL
3327 && memory_operand (operands[0], XFmode))
3328 || !TARGET_HARD_XF_REGS)"
3330 switch (get_attr_type (insn))
3333 if (which_alternative == 2)
3334 return standard_80387_constant_opcode (operands[1]);
3335 return output_387_reg_move (insn, operands);
3345 (cond [(eq_attr "alternative" "7,10")
3346 (const_string "nox64")
3347 (eq_attr "alternative" "8,11")
3348 (const_string "x64")
3350 (const_string "*")))
3352 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3353 (const_string "multi")
3355 (const_string "fmov")))
3357 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3358 (if_then_else (match_test "TARGET_64BIT")
3360 (const_string "SI"))
3362 (const_string "XF")))
3363 (set (attr "preferred_for_size")
3364 (cond [(eq_attr "alternative" "3,4")
3365 (symbol_ref "false")]
3366 (symbol_ref "true")))
3367 (set (attr "enabled")
3368 (cond [(eq_attr "alternative" "9,10,11")
3370 (match_test "TARGET_HARD_XF_REGS")
3371 (symbol_ref "false")
3373 (not (match_test "TARGET_HARD_XF_REGS"))
3374 (symbol_ref "false")
3376 (const_string "*")))])
3379 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3380 (match_operand:XF 1 "general_gr_operand"))]
3383 "ix86_split_long_move (operands); DONE;")
3385 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3386 (define_insn "*movdf_internal"
3387 [(set (match_operand:DF 0 "nonimmediate_operand"
3388 "=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")
3389 (match_operand:DF 1 "general_operand"
3390 "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"))]
3391 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3392 && (lra_in_progress || reload_completed
3393 || !CONST_DOUBLE_P (operands[1])
3394 || ((optimize_function_for_size_p (cfun)
3395 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3396 && ((IS_STACK_MODE (DFmode)
3397 && standard_80387_constant_p (operands[1]) > 0)
3398 || (TARGET_SSE2 && TARGET_SSE_MATH
3399 && standard_sse_constant_p (operands[1], DFmode) == 1))
3400 && !memory_operand (operands[0], DFmode))
3401 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3402 && memory_operand (operands[0], DFmode))
3403 || !TARGET_HARD_DF_REGS)"
3405 switch (get_attr_type (insn))
3408 if (which_alternative == 2)
3409 return standard_80387_constant_opcode (operands[1]);
3410 return output_387_reg_move (insn, operands);
3416 if (get_attr_mode (insn) == MODE_SI)
3417 return "mov{l}\t{%1, %k0|%k0, %1}";
3418 else if (which_alternative == 11)
3419 return "movabs{q}\t{%1, %0|%0, %1}";
3421 return "mov{q}\t{%1, %0|%0, %1}";
3424 return standard_sse_constant_opcode (insn, operands[1]);
3427 switch (get_attr_mode (insn))
3430 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3431 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3432 return "%vmovsd\t{%1, %0|%0, %1}";
3435 return "%vmovaps\t{%1, %0|%0, %1}";
3437 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3439 return "%vmovapd\t{%1, %0|%0, %1}";
3442 gcc_assert (!TARGET_AVX);
3443 return "movlps\t{%1, %0|%0, %1}";
3445 gcc_assert (!TARGET_AVX);
3446 return "movlpd\t{%1, %0|%0, %1}";
3449 /* Handle broken assemblers that require movd instead of movq. */
3450 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3451 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3452 return "%vmovd\t{%1, %0|%0, %1}";
3453 return "%vmovq\t{%1, %0|%0, %1}";
3464 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3465 (const_string "nox64")
3466 (eq_attr "alternative" "8,9,10,11,20,21,24,25")
3467 (const_string "x64")
3468 (eq_attr "alternative" "12,13,14,15")
3469 (const_string "sse2")
3471 (const_string "*")))
3473 (cond [(eq_attr "alternative" "0,1,2")
3474 (const_string "fmov")
3475 (eq_attr "alternative" "3,4,5,6,7,22,23")
3476 (const_string "multi")
3477 (eq_attr "alternative" "8,9,10,11,24,25")
3478 (const_string "imov")
3479 (eq_attr "alternative" "12,16")
3480 (const_string "sselog1")
3482 (const_string "ssemov")))
3484 (if_then_else (eq_attr "alternative" "11")
3486 (const_string "*")))
3487 (set (attr "length_immediate")
3488 (if_then_else (eq_attr "alternative" "11")
3490 (const_string "*")))
3491 (set (attr "prefix")
3492 (if_then_else (eq_attr "type" "sselog1,ssemov")
3493 (const_string "maybe_vex")
3494 (const_string "orig")))
3495 (set (attr "prefix_data16")
3497 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3498 (eq_attr "mode" "V1DF"))
3500 (const_string "*")))
3502 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3504 (eq_attr "alternative" "8,9,11,20,21,24,25")
3507 /* xorps is one byte shorter for non-AVX targets. */
3508 (eq_attr "alternative" "12,16")
3509 (cond [(not (match_test "TARGET_SSE2"))
3510 (const_string "V4SF")
3511 (match_test "TARGET_AVX512F")
3513 (match_test "TARGET_AVX")
3514 (const_string "V2DF")
3515 (match_test "optimize_function_for_size_p (cfun)")
3516 (const_string "V4SF")
3517 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3520 (const_string "V2DF"))
3522 /* For architectures resolving dependencies on
3523 whole SSE registers use movapd to break dependency
3524 chains, otherwise use short move to avoid extra work. */
3526 /* movaps is one byte shorter for non-AVX targets. */
3527 (eq_attr "alternative" "13,17")
3528 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3529 (match_operand 1 "ext_sse_reg_operand"))
3530 (const_string "V8DF")
3531 (ior (not (match_test "TARGET_SSE2"))
3532 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3533 (const_string "V4SF")
3534 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3535 (const_string "V2DF")
3536 (match_test "TARGET_AVX")
3538 (match_test "optimize_function_for_size_p (cfun)")
3539 (const_string "V4SF")
3541 (const_string "DF"))
3543 /* For architectures resolving dependencies on register
3544 parts we may avoid extra work to zero out upper part
3546 (eq_attr "alternative" "14,18")
3547 (cond [(not (match_test "TARGET_SSE2"))
3548 (const_string "V2SF")
3549 (match_test "TARGET_AVX")
3551 (match_test "TARGET_SSE_SPLIT_REGS")
3552 (const_string "V1DF")
3554 (const_string "DF"))
3556 (and (eq_attr "alternative" "15,19")
3557 (not (match_test "TARGET_SSE2")))
3558 (const_string "V2SF")
3560 (const_string "DF")))
3561 (set (attr "preferred_for_size")
3562 (cond [(eq_attr "alternative" "3,4")
3563 (symbol_ref "false")]
3564 (symbol_ref "true")))
3565 (set (attr "preferred_for_speed")
3566 (cond [(eq_attr "alternative" "3,4")
3567 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3568 (symbol_ref "true")))
3569 (set (attr "enabled")
3570 (cond [(eq_attr "alternative" "22,23,24,25")
3572 (match_test "TARGET_HARD_DF_REGS")
3573 (symbol_ref "false")
3575 (not (match_test "TARGET_HARD_DF_REGS"))
3576 (symbol_ref "false")
3578 (const_string "*")))])
3581 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
3582 (match_operand:DF 1 "general_gr_operand"))]
3583 "!TARGET_64BIT && reload_completed"
3585 "ix86_split_long_move (operands); DONE;")
3587 (define_insn "*movsf_internal"
3588 [(set (match_operand:SF 0 "nonimmediate_operand"
3589 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym,r ,m")
3590 (match_operand:SF 1 "general_operand"
3591 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r ,rmF,rF"))]
3592 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3593 && (lra_in_progress || reload_completed
3594 || !CONST_DOUBLE_P (operands[1])
3595 || ((optimize_function_for_size_p (cfun)
3596 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3597 && ((IS_STACK_MODE (SFmode)
3598 && standard_80387_constant_p (operands[1]) > 0)
3599 || (TARGET_SSE && TARGET_SSE_MATH
3600 && standard_sse_constant_p (operands[1], SFmode) == 1)))
3601 || memory_operand (operands[0], SFmode)
3602 || !TARGET_HARD_SF_REGS)"
3604 switch (get_attr_type (insn))
3607 if (which_alternative == 2)
3608 return standard_80387_constant_opcode (operands[1]);
3609 return output_387_reg_move (insn, operands);
3612 return "mov{l}\t{%1, %0|%0, %1}";
3615 return standard_sse_constant_opcode (insn, operands[1]);
3618 switch (get_attr_mode (insn))
3621 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3622 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3623 return "%vmovss\t{%1, %0|%0, %1}";
3626 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3628 return "%vmovaps\t{%1, %0|%0, %1}";
3631 return "%vmovd\t{%1, %0|%0, %1}";
3638 switch (get_attr_mode (insn))
3641 return "movq\t{%1, %0|%0, %1}";
3643 return "movd\t{%1, %0|%0, %1}";
3654 (cond [(eq_attr "alternative" "0,1,2")
3655 (const_string "fmov")
3656 (eq_attr "alternative" "3,4,16,17")
3657 (const_string "imov")
3658 (eq_attr "alternative" "5")
3659 (const_string "sselog1")
3660 (eq_attr "alternative" "11,12,13,14,15")
3661 (const_string "mmxmov")
3663 (const_string "ssemov")))
3664 (set (attr "prefix")
3665 (if_then_else (eq_attr "type" "sselog1,ssemov")
3666 (const_string "maybe_vex")
3667 (const_string "orig")))
3668 (set (attr "prefix_data16")
3669 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3671 (const_string "*")))
3673 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3675 (eq_attr "alternative" "11")
3677 (eq_attr "alternative" "5")
3678 (cond [(not (match_test "TARGET_SSE2"))
3679 (const_string "V4SF")
3680 (match_test "TARGET_AVX512F")
3681 (const_string "V16SF")
3682 (match_test "TARGET_AVX")
3683 (const_string "V4SF")
3684 (match_test "optimize_function_for_size_p (cfun)")
3685 (const_string "V4SF")
3686 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3689 (const_string "V4SF"))
3691 /* For architectures resolving dependencies on
3692 whole SSE registers use APS move to break dependency
3693 chains, otherwise use short move to avoid extra work.
3695 Do the same for architectures resolving dependencies on
3696 the parts. While in DF mode it is better to always handle
3697 just register parts, the SF mode is different due to lack
3698 of instructions to load just part of the register. It is
3699 better to maintain the whole registers in single format
3700 to avoid problems on using packed logical operations. */
3701 (eq_attr "alternative" "6")
3702 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3703 (match_operand 1 "ext_sse_reg_operand"))
3704 (const_string "V16SF")
3705 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3706 (match_test "TARGET_SSE_SPLIT_REGS"))
3707 (const_string "V4SF")
3709 (const_string "SF"))
3711 (const_string "SF")))
3712 (set (attr "enabled")
3713 (cond [(eq_attr "alternative" "16,17")
3715 (match_test "TARGET_HARD_SF_REGS")
3716 (symbol_ref "false")
3718 (not (match_test "TARGET_HARD_SF_REGS"))
3719 (symbol_ref "false")
3721 (const_string "*")))])
3724 [(set (match_operand 0 "any_fp_register_operand")
3725 (match_operand 1 "nonimmediate_operand"))]
3727 && (GET_MODE (operands[0]) == TFmode
3728 || GET_MODE (operands[0]) == XFmode
3729 || GET_MODE (operands[0]) == DFmode
3730 || GET_MODE (operands[0]) == SFmode)
3731 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3732 [(set (match_dup 0) (match_dup 2))]
3733 "operands[2] = find_constant_src (curr_insn);")
3736 [(set (match_operand 0 "any_fp_register_operand")
3737 (float_extend (match_operand 1 "nonimmediate_operand")))]
3739 && (GET_MODE (operands[0]) == TFmode
3740 || GET_MODE (operands[0]) == XFmode
3741 || GET_MODE (operands[0]) == DFmode)
3742 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3743 [(set (match_dup 0) (match_dup 2))]
3744 "operands[2] = find_constant_src (curr_insn);")
3746 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3748 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3749 (match_operand:X87MODEF 1 "immediate_operand"))]
3751 && (standard_80387_constant_p (operands[1]) == 8
3752 || standard_80387_constant_p (operands[1]) == 9)"
3753 [(set (match_dup 0)(match_dup 1))
3755 (neg:X87MODEF (match_dup 0)))]
3757 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3758 operands[1] = CONST0_RTX (<MODE>mode);
3760 operands[1] = CONST1_RTX (<MODE>mode);
3763 (define_insn "swapxf"
3764 [(set (match_operand:XF 0 "register_operand" "+f")
3765 (match_operand:XF 1 "register_operand" "+f"))
3770 if (STACK_TOP_P (operands[0]))
3775 [(set_attr "type" "fxch")
3776 (set_attr "mode" "XF")])
3778 (define_insn "*swap<mode>"
3779 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3780 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3783 "TARGET_80387 || reload_completed"
3785 if (STACK_TOP_P (operands[0]))
3790 [(set_attr "type" "fxch")
3791 (set_attr "mode" "<MODE>")])
3793 ;; Zero extension instructions
3795 (define_expand "zero_extendsidi2"
3796 [(set (match_operand:DI 0 "nonimmediate_operand")
3797 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3799 (define_insn "*zero_extendsidi2"
3800 [(set (match_operand:DI 0 "nonimmediate_operand"
3801 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?*Yi,*x,*x,*v,*r")
3803 (match_operand:SI 1 "x86_64_zext_operand"
3804 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,r ,m ,*x,*v,*k")))]
3807 switch (get_attr_type (insn))
3810 if (ix86_use_lea_for_mov (insn, operands))
3811 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3813 return "mov{l}\t{%1, %k0|%k0, %1}";
3819 return "movd\t{%1, %0|%0, %1}";
3822 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
3824 if (EXT_REX_SSE_REG_P (operands[0])
3825 || EXT_REX_SSE_REG_P (operands[1]))
3826 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
3828 return "%vpmovzxdq\t{%1, %0|%0, %1}";
3831 if (GENERAL_REG_P (operands[0]))
3832 return "%vmovd\t{%1, %k0|%k0, %1}";
3834 return "%vmovd\t{%1, %0|%0, %1}";
3837 return "kmovd\t{%1, %k0|%k0, %1}";
3844 (cond [(eq_attr "alternative" "0,1,2")
3845 (const_string "nox64")
3846 (eq_attr "alternative" "3")
3847 (const_string "x64")
3848 (eq_attr "alternative" "9")
3849 (const_string "sse2")
3850 (eq_attr "alternative" "10")
3851 (const_string "sse4")
3852 (eq_attr "alternative" "11")
3853 (const_string "avx512f")
3854 (eq_attr "alternative" "12")
3855 (const_string "x64_avx512bw")
3857 (const_string "*")))
3859 (cond [(eq_attr "alternative" "0,1,2,4")
3860 (const_string "multi")
3861 (eq_attr "alternative" "5,6")
3862 (const_string "mmxmov")
3863 (eq_attr "alternative" "7")
3864 (if_then_else (match_test "TARGET_64BIT")
3865 (const_string "ssemov")
3866 (const_string "multi"))
3867 (eq_attr "alternative" "8,9,10,11")
3868 (const_string "ssemov")
3869 (eq_attr "alternative" "12")
3870 (const_string "mskmov")
3872 (const_string "imovx")))
3873 (set (attr "prefix_extra")
3874 (if_then_else (eq_attr "alternative" "10,11")
3876 (const_string "*")))
3877 (set (attr "prefix")
3878 (if_then_else (eq_attr "type" "ssemov")
3879 (const_string "maybe_vex")
3880 (const_string "orig")))
3881 (set (attr "prefix_0f")
3882 (if_then_else (eq_attr "type" "imovx")
3884 (const_string "*")))
3886 (cond [(eq_attr "alternative" "5,6")
3888 (and (eq_attr "alternative" "7")
3889 (match_test "TARGET_64BIT"))
3891 (eq_attr "alternative" "8,10,11")
3894 (const_string "SI")))])
3897 [(set (match_operand:DI 0 "memory_operand")
3898 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3900 [(set (match_dup 4) (const_int 0))]
3901 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3904 [(set (match_operand:DI 0 "general_reg_operand")
3905 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
3906 "!TARGET_64BIT && reload_completed
3907 && REGNO (operands[0]) == REGNO (operands[1])"
3908 [(set (match_dup 4) (const_int 0))]
3909 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3912 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
3913 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3914 "!TARGET_64BIT && reload_completed
3915 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3916 [(set (match_dup 3) (match_dup 1))
3917 (set (match_dup 4) (const_int 0))]
3918 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3921 [(set (match_operand:DI 0 "general_reg_operand")
3922 (zero_extend:DI (match_operand:SI 1 "nonimmediate_gr_operand")))
3923 (set (match_operand:DI 2 "sse_reg_operand") (match_dup 0))]
3924 "TARGET_64BIT && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
3925 && peep2_reg_dead_p (2, operands[0])"
3927 (zero_extend:DI (match_dup 1)))])
3929 (define_mode_attr kmov_isa
3930 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
3932 (define_insn "zero_extend<mode>di2"
3933 [(set (match_operand:DI 0 "register_operand" "=r,*r")
3935 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
3938 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
3939 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
3940 [(set_attr "isa" "*,<kmov_isa>")
3941 (set_attr "type" "imovx,mskmov")
3942 (set_attr "mode" "SI,<MODE>")])
3944 (define_expand "zero_extend<mode>si2"
3945 [(set (match_operand:SI 0 "register_operand")
3946 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3949 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3951 operands[1] = force_reg (<MODE>mode, operands[1]);
3952 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3957 (define_insn_and_split "zero_extend<mode>si2_and"
3958 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3960 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3961 (clobber (reg:CC FLAGS_REG))]
3962 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3964 "&& reload_completed"
3965 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3966 (clobber (reg:CC FLAGS_REG))])]
3968 if (!REG_P (operands[1])
3969 || REGNO (operands[0]) != REGNO (operands[1]))
3971 ix86_expand_clear (operands[0]);
3973 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3974 emit_insn (gen_movstrict<mode>
3975 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3979 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3981 [(set_attr "type" "alu1")
3982 (set_attr "mode" "SI")])
3984 (define_insn "*zero_extend<mode>si2"
3985 [(set (match_operand:SI 0 "register_operand" "=r,*r")
3987 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
3988 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3990 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
3991 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
3992 [(set_attr "isa" "*,<kmov_isa>")
3993 (set_attr "type" "imovx,mskmov")
3994 (set_attr "mode" "SI,<MODE>")])
3996 (define_expand "zero_extendqihi2"
3997 [(set (match_operand:HI 0 "register_operand")
3998 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4001 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4003 operands[1] = force_reg (QImode, operands[1]);
4004 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4009 (define_insn_and_split "zero_extendqihi2_and"
4010 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4011 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4012 (clobber (reg:CC FLAGS_REG))]
4013 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4015 "&& reload_completed"
4016 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4017 (clobber (reg:CC FLAGS_REG))])]
4019 if (!REG_P (operands[1])
4020 || REGNO (operands[0]) != REGNO (operands[1]))
4022 ix86_expand_clear (operands[0]);
4024 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4025 emit_insn (gen_movstrictqi
4026 (gen_lowpart (QImode, operands[0]), operands[1]));
4030 operands[0] = gen_lowpart (SImode, operands[0]);
4032 [(set_attr "type" "alu1")
4033 (set_attr "mode" "SI")])
4035 ; zero extend to SImode to avoid partial register stalls
4036 (define_insn "*zero_extendqihi2"
4037 [(set (match_operand:HI 0 "register_operand" "=r,*r")
4038 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k")))]
4039 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4041 movz{bl|x}\t{%1, %k0|%k0, %1}
4042 kmovb\t{%1, %k0|%k0, %1}"
4043 [(set_attr "isa" "*,avx512dq")
4044 (set_attr "type" "imovx,mskmov")
4045 (set_attr "mode" "SI,QI")])
4047 (define_insn_and_split "*zext<mode>_doubleword_and"
4048 [(set (match_operand:DI 0 "register_operand" "=&<r>")
4049 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4050 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4051 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4053 "&& reload_completed && GENERAL_REG_P (operands[0])"
4054 [(set (match_dup 2) (const_int 0))]
4056 split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);
4058 emit_move_insn (operands[0], const0_rtx);
4060 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4061 emit_insn (gen_movstrict<mode>
4062 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4065 (define_insn_and_split "*zext<mode>_doubleword"
4066 [(set (match_operand:DI 0 "register_operand" "=r")
4067 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4068 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4069 && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4071 "&& reload_completed && GENERAL_REG_P (operands[0])"
4072 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
4073 (set (match_dup 2) (const_int 0))]
4074 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4076 (define_insn_and_split "*zextsi_doubleword"
4077 [(set (match_operand:DI 0 "register_operand" "=r")
4078 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
4079 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
4081 "&& reload_completed && GENERAL_REG_P (operands[0])"
4082 [(set (match_dup 0) (match_dup 1))
4083 (set (match_dup 2) (const_int 0))]
4084 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4086 ;; Sign extension instructions
4088 (define_expand "extendsidi2"
4089 [(set (match_operand:DI 0 "register_operand")
4090 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4095 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4100 (define_insn "*extendsidi2_rex64"
4101 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4102 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4106 movs{lq|x}\t{%1, %0|%0, %1}"
4107 [(set_attr "type" "imovx")
4108 (set_attr "mode" "DI")
4109 (set_attr "prefix_0f" "0")
4110 (set_attr "modrm" "0,1")])
4112 (define_insn "extendsidi2_1"
4113 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4114 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4115 (clobber (reg:CC FLAGS_REG))
4116 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4120 ;; Split the memory case. If the source register doesn't die, it will stay
4121 ;; this way, if it does die, following peephole2s take care of it.
4123 [(set (match_operand:DI 0 "memory_operand")
4124 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4125 (clobber (reg:CC FLAGS_REG))
4126 (clobber (match_operand:SI 2 "register_operand"))]
4130 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4132 emit_move_insn (operands[3], operands[1]);
4134 /* Generate a cltd if possible and doing so it profitable. */
4135 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4136 && REGNO (operands[1]) == AX_REG
4137 && REGNO (operands[2]) == DX_REG)
4139 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4143 emit_move_insn (operands[2], operands[1]);
4144 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4146 emit_move_insn (operands[4], operands[2]);
4150 ;; Peepholes for the case where the source register does die, after
4151 ;; being split with the above splitter.
4153 [(set (match_operand:SI 0 "memory_operand")
4154 (match_operand:SI 1 "general_reg_operand"))
4155 (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4156 (parallel [(set (match_dup 2)
4157 (ashiftrt:SI (match_dup 2) (const_int 31)))
4158 (clobber (reg:CC FLAGS_REG))])
4159 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4160 "REGNO (operands[1]) != REGNO (operands[2])
4161 && peep2_reg_dead_p (2, operands[1])
4162 && peep2_reg_dead_p (4, operands[2])
4163 && !reg_mentioned_p (operands[2], operands[3])"
4164 [(set (match_dup 0) (match_dup 1))
4165 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4166 (clobber (reg:CC FLAGS_REG))])
4167 (set (match_dup 3) (match_dup 1))])
4170 [(set (match_operand:SI 0 "memory_operand")
4171 (match_operand:SI 1 "general_reg_operand"))
4172 (parallel [(set (match_operand:SI 2 "general_reg_operand")
4173 (ashiftrt:SI (match_dup 1) (const_int 31)))
4174 (clobber (reg:CC FLAGS_REG))])
4175 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4176 "/* cltd is shorter than sarl $31, %eax */
4177 !optimize_function_for_size_p (cfun)
4178 && REGNO (operands[1]) == AX_REG
4179 && REGNO (operands[2]) == DX_REG
4180 && peep2_reg_dead_p (2, operands[1])
4181 && peep2_reg_dead_p (3, operands[2])
4182 && !reg_mentioned_p (operands[2], operands[3])"
4183 [(set (match_dup 0) (match_dup 1))
4184 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4185 (clobber (reg:CC FLAGS_REG))])
4186 (set (match_dup 3) (match_dup 1))])
4188 ;; Extend to register case. Optimize case where source and destination
4189 ;; registers match and cases where we can use cltd.
4191 [(set (match_operand:DI 0 "register_operand")
4192 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4193 (clobber (reg:CC FLAGS_REG))
4194 (clobber (match_scratch:SI 2))]
4198 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4200 if (REGNO (operands[3]) != REGNO (operands[1]))
4201 emit_move_insn (operands[3], operands[1]);
4203 /* Generate a cltd if possible and doing so it profitable. */
4204 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4205 && REGNO (operands[3]) == AX_REG
4206 && REGNO (operands[4]) == DX_REG)
4208 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4212 if (REGNO (operands[4]) != REGNO (operands[1]))
4213 emit_move_insn (operands[4], operands[1]);
4215 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4219 (define_insn "extend<mode>di2"
4220 [(set (match_operand:DI 0 "register_operand" "=r")
4222 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4224 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4225 [(set_attr "type" "imovx")
4226 (set_attr "mode" "DI")])
4228 (define_insn "extendhisi2"
4229 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4230 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4233 switch (get_attr_prefix_0f (insn))
4236 return "{cwtl|cwde}";
4238 return "movs{wl|x}\t{%1, %0|%0, %1}";
4241 [(set_attr "type" "imovx")
4242 (set_attr "mode" "SI")
4243 (set (attr "prefix_0f")
4244 ;; movsx is short decodable while cwtl is vector decoded.
4245 (if_then_else (and (eq_attr "cpu" "!k6")
4246 (eq_attr "alternative" "0"))
4248 (const_string "1")))
4249 (set (attr "znver1_decode")
4250 (if_then_else (eq_attr "prefix_0f" "0")
4251 (const_string "double")
4252 (const_string "direct")))
4254 (if_then_else (eq_attr "prefix_0f" "0")
4256 (const_string "1")))])
4258 (define_insn "*extendhisi2_zext"
4259 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4262 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4265 switch (get_attr_prefix_0f (insn))
4268 return "{cwtl|cwde}";
4270 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4273 [(set_attr "type" "imovx")
4274 (set_attr "mode" "SI")
4275 (set (attr "prefix_0f")
4276 ;; movsx is short decodable while cwtl is vector decoded.
4277 (if_then_else (and (eq_attr "cpu" "!k6")
4278 (eq_attr "alternative" "0"))
4280 (const_string "1")))
4282 (if_then_else (eq_attr "prefix_0f" "0")
4284 (const_string "1")))])
4286 (define_insn "extendqisi2"
4287 [(set (match_operand:SI 0 "register_operand" "=r")
4288 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4290 "movs{bl|x}\t{%1, %0|%0, %1}"
4291 [(set_attr "type" "imovx")
4292 (set_attr "mode" "SI")])
4294 (define_insn "*extendqisi2_zext"
4295 [(set (match_operand:DI 0 "register_operand" "=r")
4297 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4299 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4300 [(set_attr "type" "imovx")
4301 (set_attr "mode" "SI")])
4303 (define_insn "extendqihi2"
4304 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4305 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4308 switch (get_attr_prefix_0f (insn))
4311 return "{cbtw|cbw}";
4313 return "movs{bw|x}\t{%1, %0|%0, %1}";
4316 [(set_attr "type" "imovx")
4317 (set_attr "mode" "HI")
4318 (set (attr "prefix_0f")
4319 ;; movsx is short decodable while cwtl is vector decoded.
4320 (if_then_else (and (eq_attr "cpu" "!k6")
4321 (eq_attr "alternative" "0"))
4323 (const_string "1")))
4325 (if_then_else (eq_attr "prefix_0f" "0")
4327 (const_string "1")))])
4329 ;; Conversions between float and double.
4331 ;; These are all no-ops in the model used for the 80387.
4332 ;; So just emit moves.
4334 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4336 [(set (match_operand:DF 0 "push_operand")
4337 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4339 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4340 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4343 [(set (match_operand:XF 0 "push_operand")
4344 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4346 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4347 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4348 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4350 (define_expand "extendsfdf2"
4351 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4352 (float_extend:DF (match_operand:SF 1 "general_operand")))]
4353 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4355 /* ??? Needed for compress_float_constant since all fp constants
4356 are TARGET_LEGITIMATE_CONSTANT_P. */
4357 if (CONST_DOUBLE_P (operands[1]))
4359 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4360 && standard_80387_constant_p (operands[1]) > 0)
4362 operands[1] = simplify_const_unary_operation
4363 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4364 emit_move_insn_1 (operands[0], operands[1]);
4367 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4371 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4373 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4375 We do the conversion post reload to avoid producing of 128bit spills
4376 that might lead to ICE on 32bit target. The sequence unlikely combine
4379 [(set (match_operand:DF 0 "sse_reg_operand")
4381 (match_operand:SF 1 "nonimmediate_operand")))]
4382 "TARGET_USE_VECTOR_FP_CONVERTS
4383 && optimize_insn_for_speed_p ()
4385 && (!EXT_REX_SSE_REG_P (operands[0])
4386 || TARGET_AVX512VL)"
4391 (parallel [(const_int 0) (const_int 1)]))))]
4393 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4394 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4395 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4396 Try to avoid move when unpacking can be done in source. */
4397 if (REG_P (operands[1]))
4399 /* If it is unsafe to overwrite upper half of source, we need
4400 to move to destination and unpack there. */
4401 if (REGNO (operands[0]) != REGNO (operands[1])
4402 || (EXT_REX_SSE_REG_P (operands[1])
4403 && !TARGET_AVX512VL))
4405 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4406 emit_move_insn (tmp, operands[1]);
4409 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4410 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4411 =v, v, then vbroadcastss will be only needed for AVX512F without
4413 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4414 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4418 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4419 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4423 emit_insn (gen_vec_setv4sf_0 (operands[3],
4424 CONST0_RTX (V4SFmode), operands[1]));
4427 ;; It's more profitable to split and then extend in the same register.
4429 [(set (match_operand:DF 0 "sse_reg_operand")
4431 (match_operand:SF 1 "memory_operand")))]
4432 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4433 && optimize_insn_for_speed_p ()"
4434 [(set (match_dup 2) (match_dup 1))
4435 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4436 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4438 (define_insn "*extendsfdf2"
4439 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v")
4441 (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4442 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4444 switch (which_alternative)
4448 return output_387_reg_move (insn, operands);
4451 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4457 [(set_attr "type" "fmov,fmov,ssecvt")
4458 (set_attr "prefix" "orig,orig,maybe_vex")
4459 (set_attr "mode" "SF,XF,DF")
4460 (set (attr "enabled")
4462 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4464 (eq_attr "alternative" "0,1")
4465 (symbol_ref "TARGET_MIX_SSE_I387")
4466 (symbol_ref "true"))
4468 (eq_attr "alternative" "0,1")
4470 (symbol_ref "false"))))])
4472 (define_expand "extend<mode>xf2"
4473 [(set (match_operand:XF 0 "nonimmediate_operand")
4474 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4477 /* ??? Needed for compress_float_constant since all fp constants
4478 are TARGET_LEGITIMATE_CONSTANT_P. */
4479 if (CONST_DOUBLE_P (operands[1]))
4481 if (standard_80387_constant_p (operands[1]) > 0)
4483 operands[1] = simplify_const_unary_operation
4484 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4485 emit_move_insn_1 (operands[0], operands[1]);
4488 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4492 (define_insn "*extend<mode>xf2_i387"
4493 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4495 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4497 "* return output_387_reg_move (insn, operands);"
4498 [(set_attr "type" "fmov")
4499 (set_attr "mode" "<MODE>,XF")])
4501 ;; %%% This seems like bad news.
4502 ;; This cannot output into an f-reg because there is no way to be sure
4503 ;; of truncating in that case. Otherwise this is just like a simple move
4504 ;; insn. So we pretend we can output to a reg in order to get better
4505 ;; register preferencing, but we really use a stack slot.
4507 ;; Conversion from DFmode to SFmode.
4509 (define_expand "truncdfsf2"
4510 [(set (match_operand:SF 0 "nonimmediate_operand")
4512 (match_operand:DF 1 "nonimmediate_operand")))]
4513 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4515 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4517 else if (flag_unsafe_math_optimizations)
4521 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4522 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4527 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4529 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4531 We do the conversion post reload to avoid producing of 128bit spills
4532 that might lead to ICE on 32bit target. The sequence unlikely combine
4535 [(set (match_operand:SF 0 "sse_reg_operand")
4537 (match_operand:DF 1 "nonimmediate_operand")))]
4538 "TARGET_USE_VECTOR_FP_CONVERTS
4539 && optimize_insn_for_speed_p ()
4541 && (!EXT_REX_SSE_REG_P (operands[0])
4542 || TARGET_AVX512VL)"
4545 (float_truncate:V2SF
4549 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4550 operands[3] = CONST0_RTX (V2SFmode);
4551 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4552 /* Use movsd for loading from memory, unpcklpd for registers.
4553 Try to avoid move when unpacking can be done in source, or SSE3
4554 movddup is available. */
4555 if (REG_P (operands[1]))
4558 && REGNO (operands[0]) != REGNO (operands[1]))
4560 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4561 emit_move_insn (tmp, operands[1]);
4564 else if (!TARGET_SSE3)
4565 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4566 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4569 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4570 CONST0_RTX (DFmode)));
4573 ;; It's more profitable to split and then extend in the same register.
4575 [(set (match_operand:SF 0 "sse_reg_operand")
4577 (match_operand:DF 1 "memory_operand")))]
4578 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4579 && optimize_insn_for_speed_p ()"
4580 [(set (match_dup 2) (match_dup 1))
4581 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4582 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4584 (define_expand "truncdfsf2_with_temp"
4585 [(parallel [(set (match_operand:SF 0)
4586 (float_truncate:SF (match_operand:DF 1)))
4587 (clobber (match_operand:SF 2))])])
4589 ;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
4590 ;; because nothing we do there is unsafe.
4591 (define_insn "*truncdfsf_fast_mixed"
4592 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,v")
4594 (match_operand:DF 1 "nonimmediate_operand" "f ,vm")))]
4595 "TARGET_SSE2 && TARGET_SSE_MATH"
4597 switch (which_alternative)
4600 return output_387_reg_move (insn, operands);
4602 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4607 [(set_attr "type" "fmov,ssecvt")
4608 (set_attr "prefix" "orig,maybe_vex")
4609 (set_attr "mode" "SF")
4610 (set (attr "enabled")
4611 (cond [(eq_attr "alternative" "0")
4612 (symbol_ref "TARGET_MIX_SSE_I387
4613 && flag_unsafe_math_optimizations")
4615 (symbol_ref "true")))])
4617 (define_insn "*truncdfsf_fast_i387"
4618 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4620 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4621 "TARGET_80387 && flag_unsafe_math_optimizations"
4622 "* return output_387_reg_move (insn, operands);"
4623 [(set_attr "type" "fmov")
4624 (set_attr "mode" "SF")])
4626 (define_insn "*truncdfsf_mixed"
4627 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,v ,?f,?v,?*r")
4629 (match_operand:DF 1 "nonimmediate_operand" "f ,vm,f ,f ,f")))
4630 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4631 "TARGET_MIX_SSE_I387"
4633 switch (which_alternative)
4636 return output_387_reg_move (insn, operands);
4638 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4644 [(set_attr "isa" "*,sse2,*,*,*")
4645 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4646 (set_attr "unit" "*,*,i387,i387,i387")
4647 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4648 (set_attr "mode" "SF")])
4650 (define_insn "*truncdfsf_i387"
4651 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4653 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4654 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4657 switch (which_alternative)
4660 return output_387_reg_move (insn, operands);
4666 [(set_attr "type" "fmov,multi,multi,multi")
4667 (set_attr "unit" "*,i387,i387,i387")
4668 (set_attr "mode" "SF")])
4670 (define_insn "*truncdfsf2_i387_1"
4671 [(set (match_operand:SF 0 "memory_operand" "=m")
4673 (match_operand:DF 1 "register_operand" "f")))]
4675 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4676 && !TARGET_MIX_SSE_I387"
4677 "* return output_387_reg_move (insn, operands);"
4678 [(set_attr "type" "fmov")
4679 (set_attr "mode" "SF")])
4682 [(set (match_operand:SF 0 "register_operand")
4684 (match_operand:DF 1 "fp_register_operand")))
4685 (clobber (match_operand 2))]
4687 [(set (match_dup 2) (match_dup 1))
4688 (set (match_dup 0) (match_dup 2))]
4689 "operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));")
4691 ;; Conversion from XFmode to {SF,DF}mode
4693 (define_expand "truncxf<mode>2"
4694 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4695 (float_truncate:MODEF
4696 (match_operand:XF 1 "register_operand")))
4697 (clobber (match_dup 2))])]
4700 if (flag_unsafe_math_optimizations)
4702 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4703 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4704 if (reg != operands[0])
4705 emit_move_insn (operands[0], reg);
4709 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4712 (define_insn "*truncxfsf2_mixed"
4713 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4715 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4716 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4719 gcc_assert (!which_alternative);
4720 return output_387_reg_move (insn, operands);
4722 [(set_attr "type" "fmov,multi,multi,multi")
4723 (set_attr "unit" "*,i387,i387,i387")
4724 (set_attr "mode" "SF")])
4726 (define_insn "*truncxfdf2_mixed"
4727 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4729 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4730 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4733 gcc_assert (!which_alternative);
4734 return output_387_reg_move (insn, operands);
4736 [(set_attr "isa" "*,*,sse2,*")
4737 (set_attr "type" "fmov,multi,multi,multi")
4738 (set_attr "unit" "*,i387,i387,i387")
4739 (set_attr "mode" "DF")])
4741 (define_insn "truncxf<mode>2_i387_noop"
4742 [(set (match_operand:MODEF 0 "register_operand" "=f")
4743 (float_truncate:MODEF
4744 (match_operand:XF 1 "register_operand" "f")))]
4745 "TARGET_80387 && flag_unsafe_math_optimizations"
4746 "* return output_387_reg_move (insn, operands);"
4747 [(set_attr "type" "fmov")
4748 (set_attr "mode" "<MODE>")])
4750 (define_insn "*truncxf<mode>2_i387"
4751 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4752 (float_truncate:MODEF
4753 (match_operand:XF 1 "register_operand" "f")))]
4755 "* return output_387_reg_move (insn, operands);"
4756 [(set_attr "type" "fmov")
4757 (set_attr "mode" "<MODE>")])
4760 [(set (match_operand:MODEF 0 "register_operand")
4761 (float_truncate:MODEF
4762 (match_operand:XF 1 "register_operand")))
4763 (clobber (match_operand:MODEF 2 "memory_operand"))]
4764 "TARGET_80387 && reload_completed"
4765 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4766 (set (match_dup 0) (match_dup 2))])
4769 [(set (match_operand:MODEF 0 "memory_operand")
4770 (float_truncate:MODEF
4771 (match_operand:XF 1 "register_operand")))
4772 (clobber (match_operand:MODEF 2 "memory_operand"))]
4774 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4776 ;; Signed conversion to DImode.
4778 (define_expand "fix_truncxfdi2"
4779 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4780 (fix:DI (match_operand:XF 1 "register_operand")))
4781 (clobber (reg:CC FLAGS_REG))])]
4786 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4791 (define_expand "fix_trunc<mode>di2"
4792 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4793 (fix:DI (match_operand:MODEF 1 "register_operand")))
4794 (clobber (reg:CC FLAGS_REG))])]
4795 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4798 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4800 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4803 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4805 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4806 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4807 if (out != operands[0])
4808 emit_move_insn (operands[0], out);
4813 ;; Signed conversion to SImode.
4815 (define_expand "fix_truncxfsi2"
4816 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4817 (fix:SI (match_operand:XF 1 "register_operand")))
4818 (clobber (reg:CC FLAGS_REG))])]
4823 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4828 (define_expand "fix_trunc<mode>si2"
4829 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4830 (fix:SI (match_operand:MODEF 1 "register_operand")))
4831 (clobber (reg:CC FLAGS_REG))])]
4832 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4835 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4837 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4840 if (SSE_FLOAT_MODE_P (<MODE>mode))
4842 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4843 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4844 if (out != operands[0])
4845 emit_move_insn (operands[0], out);
4850 ;; Signed conversion to HImode.
4852 (define_expand "fix_trunc<mode>hi2"
4853 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4854 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4855 (clobber (reg:CC FLAGS_REG))])]
4857 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4861 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4866 ;; Unsigned conversion to SImode.
4868 (define_expand "fixuns_trunc<mode>si2"
4870 [(set (match_operand:SI 0 "register_operand")
4872 (match_operand:MODEF 1 "nonimmediate_operand")))
4874 (clobber (match_scratch:<ssevecmode> 3))
4875 (clobber (match_scratch:<ssevecmode> 4))])]
4876 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4878 machine_mode mode = <MODE>mode;
4879 machine_mode vecmode = <ssevecmode>mode;
4880 REAL_VALUE_TYPE TWO31r;
4883 if (optimize_insn_for_size_p ())
4886 real_ldexp (&TWO31r, &dconst1, 31);
4887 two31 = const_double_from_real_value (TWO31r, mode);
4888 two31 = ix86_build_const_vector (vecmode, true, two31);
4889 operands[2] = force_reg (vecmode, two31);
4892 (define_insn_and_split "*fixuns_trunc<mode>_1"
4893 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4895 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4896 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4897 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4898 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4899 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4900 && optimize_function_for_speed_p (cfun)"
4902 "&& reload_completed"
4905 ix86_split_convert_uns_si_sse (operands);
4909 ;; Unsigned conversion to HImode.
4910 ;; Without these patterns, we'll try the unsigned SI conversion which
4911 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4913 (define_expand "fixuns_trunc<mode>hi2"
4915 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4916 (set (match_operand:HI 0 "nonimmediate_operand")
4917 (subreg:HI (match_dup 2) 0))]
4918 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4919 "operands[2] = gen_reg_rtx (SImode);")
4921 ;; When SSE is available, it is always faster to use it!
4922 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4923 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4924 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
4925 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4926 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4927 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4928 [(set_attr "type" "sseicvt")
4929 (set_attr "prefix" "maybe_vex")
4930 (set (attr "prefix_rex")
4932 (match_test "<SWI48:MODE>mode == DImode")
4934 (const_string "*")))
4935 (set_attr "mode" "<MODEF:MODE>")
4936 (set_attr "athlon_decode" "double,vector")
4937 (set_attr "amdfam10_decode" "double,double")
4938 (set_attr "bdver1_decode" "double,double")])
4940 ;; Avoid vector decoded forms of the instruction.
4942 [(match_scratch:MODEF 2 "x")
4943 (set (match_operand:SWI48 0 "register_operand")
4944 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4945 "TARGET_AVOID_VECTOR_DECODE
4946 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4947 && optimize_insn_for_speed_p ()"
4948 [(set (match_dup 2) (match_dup 1))
4949 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4951 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4952 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4953 (fix:SWI248x (match_operand 1 "register_operand")))]
4954 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4956 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4957 && (TARGET_64BIT || <MODE>mode != DImode))
4959 && can_create_pseudo_p ()"
4964 if (memory_operand (operands[0], VOIDmode))
4965 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4968 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4969 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4975 [(set_attr "type" "fisttp")
4976 (set_attr "mode" "<MODE>")])
4978 (define_insn "fix_trunc<mode>_i387_fisttp"
4979 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4980 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4981 (clobber (match_scratch:XF 2 "=&1f"))]
4982 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4984 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4985 && (TARGET_64BIT || <MODE>mode != DImode))
4986 && TARGET_SSE_MATH)"
4987 "* return output_fix_trunc (insn, operands, true);"
4988 [(set_attr "type" "fisttp")
4989 (set_attr "mode" "<MODE>")])
4991 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4992 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4993 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4994 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4995 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4996 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4998 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4999 && (TARGET_64BIT || <MODE>mode != DImode))
5000 && TARGET_SSE_MATH)"
5002 [(set_attr "type" "fisttp")
5003 (set_attr "mode" "<MODE>")])
5006 [(set (match_operand:SWI248x 0 "register_operand")
5007 (fix:SWI248x (match_operand 1 "register_operand")))
5008 (clobber (match_operand:SWI248x 2 "memory_operand"))
5009 (clobber (match_scratch 3))]
5011 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
5012 (clobber (match_dup 3))])
5013 (set (match_dup 0) (match_dup 2))])
5016 [(set (match_operand:SWI248x 0 "memory_operand")
5017 (fix:SWI248x (match_operand 1 "register_operand")))
5018 (clobber (match_operand:SWI248x 2 "memory_operand"))
5019 (clobber (match_scratch 3))]
5021 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
5022 (clobber (match_dup 3))])])
5024 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5025 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5026 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5027 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5028 ;; function in i386.c.
5029 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5030 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5031 (fix:SWI248x (match_operand 1 "register_operand")))
5032 (clobber (reg:CC FLAGS_REG))]
5033 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5035 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5036 && (TARGET_64BIT || <MODE>mode != DImode))
5037 && can_create_pseudo_p ()"
5042 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5044 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5045 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5046 if (memory_operand (operands[0], VOIDmode))
5047 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5048 operands[2], operands[3]));
5051 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5052 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5053 operands[2], operands[3],
5058 [(set_attr "type" "fistp")
5059 (set_attr "i387_cw" "trunc")
5060 (set_attr "mode" "<MODE>")])
5062 (define_insn "fix_truncdi_i387"
5063 [(set (match_operand:DI 0 "memory_operand" "=m")
5064 (fix:DI (match_operand 1 "register_operand" "f")))
5065 (use (match_operand:HI 2 "memory_operand" "m"))
5066 (use (match_operand:HI 3 "memory_operand" "m"))
5067 (clobber (match_scratch:XF 4 "=&1f"))]
5068 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5070 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5071 "* return output_fix_trunc (insn, operands, false);"
5072 [(set_attr "type" "fistp")
5073 (set_attr "i387_cw" "trunc")
5074 (set_attr "mode" "DI")])
5076 (define_insn "fix_truncdi_i387_with_temp"
5077 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5078 (fix:DI (match_operand 1 "register_operand" "f,f")))
5079 (use (match_operand:HI 2 "memory_operand" "m,m"))
5080 (use (match_operand:HI 3 "memory_operand" "m,m"))
5081 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5082 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5083 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5085 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5087 [(set_attr "type" "fistp")
5088 (set_attr "i387_cw" "trunc")
5089 (set_attr "mode" "DI")])
5092 [(set (match_operand:DI 0 "register_operand")
5093 (fix:DI (match_operand 1 "register_operand")))
5094 (use (match_operand:HI 2 "memory_operand"))
5095 (use (match_operand:HI 3 "memory_operand"))
5096 (clobber (match_operand:DI 4 "memory_operand"))
5097 (clobber (match_scratch 5))]
5099 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5102 (clobber (match_dup 5))])
5103 (set (match_dup 0) (match_dup 4))])
5106 [(set (match_operand:DI 0 "memory_operand")
5107 (fix:DI (match_operand 1 "register_operand")))
5108 (use (match_operand:HI 2 "memory_operand"))
5109 (use (match_operand:HI 3 "memory_operand"))
5110 (clobber (match_operand:DI 4 "memory_operand"))
5111 (clobber (match_scratch 5))]
5113 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5116 (clobber (match_dup 5))])])
5118 (define_insn "fix_trunc<mode>_i387"
5119 [(set (match_operand:SWI24 0 "memory_operand" "=m")
5120 (fix:SWI24 (match_operand 1 "register_operand" "f")))
5121 (use (match_operand:HI 2 "memory_operand" "m"))
5122 (use (match_operand:HI 3 "memory_operand" "m"))]
5123 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5125 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5126 "* return output_fix_trunc (insn, operands, false);"
5127 [(set_attr "type" "fistp")
5128 (set_attr "i387_cw" "trunc")
5129 (set_attr "mode" "<MODE>")])
5131 (define_insn "fix_trunc<mode>_i387_with_temp"
5132 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
5133 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
5134 (use (match_operand:HI 2 "memory_operand" "m,m"))
5135 (use (match_operand:HI 3 "memory_operand" "m,m"))
5136 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
5137 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5139 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5141 [(set_attr "type" "fistp")
5142 (set_attr "i387_cw" "trunc")
5143 (set_attr "mode" "<MODE>")])
5146 [(set (match_operand:SWI24 0 "register_operand")
5147 (fix:SWI24 (match_operand 1 "register_operand")))
5148 (use (match_operand:HI 2 "memory_operand"))
5149 (use (match_operand:HI 3 "memory_operand"))
5150 (clobber (match_operand:SWI24 4 "memory_operand"))]
5152 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
5154 (use (match_dup 3))])
5155 (set (match_dup 0) (match_dup 4))])
5158 [(set (match_operand:SWI24 0 "memory_operand")
5159 (fix:SWI24 (match_operand 1 "register_operand")))
5160 (use (match_operand:HI 2 "memory_operand"))
5161 (use (match_operand:HI 3 "memory_operand"))
5162 (clobber (match_operand:SWI24 4 "memory_operand"))]
5164 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
5166 (use (match_dup 3))])])
5168 (define_insn "x86_fnstcw_1"
5169 [(set (match_operand:HI 0 "memory_operand" "=m")
5170 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5173 [(set (attr "length")
5174 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5175 (set_attr "mode" "HI")
5176 (set_attr "unit" "i387")
5177 (set_attr "bdver1_decode" "vector")])
5179 (define_insn "x86_fldcw_1"
5180 [(set (reg:HI FPCR_REG)
5181 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5184 [(set (attr "length")
5185 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5186 (set_attr "mode" "HI")
5187 (set_attr "unit" "i387")
5188 (set_attr "athlon_decode" "vector")
5189 (set_attr "amdfam10_decode" "vector")
5190 (set_attr "bdver1_decode" "vector")])
5192 ;; Conversion between fixed point and floating point.
5194 ;; Even though we only accept memory inputs, the backend _really_
5195 ;; wants to be able to do this between registers. Thankfully, LRA
5196 ;; will fix this up for us during register allocation.
5198 (define_insn "floathi<mode>2"
5199 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5200 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5202 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5203 || TARGET_MIX_SSE_I387)"
5205 [(set_attr "type" "fmov")
5206 (set_attr "mode" "<MODE>")
5207 (set_attr "znver1_decode" "double")
5208 (set_attr "fp_int_src" "true")])
5210 (define_insn "float<SWI48x:mode>xf2"
5211 [(set (match_operand:XF 0 "register_operand" "=f")
5212 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5215 [(set_attr "type" "fmov")
5216 (set_attr "mode" "XF")
5217 (set_attr "znver1_decode" "double")
5218 (set_attr "fp_int_src" "true")])
5220 (define_expand "float<SWI48:mode><MODEF:mode>2"
5221 [(set (match_operand:MODEF 0 "register_operand")
5222 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5223 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5225 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
5226 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5228 rtx reg = gen_reg_rtx (XFmode);
5229 rtx (*insn)(rtx, rtx);
5231 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
5233 if (<MODEF:MODE>mode == SFmode)
5234 insn = gen_truncxfsf2;
5235 else if (<MODEF:MODE>mode == DFmode)
5236 insn = gen_truncxfdf2;
5240 emit_insn (insn (operands[0], reg));
5245 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed"
5246 [(set (match_operand:MODEF 0 "register_operand" "=f,Yc,v")
5248 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5249 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5252 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5253 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5254 [(set_attr "type" "fmov,sseicvt,sseicvt")
5255 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5256 (set_attr "mode" "<MODEF:MODE>")
5257 (set (attr "prefix_rex")
5259 (and (eq_attr "prefix" "maybe_vex")
5260 (match_test "<SWI48:MODE>mode == DImode"))
5262 (const_string "*")))
5263 (set_attr "unit" "i387,*,*")
5264 (set_attr "athlon_decode" "*,double,direct")
5265 (set_attr "amdfam10_decode" "*,vector,double")
5266 (set_attr "bdver1_decode" "*,double,direct")
5267 (set_attr "znver1_decode" "double,*,*")
5268 (set_attr "fp_int_src" "true")
5269 (set (attr "enabled")
5270 (cond [(eq_attr "alternative" "0")
5271 (symbol_ref "TARGET_MIX_SSE_I387
5272 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5275 (symbol_ref "true")))])
5277 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
5278 [(set (match_operand:MODEF 0 "register_operand" "=f")
5279 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5280 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
5282 [(set_attr "type" "fmov")
5283 (set_attr "mode" "<MODEF:MODE>")
5284 (set_attr "znver1_decode" "double")
5285 (set_attr "fp_int_src" "true")])
5287 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5288 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5289 ;; alternative in sse2_loadld.
5291 [(set (match_operand:MODEF 0 "sse_reg_operand")
5292 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5294 && TARGET_USE_VECTOR_CONVERTS
5295 && optimize_function_for_speed_p (cfun)
5297 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5298 && (!EXT_REX_SSE_REG_P (operands[0])
5299 || TARGET_AVX512VL)"
5302 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5303 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5305 emit_insn (gen_sse2_loadld (operands[4],
5306 CONST0_RTX (V4SImode), operands[1]));
5308 if (<ssevecmode>mode == V4SFmode)
5309 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5311 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5315 ;; Avoid partial SSE register dependency stalls. This splitter should split
5316 ;; late in the pass sequence (after register rename pass), so allocated
5317 ;; registers won't change anymore
5320 [(set (match_operand:MODEF 0 "sse_reg_operand")
5321 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5322 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5323 && optimize_function_for_speed_p (cfun)
5324 && (!EXT_REX_SSE_REG_P (operands[0])
5325 || TARGET_AVX512VL)"
5327 (vec_merge:<MODEF:ssevecmode>
5328 (vec_duplicate:<MODEF:ssevecmode>
5334 const machine_mode vmode = <MODEF:ssevecmode>mode;
5336 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5337 emit_move_insn (operands[0], CONST0_RTX (vmode));
5340 ;; Break partial reg stall for cvtsd2ss. This splitter should split
5341 ;; late in the pass sequence (after register rename pass),
5342 ;; so allocated registers won't change anymore.
5345 [(set (match_operand:SF 0 "sse_reg_operand")
5347 (match_operand:DF 1 "nonimmediate_operand")))]
5348 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5349 && optimize_function_for_speed_p (cfun)
5350 && (!REG_P (operands[1])
5351 || REGNO (operands[0]) != REGNO (operands[1]))
5352 && (!EXT_REX_SSE_REG_P (operands[0])
5353 || TARGET_AVX512VL)"
5362 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5363 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5366 ;; Break partial reg stall for cvtss2sd. This splitter should split
5367 ;; late in the pass sequence (after register rename pass),
5368 ;; so allocated registers won't change anymore.
5371 [(set (match_operand:DF 0 "sse_reg_operand")
5373 (match_operand:SF 1 "nonimmediate_operand")))]
5374 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5375 && optimize_function_for_speed_p (cfun)
5376 && (!REG_P (operands[1])
5377 || REGNO (operands[0]) != REGNO (operands[1]))
5378 && (!EXT_REX_SSE_REG_P (operands[0])
5379 || TARGET_AVX512VL)"
5388 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5389 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5392 ;; Avoid store forwarding (partial memory) stall penalty
5393 ;; by passing DImode value through XMM registers. */
5395 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5396 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5398 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5399 (clobber (match_scratch:V4SI 3 "=X,x"))
5400 (clobber (match_scratch:V4SI 4 "=X,x"))
5401 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5402 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5403 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5404 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5406 [(set_attr "type" "multi")
5407 (set_attr "mode" "<X87MODEF:MODE>")
5408 (set_attr "unit" "i387")
5409 (set_attr "fp_int_src" "true")])
5412 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5413 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5414 (clobber (match_scratch:V4SI 3))
5415 (clobber (match_scratch:V4SI 4))
5416 (clobber (match_operand:DI 2 "memory_operand"))]
5417 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5418 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5419 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5420 && reload_completed"
5421 [(set (match_dup 2) (match_dup 3))
5422 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5424 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5425 Assemble the 64-bit DImode value in an xmm register. */
5426 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5427 gen_lowpart (SImode, operands[1])));
5428 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5429 gen_highpart (SImode, operands[1])));
5430 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5433 operands[3] = gen_lowpart (DImode, operands[3]);
5437 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5438 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5439 (clobber (match_scratch:V4SI 3))
5440 (clobber (match_scratch:V4SI 4))
5441 (clobber (match_operand:DI 2 "memory_operand"))]
5442 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5443 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5444 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5445 && reload_completed"
5446 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5448 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5449 [(set (match_operand:MODEF 0 "register_operand")
5450 (unsigned_float:MODEF
5451 (match_operand:SWI12 1 "nonimmediate_operand")))]
5453 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5455 operands[1] = convert_to_mode (SImode, operands[1], 1);
5456 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5460 ;; Avoid store forwarding (partial memory) stall penalty by extending
5461 ;; SImode value to DImode through XMM register instead of pushing two
5462 ;; SImode values to stack. Also note that fild loads from memory only.
5464 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5465 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5466 (unsigned_float:X87MODEF
5467 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5468 (clobber (match_scratch:DI 3 "=x"))
5469 (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5471 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5472 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5474 "&& reload_completed"
5475 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5476 (set (match_dup 2) (match_dup 3))
5478 (float:X87MODEF (match_dup 2)))]
5480 [(set_attr "type" "multi")
5481 (set_attr "mode" "<MODE>")])
5483 (define_expand "floatunssi<mode>2"
5485 [(set (match_operand:X87MODEF 0 "register_operand")
5486 (unsigned_float:X87MODEF
5487 (match_operand:SI 1 "nonimmediate_operand")))
5488 (clobber (match_scratch:DI 3))
5489 (clobber (match_dup 2))])]
5491 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5492 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5493 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5495 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5497 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5501 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5504 (define_expand "floatunsdisf2"
5505 [(use (match_operand:SF 0 "register_operand"))
5506 (use (match_operand:DI 1 "nonimmediate_operand"))]
5507 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
5508 "x86_emit_floatuns (operands); DONE;")
5510 (define_expand "floatunsdidf2"
5511 [(use (match_operand:DF 0 "register_operand"))
5512 (use (match_operand:DI 1 "nonimmediate_operand"))]
5513 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5514 && TARGET_SSE2 && TARGET_SSE_MATH"
5517 x86_emit_floatuns (operands);
5519 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5523 ;; Load effective address instructions
5525 (define_insn_and_split "*lea<mode>"
5526 [(set (match_operand:SWI48 0 "register_operand" "=r")
5527 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5530 if (SImode_address_operand (operands[1], VOIDmode))
5532 gcc_assert (TARGET_64BIT);
5533 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5536 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5538 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5541 machine_mode mode = <MODE>mode;
5544 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5545 change operands[] array behind our back. */
5546 pat = PATTERN (curr_insn);
5548 operands[0] = SET_DEST (pat);
5549 operands[1] = SET_SRC (pat);
5551 /* Emit all operations in SImode for zero-extended addresses. */
5552 if (SImode_address_operand (operands[1], VOIDmode))
5555 ix86_split_lea_for_addr (curr_insn, operands, mode);
5557 /* Zero-extend return register to DImode for zero-extended addresses. */
5558 if (mode != <MODE>mode)
5559 emit_insn (gen_zero_extendsidi2
5560 (operands[0], gen_lowpart (mode, operands[0])));
5564 [(set_attr "type" "lea")
5567 (match_operand 1 "SImode_address_operand")
5569 (const_string "<MODE>")))])
5573 (define_expand "add<mode>3"
5574 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5575 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5576 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5578 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5580 (define_insn_and_split "*add<dwi>3_doubleword"
5581 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5583 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5584 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
5586 (clobber (reg:CC FLAGS_REG))]
5587 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5590 [(parallel [(set (reg:CCC FLAGS_REG)
5592 (plus:DWIH (match_dup 1) (match_dup 2))
5595 (plus:DWIH (match_dup 1) (match_dup 2)))])
5596 (parallel [(set (match_dup 3)
5599 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5602 (clobber (reg:CC FLAGS_REG))])]
5604 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5605 if (operands[2] == const0_rtx)
5607 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5612 (define_insn "*add<mode>_1"
5613 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5615 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5616 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5617 (clobber (reg:CC FLAGS_REG))]
5618 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5620 switch (get_attr_type (insn))
5626 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5627 if (operands[2] == const1_rtx)
5628 return "inc{<imodesuffix>}\t%0";
5631 gcc_assert (operands[2] == constm1_rtx);
5632 return "dec{<imodesuffix>}\t%0";
5636 /* For most processors, ADD is faster than LEA. This alternative
5637 was added to use ADD as much as possible. */
5638 if (which_alternative == 2)
5639 std::swap (operands[1], operands[2]);
5641 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5642 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5643 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5645 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5649 (cond [(eq_attr "alternative" "3")
5650 (const_string "lea")
5651 (match_operand:SWI48 2 "incdec_operand")
5652 (const_string "incdec")
5654 (const_string "alu")))
5655 (set (attr "length_immediate")
5657 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5659 (const_string "*")))
5660 (set_attr "mode" "<MODE>")])
5662 ;; It may seem that nonimmediate operand is proper one for operand 1.
5663 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5664 ;; we take care in ix86_binary_operator_ok to not allow two memory
5665 ;; operands so proper swapping will be done in reload. This allow
5666 ;; patterns constructed from addsi_1 to match.
5668 (define_insn "addsi_1_zext"
5669 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5671 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5672 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5673 (clobber (reg:CC FLAGS_REG))]
5674 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5676 switch (get_attr_type (insn))
5682 if (operands[2] == const1_rtx)
5683 return "inc{l}\t%k0";
5686 gcc_assert (operands[2] == constm1_rtx);
5687 return "dec{l}\t%k0";
5691 /* For most processors, ADD is faster than LEA. This alternative
5692 was added to use ADD as much as possible. */
5693 if (which_alternative == 1)
5694 std::swap (operands[1], operands[2]);
5696 if (x86_maybe_negate_const_int (&operands[2], SImode))
5697 return "sub{l}\t{%2, %k0|%k0, %2}";
5699 return "add{l}\t{%2, %k0|%k0, %2}";
5703 (cond [(eq_attr "alternative" "2")
5704 (const_string "lea")
5705 (match_operand:SI 2 "incdec_operand")
5706 (const_string "incdec")
5708 (const_string "alu")))
5709 (set (attr "length_immediate")
5711 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5713 (const_string "*")))
5714 (set_attr "mode" "SI")])
5716 (define_insn "*addhi_1"
5717 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5718 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5719 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5720 (clobber (reg:CC FLAGS_REG))]
5721 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5723 switch (get_attr_type (insn))
5729 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5730 if (operands[2] == const1_rtx)
5731 return "inc{w}\t%0";
5734 gcc_assert (operands[2] == constm1_rtx);
5735 return "dec{w}\t%0";
5739 /* For most processors, ADD is faster than LEA. This alternative
5740 was added to use ADD as much as possible. */
5741 if (which_alternative == 2)
5742 std::swap (operands[1], operands[2]);
5744 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5745 if (x86_maybe_negate_const_int (&operands[2], HImode))
5746 return "sub{w}\t{%2, %0|%0, %2}";
5748 return "add{w}\t{%2, %0|%0, %2}";
5752 (cond [(eq_attr "alternative" "3")
5753 (const_string "lea")
5754 (match_operand:HI 2 "incdec_operand")
5755 (const_string "incdec")
5757 (const_string "alu")))
5758 (set (attr "length_immediate")
5760 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5762 (const_string "*")))
5763 (set_attr "mode" "HI,HI,HI,SI")])
5765 (define_insn "*addqi_1"
5766 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5767 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5768 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5769 (clobber (reg:CC FLAGS_REG))]
5770 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5772 bool widen = (get_attr_mode (insn) != MODE_QI);
5774 switch (get_attr_type (insn))
5780 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5781 if (operands[2] == const1_rtx)
5782 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5785 gcc_assert (operands[2] == constm1_rtx);
5786 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5790 /* For most processors, ADD is faster than LEA. These alternatives
5791 were added to use ADD as much as possible. */
5792 if (which_alternative == 2 || which_alternative == 4)
5793 std::swap (operands[1], operands[2]);
5795 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5796 if (x86_maybe_negate_const_int (&operands[2], QImode))
5799 return "sub{l}\t{%2, %k0|%k0, %2}";
5801 return "sub{b}\t{%2, %0|%0, %2}";
5804 return "add{l}\t{%k2, %k0|%k0, %k2}";
5806 return "add{b}\t{%2, %0|%0, %2}";
5810 (cond [(eq_attr "alternative" "5")
5811 (const_string "lea")
5812 (match_operand:QI 2 "incdec_operand")
5813 (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" "QI,QI,QI,SI,SI,SI")
5822 ;; Potential partial reg stall on alternatives 3 and 4.
5823 (set (attr "preferred_for_speed")
5824 (cond [(eq_attr "alternative" "3,4")
5825 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
5826 (symbol_ref "true")))])
5828 (define_insn "*addqi_1_slp"
5829 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5830 (plus:QI (match_dup 0)
5831 (match_operand:QI 1 "general_operand" "qn,qm")))
5832 (clobber (reg:CC FLAGS_REG))]
5833 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5834 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5836 switch (get_attr_type (insn))
5839 if (operands[1] == const1_rtx)
5840 return "inc{b}\t%0";
5843 gcc_assert (operands[1] == constm1_rtx);
5844 return "dec{b}\t%0";
5848 if (x86_maybe_negate_const_int (&operands[1], QImode))
5849 return "sub{b}\t{%1, %0|%0, %1}";
5851 return "add{b}\t{%1, %0|%0, %1}";
5855 (if_then_else (match_operand:QI 1 "incdec_operand")
5856 (const_string "incdec")
5857 (const_string "alu1")))
5858 (set (attr "memory")
5859 (if_then_else (match_operand 1 "memory_operand")
5860 (const_string "load")
5861 (const_string "none")))
5862 (set_attr "mode" "QI")])
5864 ;; Split non destructive adds if we cannot use lea.
5866 [(set (match_operand:SWI48 0 "register_operand")
5867 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5868 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5869 (clobber (reg:CC FLAGS_REG))]
5870 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5871 [(set (match_dup 0) (match_dup 1))
5872 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5873 (clobber (reg:CC FLAGS_REG))])])
5875 ;; Split non destructive adds if we cannot use lea.
5877 [(set (match_operand:DI 0 "register_operand")
5879 (plus:SI (match_operand:SI 1 "register_operand")
5880 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5881 (clobber (reg:CC FLAGS_REG))]
5883 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5884 [(set (match_dup 3) (match_dup 1))
5885 (parallel [(set (match_dup 0)
5886 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5887 (clobber (reg:CC FLAGS_REG))])]
5888 "operands[3] = gen_lowpart (SImode, operands[0]);")
5890 ;; Convert add to the lea pattern to avoid flags dependency.
5892 [(set (match_operand:SWI 0 "register_operand")
5893 (plus:SWI (match_operand:SWI 1 "register_operand")
5894 (match_operand:SWI 2 "<nonmemory_operand>")))
5895 (clobber (reg:CC FLAGS_REG))]
5896 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5898 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
5900 if (<MODE>mode != <LEAMODE>mode)
5902 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
5903 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
5904 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
5908 ;; Convert add to the lea pattern to avoid flags dependency.
5910 [(set (match_operand:DI 0 "register_operand")
5912 (plus:SI (match_operand:SI 1 "register_operand")
5913 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5914 (clobber (reg:CC FLAGS_REG))]
5915 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5917 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5919 (define_insn "*add<mode>_2"
5920 [(set (reg FLAGS_REG)
5923 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5924 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5926 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5927 (plus:SWI (match_dup 1) (match_dup 2)))]
5928 "ix86_match_ccmode (insn, CCGOCmode)
5929 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5931 switch (get_attr_type (insn))
5934 if (operands[2] == const1_rtx)
5935 return "inc{<imodesuffix>}\t%0";
5938 gcc_assert (operands[2] == constm1_rtx);
5939 return "dec{<imodesuffix>}\t%0";
5943 if (which_alternative == 2)
5944 std::swap (operands[1], operands[2]);
5946 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5947 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5948 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5950 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5954 (if_then_else (match_operand:SWI 2 "incdec_operand")
5955 (const_string "incdec")
5956 (const_string "alu")))
5957 (set (attr "length_immediate")
5959 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5961 (const_string "*")))
5962 (set_attr "mode" "<MODE>")])
5964 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5965 (define_insn "*addsi_2_zext"
5966 [(set (reg FLAGS_REG)
5968 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5969 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5971 (set (match_operand:DI 0 "register_operand" "=r,r")
5972 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5973 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5974 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5976 switch (get_attr_type (insn))
5979 if (operands[2] == const1_rtx)
5980 return "inc{l}\t%k0";
5983 gcc_assert (operands[2] == constm1_rtx);
5984 return "dec{l}\t%k0";
5988 if (which_alternative == 1)
5989 std::swap (operands[1], operands[2]);
5991 if (x86_maybe_negate_const_int (&operands[2], SImode))
5992 return "sub{l}\t{%2, %k0|%k0, %2}";
5994 return "add{l}\t{%2, %k0|%k0, %2}";
5998 (if_then_else (match_operand:SI 2 "incdec_operand")
5999 (const_string "incdec")
6000 (const_string "alu")))
6001 (set (attr "length_immediate")
6003 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6005 (const_string "*")))
6006 (set_attr "mode" "SI")])
6008 (define_insn "*add<mode>_3"
6009 [(set (reg FLAGS_REG)
6011 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6012 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6013 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6014 "ix86_match_ccmode (insn, CCZmode)
6015 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6017 switch (get_attr_type (insn))
6020 if (operands[2] == const1_rtx)
6021 return "inc{<imodesuffix>}\t%0";
6024 gcc_assert (operands[2] == constm1_rtx);
6025 return "dec{<imodesuffix>}\t%0";
6029 if (which_alternative == 1)
6030 std::swap (operands[1], operands[2]);
6032 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6033 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6034 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6036 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6040 (if_then_else (match_operand:SWI 2 "incdec_operand")
6041 (const_string "incdec")
6042 (const_string "alu")))
6043 (set (attr "length_immediate")
6045 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6047 (const_string "*")))
6048 (set_attr "mode" "<MODE>")])
6050 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6051 (define_insn "*addsi_3_zext"
6052 [(set (reg FLAGS_REG)
6054 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6055 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6056 (set (match_operand:DI 0 "register_operand" "=r,r")
6057 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6058 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6059 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6061 switch (get_attr_type (insn))
6064 if (operands[2] == const1_rtx)
6065 return "inc{l}\t%k0";
6068 gcc_assert (operands[2] == constm1_rtx);
6069 return "dec{l}\t%k0";
6073 if (which_alternative == 1)
6074 std::swap (operands[1], operands[2]);
6076 if (x86_maybe_negate_const_int (&operands[2], SImode))
6077 return "sub{l}\t{%2, %k0|%k0, %2}";
6079 return "add{l}\t{%2, %k0|%k0, %2}";
6083 (if_then_else (match_operand:SI 2 "incdec_operand")
6084 (const_string "incdec")
6085 (const_string "alu")))
6086 (set (attr "length_immediate")
6088 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6090 (const_string "*")))
6091 (set_attr "mode" "SI")])
6093 ; For comparisons against 1, -1 and 128, we may generate better code
6094 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6095 ; is matched then. We can't accept general immediate, because for
6096 ; case of overflows, the result is messed up.
6097 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6098 ; only for comparisons not depending on it.
6100 (define_insn "*adddi_4"
6101 [(set (reg FLAGS_REG)
6103 (match_operand:DI 1 "nonimmediate_operand" "0")
6104 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6105 (clobber (match_scratch:DI 0 "=rm"))]
6107 && ix86_match_ccmode (insn, CCGCmode)"
6109 switch (get_attr_type (insn))
6112 if (operands[2] == constm1_rtx)
6113 return "inc{q}\t%0";
6116 gcc_assert (operands[2] == const1_rtx);
6117 return "dec{q}\t%0";
6121 if (x86_maybe_negate_const_int (&operands[2], DImode))
6122 return "add{q}\t{%2, %0|%0, %2}";
6124 return "sub{q}\t{%2, %0|%0, %2}";
6128 (if_then_else (match_operand:DI 2 "incdec_operand")
6129 (const_string "incdec")
6130 (const_string "alu")))
6131 (set (attr "length_immediate")
6133 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6135 (const_string "*")))
6136 (set_attr "mode" "DI")])
6138 ; For comparisons against 1, -1 and 128, we may generate better code
6139 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6140 ; is matched then. We can't accept general immediate, because for
6141 ; case of overflows, the result is messed up.
6142 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6143 ; only for comparisons not depending on it.
6145 (define_insn "*add<mode>_4"
6146 [(set (reg FLAGS_REG)
6148 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6149 (match_operand:SWI124 2 "const_int_operand" "n")))
6150 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6151 "ix86_match_ccmode (insn, CCGCmode)"
6153 switch (get_attr_type (insn))
6156 if (operands[2] == constm1_rtx)
6157 return "inc{<imodesuffix>}\t%0";
6160 gcc_assert (operands[2] == const1_rtx);
6161 return "dec{<imodesuffix>}\t%0";
6165 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6166 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6168 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6172 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6173 (const_string "incdec")
6174 (const_string "alu")))
6175 (set (attr "length_immediate")
6177 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6179 (const_string "*")))
6180 (set_attr "mode" "<MODE>")])
6182 (define_insn "*add<mode>_5"
6183 [(set (reg FLAGS_REG)
6186 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6187 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6189 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6190 "ix86_match_ccmode (insn, CCGOCmode)
6191 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6193 switch (get_attr_type (insn))
6196 if (operands[2] == const1_rtx)
6197 return "inc{<imodesuffix>}\t%0";
6200 gcc_assert (operands[2] == constm1_rtx);
6201 return "dec{<imodesuffix>}\t%0";
6205 if (which_alternative == 1)
6206 std::swap (operands[1], operands[2]);
6208 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6209 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6210 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6212 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6216 (if_then_else (match_operand:SWI 2 "incdec_operand")
6217 (const_string "incdec")
6218 (const_string "alu")))
6219 (set (attr "length_immediate")
6221 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6223 (const_string "*")))
6224 (set_attr "mode" "<MODE>")])
6226 (define_insn "addqi_ext_1"
6227 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
6233 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
6236 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
6237 (clobber (reg:CC FLAGS_REG))]
6240 switch (get_attr_type (insn))
6243 if (operands[2] == const1_rtx)
6244 return "inc{b}\t%h0";
6247 gcc_assert (operands[2] == constm1_rtx);
6248 return "dec{b}\t%h0";
6252 return "add{b}\t{%2, %h0|%h0, %2}";
6255 [(set_attr "isa" "*,nox64")
6257 (if_then_else (match_operand:QI 2 "incdec_operand")
6258 (const_string "incdec")
6259 (const_string "alu")))
6260 (set_attr "mode" "QI")])
6262 (define_insn "*addqi_ext_2"
6263 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6269 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
6273 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
6275 (const_int 8)) 0)) 0))
6276 (clobber (reg:CC FLAGS_REG))]
6278 "add{b}\t{%h2, %h0|%h0, %h2}"
6279 [(set_attr "type" "alu")
6280 (set_attr "mode" "QI")])
6282 ;; Add with jump on overflow.
6283 (define_expand "addv<mode>4"
6284 [(parallel [(set (reg:CCO FLAGS_REG)
6287 (match_operand:SWI 1 "nonimmediate_operand"))
6290 (plus:SWI (match_dup 1)
6291 (match_operand:SWI 2
6292 "<general_operand>")))))
6293 (set (match_operand:SWI 0 "register_operand")
6294 (plus:SWI (match_dup 1) (match_dup 2)))])
6295 (set (pc) (if_then_else
6296 (eq (reg:CCO FLAGS_REG) (const_int 0))
6297 (label_ref (match_operand 3))
6301 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6302 if (CONST_INT_P (operands[2]))
6303 operands[4] = operands[2];
6305 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6308 (define_insn "*addv<mode>4"
6309 [(set (reg:CCO FLAGS_REG)
6312 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6314 (match_operand:SWI 2 "<general_sext_operand>"
6317 (plus:SWI (match_dup 1) (match_dup 2)))))
6318 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6319 (plus:SWI (match_dup 1) (match_dup 2)))]
6320 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6321 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6322 [(set_attr "type" "alu")
6323 (set_attr "mode" "<MODE>")])
6325 (define_insn "*addv<mode>4_1"
6326 [(set (reg:CCO FLAGS_REG)
6329 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6330 (match_operand:<DWI> 3 "const_int_operand" "i"))
6332 (plus:SWI (match_dup 1)
6333 (match_operand:SWI 2 "x86_64_immediate_operand"
6335 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6336 (plus:SWI (match_dup 1) (match_dup 2)))]
6337 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6338 && CONST_INT_P (operands[2])
6339 && INTVAL (operands[2]) == INTVAL (operands[3])"
6340 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6341 [(set_attr "type" "alu")
6342 (set_attr "mode" "<MODE>")
6343 (set (attr "length_immediate")
6344 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6346 (match_test "<MODE_SIZE> == 8")
6348 (const_string "<MODE_SIZE>")))])
6350 (define_expand "uaddv<mode>4"
6351 [(parallel [(set (reg:CCC FLAGS_REG)
6354 (match_operand:SWI 1 "nonimmediate_operand")
6355 (match_operand:SWI 2 "<general_operand>"))
6357 (set (match_operand:SWI 0 "register_operand")
6358 (plus:SWI (match_dup 1) (match_dup 2)))])
6359 (set (pc) (if_then_else
6360 (ltu (reg:CCC FLAGS_REG) (const_int 0))
6361 (label_ref (match_operand 3))
6364 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6366 ;; The lea patterns for modes less than 32 bits need to be matched by
6367 ;; several insns converted to real lea by splitters.
6369 (define_insn_and_split "*lea<mode>_general_1"
6370 [(set (match_operand:SWI12 0 "register_operand" "=r")
6372 (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6373 (match_operand:SWI12 2 "register_operand" "r"))
6374 (match_operand:SWI12 3 "immediate_operand" "i")))]
6375 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6377 "&& reload_completed"
6380 (plus:SI (match_dup 1) (match_dup 2))
6383 operands[0] = gen_lowpart (SImode, operands[0]);
6384 operands[1] = gen_lowpart (SImode, operands[1]);
6385 operands[2] = gen_lowpart (SImode, operands[2]);
6386 operands[3] = gen_lowpart (SImode, operands[3]);
6388 [(set_attr "type" "lea")
6389 (set_attr "mode" "SI")])
6391 (define_insn_and_split "*lea<mode>_general_2"
6392 [(set (match_operand:SWI12 0 "register_operand" "=r")
6394 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6395 (match_operand 2 "const248_operand" "n"))
6396 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6397 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6399 "&& reload_completed"
6402 (mult:SI (match_dup 1) (match_dup 2))
6405 operands[0] = gen_lowpart (SImode, operands[0]);
6406 operands[1] = gen_lowpart (SImode, operands[1]);
6407 operands[3] = gen_lowpart (SImode, operands[3]);
6409 [(set_attr "type" "lea")
6410 (set_attr "mode" "SI")])
6412 (define_insn_and_split "*lea<mode>_general_2b"
6413 [(set (match_operand:SWI12 0 "register_operand" "=r")
6415 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6416 (match_operand 2 "const123_operand" "n"))
6417 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6418 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6420 "&& reload_completed"
6423 (ashift:SI (match_dup 1) (match_dup 2))
6426 operands[0] = gen_lowpart (SImode, operands[0]);
6427 operands[1] = gen_lowpart (SImode, operands[1]);
6428 operands[3] = gen_lowpart (SImode, operands[3]);
6430 [(set_attr "type" "lea")
6431 (set_attr "mode" "SI")])
6433 (define_insn_and_split "*lea<mode>_general_3"
6434 [(set (match_operand:SWI12 0 "register_operand" "=r")
6437 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6438 (match_operand 2 "const248_operand" "n"))
6439 (match_operand:SWI12 3 "register_operand" "r"))
6440 (match_operand:SWI12 4 "immediate_operand" "i")))]
6441 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6443 "&& reload_completed"
6447 (mult:SI (match_dup 1) (match_dup 2))
6451 operands[0] = gen_lowpart (SImode, operands[0]);
6452 operands[1] = gen_lowpart (SImode, operands[1]);
6453 operands[3] = gen_lowpart (SImode, operands[3]);
6454 operands[4] = gen_lowpart (SImode, operands[4]);
6456 [(set_attr "type" "lea")
6457 (set_attr "mode" "SI")])
6459 (define_insn_and_split "*lea<mode>_general_3b"
6460 [(set (match_operand:SWI12 0 "register_operand" "=r")
6463 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6464 (match_operand 2 "const123_operand" "n"))
6465 (match_operand:SWI12 3 "register_operand" "r"))
6466 (match_operand:SWI12 4 "immediate_operand" "i")))]
6467 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6469 "&& reload_completed"
6473 (ashift:SI (match_dup 1) (match_dup 2))
6477 operands[0] = gen_lowpart (SImode, operands[0]);
6478 operands[1] = gen_lowpart (SImode, operands[1]);
6479 operands[3] = gen_lowpart (SImode, operands[3]);
6480 operands[4] = gen_lowpart (SImode, operands[4]);
6482 [(set_attr "type" "lea")
6483 (set_attr "mode" "SI")])
6485 (define_insn_and_split "*lea<mode>_general_4"
6486 [(set (match_operand:SWI12 0 "register_operand" "=r")
6489 (match_operand:SWI12 1 "index_register_operand" "l")
6490 (match_operand 2 "const_0_to_3_operand" "n"))
6491 (match_operand 3 "const_int_operand" "n")))]
6492 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6493 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6494 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6496 "&& reload_completed"
6499 (mult:SI (match_dup 1) (match_dup 2))
6502 operands[0] = gen_lowpart (SImode, operands[0]);
6503 operands[1] = gen_lowpart (SImode, operands[1]);
6504 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6506 [(set_attr "type" "lea")
6507 (set_attr "mode" "SI")])
6509 (define_insn_and_split "*lea<mode>_general_4"
6510 [(set (match_operand:SWI48 0 "register_operand" "=r")
6513 (match_operand:SWI48 1 "index_register_operand" "l")
6514 (match_operand 2 "const_0_to_3_operand" "n"))
6515 (match_operand 3 "const_int_operand" "n")))]
6516 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6517 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6519 "&& reload_completed"
6522 (mult:SWI48 (match_dup 1) (match_dup 2))
6524 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6525 [(set_attr "type" "lea")
6526 (set_attr "mode" "<MODE>")])
6528 ;; Subtract instructions
6530 (define_expand "sub<mode>3"
6531 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6532 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6533 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6535 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6537 (define_insn_and_split "*sub<dwi>3_doubleword"
6538 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6540 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6541 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
6543 (clobber (reg:CC FLAGS_REG))]
6544 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6547 [(parallel [(set (reg:CC FLAGS_REG)
6548 (compare:CC (match_dup 1) (match_dup 2)))
6550 (minus:DWIH (match_dup 1) (match_dup 2)))])
6551 (parallel [(set (match_dup 3)
6555 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6557 (clobber (reg:CC FLAGS_REG))])]
6559 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6560 if (operands[2] == const0_rtx)
6562 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6567 (define_insn "*sub<mode>_1"
6568 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6570 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6571 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6572 (clobber (reg:CC FLAGS_REG))]
6573 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6574 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6575 [(set_attr "type" "alu")
6576 (set_attr "mode" "<MODE>")])
6578 (define_insn "*subsi_1_zext"
6579 [(set (match_operand:DI 0 "register_operand" "=r")
6581 (minus:SI (match_operand:SI 1 "register_operand" "0")
6582 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6583 (clobber (reg:CC FLAGS_REG))]
6584 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6585 "sub{l}\t{%2, %k0|%k0, %2}"
6586 [(set_attr "type" "alu")
6587 (set_attr "mode" "SI")])
6589 (define_insn "*subqi_1_slp"
6590 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6591 (minus:QI (match_dup 0)
6592 (match_operand:QI 1 "general_operand" "qn,qm")))
6593 (clobber (reg:CC FLAGS_REG))]
6594 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6595 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6596 "sub{b}\t{%1, %0|%0, %1}"
6597 [(set_attr "type" "alu1")
6598 (set_attr "mode" "QI")])
6600 (define_insn "*sub<mode>_2"
6601 [(set (reg FLAGS_REG)
6604 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6605 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6607 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6608 (minus:SWI (match_dup 1) (match_dup 2)))]
6609 "ix86_match_ccmode (insn, CCGOCmode)
6610 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6611 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6612 [(set_attr "type" "alu")
6613 (set_attr "mode" "<MODE>")])
6615 (define_insn "*subsi_2_zext"
6616 [(set (reg FLAGS_REG)
6618 (minus:SI (match_operand:SI 1 "register_operand" "0")
6619 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6621 (set (match_operand:DI 0 "register_operand" "=r")
6623 (minus:SI (match_dup 1)
6625 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6626 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6627 "sub{l}\t{%2, %k0|%k0, %2}"
6628 [(set_attr "type" "alu")
6629 (set_attr "mode" "SI")])
6631 ;; Subtract with jump on overflow.
6632 (define_expand "subv<mode>4"
6633 [(parallel [(set (reg:CCO FLAGS_REG)
6634 (eq:CCO (minus:<DWI>
6636 (match_operand:SWI 1 "nonimmediate_operand"))
6639 (minus:SWI (match_dup 1)
6640 (match_operand:SWI 2
6641 "<general_operand>")))))
6642 (set (match_operand:SWI 0 "register_operand")
6643 (minus:SWI (match_dup 1) (match_dup 2)))])
6644 (set (pc) (if_then_else
6645 (eq (reg:CCO FLAGS_REG) (const_int 0))
6646 (label_ref (match_operand 3))
6650 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6651 if (CONST_INT_P (operands[2]))
6652 operands[4] = operands[2];
6654 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6657 (define_insn "*subv<mode>4"
6658 [(set (reg:CCO FLAGS_REG)
6659 (eq:CCO (minus:<DWI>
6661 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6663 (match_operand:SWI 2 "<general_sext_operand>"
6666 (minus:SWI (match_dup 1) (match_dup 2)))))
6667 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6668 (minus:SWI (match_dup 1) (match_dup 2)))]
6669 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6670 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6671 [(set_attr "type" "alu")
6672 (set_attr "mode" "<MODE>")])
6674 (define_insn "*subv<mode>4_1"
6675 [(set (reg:CCO FLAGS_REG)
6676 (eq:CCO (minus:<DWI>
6678 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6679 (match_operand:<DWI> 3 "const_int_operand" "i"))
6681 (minus:SWI (match_dup 1)
6682 (match_operand:SWI 2 "x86_64_immediate_operand"
6684 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6685 (minus:SWI (match_dup 1) (match_dup 2)))]
6686 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6687 && CONST_INT_P (operands[2])
6688 && INTVAL (operands[2]) == INTVAL (operands[3])"
6689 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6690 [(set_attr "type" "alu")
6691 (set_attr "mode" "<MODE>")
6692 (set (attr "length_immediate")
6693 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6695 (match_test "<MODE_SIZE> == 8")
6697 (const_string "<MODE_SIZE>")))])
6699 (define_expand "usubv<mode>4"
6700 [(parallel [(set (reg:CC FLAGS_REG)
6702 (match_operand:SWI 1 "nonimmediate_operand")
6703 (match_operand:SWI 2 "<general_operand>")))
6704 (set (match_operand:SWI 0 "register_operand")
6705 (minus:SWI (match_dup 1) (match_dup 2)))])
6706 (set (pc) (if_then_else
6707 (ltu (reg:CC FLAGS_REG) (const_int 0))
6708 (label_ref (match_operand 3))
6711 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6713 (define_insn "*sub<mode>_3"
6714 [(set (reg FLAGS_REG)
6715 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6716 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6717 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6718 (minus:SWI (match_dup 1) (match_dup 2)))]
6719 "ix86_match_ccmode (insn, CCmode)
6720 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6721 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6722 [(set_attr "type" "alu")
6723 (set_attr "mode" "<MODE>")])
6725 (define_insn "*subsi_3_zext"
6726 [(set (reg FLAGS_REG)
6727 (compare (match_operand:SI 1 "register_operand" "0")
6728 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6729 (set (match_operand:DI 0 "register_operand" "=r")
6731 (minus:SI (match_dup 1)
6733 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6734 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6735 "sub{l}\t{%2, %1|%1, %2}"
6736 [(set_attr "type" "alu")
6737 (set_attr "mode" "SI")])
6739 ;; Add with carry and subtract with borrow
6741 (define_insn "add<mode>3_carry"
6742 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6745 (match_operator:SWI 4 "ix86_carry_flag_operator"
6746 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6747 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6748 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6749 (clobber (reg:CC FLAGS_REG))]
6750 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6751 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6752 [(set_attr "type" "alu")
6753 (set_attr "use_carry" "1")
6754 (set_attr "pent_pair" "pu")
6755 (set_attr "mode" "<MODE>")])
6757 (define_insn "*addsi3_carry_zext"
6758 [(set (match_operand:DI 0 "register_operand" "=r")
6761 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6762 [(reg FLAGS_REG) (const_int 0)])
6763 (match_operand:SI 1 "register_operand" "%0"))
6764 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6765 (clobber (reg:CC FLAGS_REG))]
6766 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6767 "adc{l}\t{%2, %k0|%k0, %2}"
6768 [(set_attr "type" "alu")
6769 (set_attr "use_carry" "1")
6770 (set_attr "pent_pair" "pu")
6771 (set_attr "mode" "SI")])
6773 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6775 (define_insn "addcarry<mode>"
6776 [(set (reg:CCC FLAGS_REG)
6780 (match_operator:SWI48 4 "ix86_carry_flag_operator"
6781 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6782 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6783 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))
6785 (set (match_operand:SWI48 0 "register_operand" "=r")
6786 (plus:SWI48 (plus:SWI48 (match_op_dup 4
6787 [(match_dup 3) (const_int 0)])
6790 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6791 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6792 [(set_attr "type" "alu")
6793 (set_attr "use_carry" "1")
6794 (set_attr "pent_pair" "pu")
6795 (set_attr "mode" "<MODE>")])
6797 (define_insn "sub<mode>3_carry"
6798 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6801 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6802 (match_operator:SWI 4 "ix86_carry_flag_operator"
6803 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6804 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6805 (clobber (reg:CC FLAGS_REG))]
6806 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6807 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6808 [(set_attr "type" "alu")
6809 (set_attr "use_carry" "1")
6810 (set_attr "pent_pair" "pu")
6811 (set_attr "mode" "<MODE>")])
6813 (define_insn "*subsi3_carry_zext"
6814 [(set (match_operand:DI 0 "register_operand" "=r")
6818 (match_operand:SI 1 "register_operand" "0")
6819 (match_operator:SI 3 "ix86_carry_flag_operator"
6820 [(reg FLAGS_REG) (const_int 0)]))
6821 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6822 (clobber (reg:CC FLAGS_REG))]
6823 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6824 "sbb{l}\t{%2, %k0|%k0, %2}"
6825 [(set_attr "type" "alu")
6826 (set_attr "use_carry" "1")
6827 (set_attr "pent_pair" "pu")
6828 (set_attr "mode" "SI")])
6830 (define_insn "subborrow<mode>"
6831 [(set (reg:CCC FLAGS_REG)
6833 (match_operand:SWI48 1 "nonimmediate_operand" "0")
6835 (match_operator:SWI48 4 "ix86_carry_flag_operator"
6836 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6837 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
6838 (set (match_operand:SWI48 0 "register_operand" "=r")
6839 (minus:SWI48 (minus:SWI48 (match_dup 1)
6841 [(match_dup 3) (const_int 0)]))
6843 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6844 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6845 [(set_attr "type" "alu")
6846 (set_attr "use_carry" "1")
6847 (set_attr "pent_pair" "pu")
6848 (set_attr "mode" "<MODE>")])
6850 ;; Overflow setting add instructions
6852 (define_expand "addqi3_cconly_overflow"
6854 [(set (reg:CCC FLAGS_REG)
6857 (match_operand:QI 0 "nonimmediate_operand")
6858 (match_operand:QI 1 "general_operand"))
6860 (clobber (match_scratch:QI 2))])]
6861 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
6863 (define_insn "*add<mode>3_cconly_overflow_1"
6864 [(set (reg:CCC FLAGS_REG)
6867 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6868 (match_operand:SWI 2 "<general_operand>" "<g>"))
6870 (clobber (match_scratch:SWI 0 "=<r>"))]
6871 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6872 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6873 [(set_attr "type" "alu")
6874 (set_attr "mode" "<MODE>")])
6876 (define_insn "*add<mode>3_cc_overflow_1"
6877 [(set (reg:CCC FLAGS_REG)
6880 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6881 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6883 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6884 (plus:SWI (match_dup 1) (match_dup 2)))]
6885 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6886 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6887 [(set_attr "type" "alu")
6888 (set_attr "mode" "<MODE>")])
6890 (define_insn "*addsi3_zext_cc_overflow_1"
6891 [(set (reg:CCC FLAGS_REG)
6894 (match_operand:SI 1 "nonimmediate_operand" "%0")
6895 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6897 (set (match_operand:DI 0 "register_operand" "=r")
6898 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6899 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6900 "add{l}\t{%2, %k0|%k0, %2}"
6901 [(set_attr "type" "alu")
6902 (set_attr "mode" "SI")])
6904 (define_insn "*add<mode>3_cconly_overflow_2"
6905 [(set (reg:CCC FLAGS_REG)
6908 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6909 (match_operand:SWI 2 "<general_operand>" "<g>"))
6911 (clobber (match_scratch:SWI 0 "=<r>"))]
6912 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6913 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6914 [(set_attr "type" "alu")
6915 (set_attr "mode" "<MODE>")])
6917 (define_insn "*add<mode>3_cc_overflow_2"
6918 [(set (reg:CCC FLAGS_REG)
6921 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6922 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6924 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6925 (plus:SWI (match_dup 1) (match_dup 2)))]
6926 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6927 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6928 [(set_attr "type" "alu")
6929 (set_attr "mode" "<MODE>")])
6931 (define_insn "*addsi3_zext_cc_overflow_2"
6932 [(set (reg:CCC FLAGS_REG)
6935 (match_operand:SI 1 "nonimmediate_operand" "%0")
6936 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6938 (set (match_operand:DI 0 "register_operand" "=r")
6939 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6940 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6941 "add{l}\t{%2, %k0|%k0, %2}"
6942 [(set_attr "type" "alu")
6943 (set_attr "mode" "SI")])
6945 ;; The patterns that match these are at the end of this file.
6947 (define_expand "<plusminus_insn>xf3"
6948 [(set (match_operand:XF 0 "register_operand")
6950 (match_operand:XF 1 "register_operand")
6951 (match_operand:XF 2 "register_operand")))]
6954 (define_expand "<plusminus_insn><mode>3"
6955 [(set (match_operand:MODEF 0 "register_operand")
6957 (match_operand:MODEF 1 "register_operand")
6958 (match_operand:MODEF 2 "nonimmediate_operand")))]
6959 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6960 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6962 ;; Multiply instructions
6964 (define_expand "mul<mode>3"
6965 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6967 (match_operand:SWIM248 1 "register_operand")
6968 (match_operand:SWIM248 2 "<general_operand>")))
6969 (clobber (reg:CC FLAGS_REG))])])
6971 (define_expand "mulqi3"
6972 [(parallel [(set (match_operand:QI 0 "register_operand")
6974 (match_operand:QI 1 "register_operand")
6975 (match_operand:QI 2 "nonimmediate_operand")))
6976 (clobber (reg:CC FLAGS_REG))])]
6977 "TARGET_QIMODE_MATH")
6980 ;; IMUL reg32/64, reg32/64, imm8 Direct
6981 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6982 ;; IMUL reg32/64, reg32/64, imm32 Direct
6983 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6984 ;; IMUL reg32/64, reg32/64 Direct
6985 ;; IMUL reg32/64, mem32/64 Direct
6987 ;; On BDVER1, all above IMULs use DirectPath
6990 ;; IMUL reg16, reg16, imm8 VectorPath
6991 ;; IMUL reg16, mem16, imm8 VectorPath
6992 ;; IMUL reg16, reg16, imm16 VectorPath
6993 ;; IMUL reg16, mem16, imm16 VectorPath
6994 ;; IMUL reg16, reg16 Direct
6995 ;; IMUL reg16, mem16 Direct
6997 ;; On BDVER1, all HI MULs use DoublePath
6999 (define_insn "*mul<mode>3_1"
7000 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
7002 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
7003 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
7004 (clobber (reg:CC FLAGS_REG))]
7005 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7007 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7008 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7009 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7010 [(set_attr "type" "imul")
7011 (set_attr "prefix_0f" "0,0,1")
7012 (set (attr "athlon_decode")
7013 (cond [(eq_attr "cpu" "athlon")
7014 (const_string "vector")
7015 (eq_attr "alternative" "1")
7016 (const_string "vector")
7017 (and (eq_attr "alternative" "2")
7018 (ior (match_test "<MODE>mode == HImode")
7019 (match_operand 1 "memory_operand")))
7020 (const_string "vector")]
7021 (const_string "direct")))
7022 (set (attr "amdfam10_decode")
7023 (cond [(and (eq_attr "alternative" "0,1")
7024 (ior (match_test "<MODE>mode == HImode")
7025 (match_operand 1 "memory_operand")))
7026 (const_string "vector")]
7027 (const_string "direct")))
7028 (set (attr "bdver1_decode")
7030 (match_test "<MODE>mode == HImode")
7031 (const_string "double")
7032 (const_string "direct")))
7033 (set_attr "mode" "<MODE>")])
7035 (define_insn "*mulsi3_1_zext"
7036 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7038 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7039 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
7040 (clobber (reg:CC FLAGS_REG))]
7042 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7044 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7045 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7046 imul{l}\t{%2, %k0|%k0, %2}"
7047 [(set_attr "type" "imul")
7048 (set_attr "prefix_0f" "0,0,1")
7049 (set (attr "athlon_decode")
7050 (cond [(eq_attr "cpu" "athlon")
7051 (const_string "vector")
7052 (eq_attr "alternative" "1")
7053 (const_string "vector")
7054 (and (eq_attr "alternative" "2")
7055 (match_operand 1 "memory_operand"))
7056 (const_string "vector")]
7057 (const_string "direct")))
7058 (set (attr "amdfam10_decode")
7059 (cond [(and (eq_attr "alternative" "0,1")
7060 (match_operand 1 "memory_operand"))
7061 (const_string "vector")]
7062 (const_string "direct")))
7063 (set_attr "bdver1_decode" "direct")
7064 (set_attr "mode" "SI")])
7066 ;;On AMDFAM10 and BDVER1
7070 (define_insn "*mulqi3_1"
7071 [(set (match_operand:QI 0 "register_operand" "=a")
7072 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7073 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7074 (clobber (reg:CC FLAGS_REG))]
7076 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7078 [(set_attr "type" "imul")
7079 (set_attr "length_immediate" "0")
7080 (set (attr "athlon_decode")
7081 (if_then_else (eq_attr "cpu" "athlon")
7082 (const_string "vector")
7083 (const_string "direct")))
7084 (set_attr "amdfam10_decode" "direct")
7085 (set_attr "bdver1_decode" "direct")
7086 (set_attr "mode" "QI")])
7088 ;; Multiply with jump on overflow.
7089 (define_expand "mulv<mode>4"
7090 [(parallel [(set (reg:CCO FLAGS_REG)
7093 (match_operand:SWI248 1 "register_operand"))
7096 (mult:SWI248 (match_dup 1)
7097 (match_operand:SWI248 2
7098 "<general_operand>")))))
7099 (set (match_operand:SWI248 0 "register_operand")
7100 (mult:SWI248 (match_dup 1) (match_dup 2)))])
7101 (set (pc) (if_then_else
7102 (eq (reg:CCO FLAGS_REG) (const_int 0))
7103 (label_ref (match_operand 3))
7107 if (CONST_INT_P (operands[2]))
7108 operands[4] = operands[2];
7110 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
7113 (define_insn "*mulv<mode>4"
7114 [(set (reg:CCO FLAGS_REG)
7117 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
7119 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
7121 (mult:SWI48 (match_dup 1) (match_dup 2)))))
7122 (set (match_operand:SWI48 0 "register_operand" "=r,r")
7123 (mult:SWI48 (match_dup 1) (match_dup 2)))]
7124 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7126 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7127 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7128 [(set_attr "type" "imul")
7129 (set_attr "prefix_0f" "0,1")
7130 (set (attr "athlon_decode")
7131 (cond [(eq_attr "cpu" "athlon")
7132 (const_string "vector")
7133 (eq_attr "alternative" "0")
7134 (const_string "vector")
7135 (and (eq_attr "alternative" "1")
7136 (match_operand 1 "memory_operand"))
7137 (const_string "vector")]
7138 (const_string "direct")))
7139 (set (attr "amdfam10_decode")
7140 (cond [(and (eq_attr "alternative" "1")
7141 (match_operand 1 "memory_operand"))
7142 (const_string "vector")]
7143 (const_string "direct")))
7144 (set_attr "bdver1_decode" "direct")
7145 (set_attr "mode" "<MODE>")])
7147 (define_insn "*mulvhi4"
7148 [(set (reg:CCO FLAGS_REG)
7151 (match_operand:HI 1 "nonimmediate_operand" "%0"))
7153 (match_operand:HI 2 "nonimmediate_operand" "mr")))
7155 (mult:HI (match_dup 1) (match_dup 2)))))
7156 (set (match_operand:HI 0 "register_operand" "=r")
7157 (mult:HI (match_dup 1) (match_dup 2)))]
7158 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7159 "imul{w}\t{%2, %0|%0, %2}"
7160 [(set_attr "type" "imul")
7161 (set_attr "prefix_0f" "1")
7162 (set_attr "athlon_decode" "vector")
7163 (set_attr "amdfam10_decode" "direct")
7164 (set_attr "bdver1_decode" "double")
7165 (set_attr "mode" "HI")])
7167 (define_insn "*mulv<mode>4_1"
7168 [(set (reg:CCO FLAGS_REG)
7171 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7172 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7174 (mult:SWI248 (match_dup 1)
7175 (match_operand:SWI248 2
7176 "<immediate_operand>" "K,<i>")))))
7177 (set (match_operand:SWI248 0 "register_operand" "=r,r")
7178 (mult:SWI248 (match_dup 1) (match_dup 2)))]
7179 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7180 && CONST_INT_P (operands[2])
7181 && INTVAL (operands[2]) == INTVAL (operands[3])"
7182 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7183 [(set_attr "type" "imul")
7184 (set (attr "prefix_0f")
7186 (match_test "<MODE>mode == HImode")
7188 (const_string "*")))
7189 (set (attr "athlon_decode")
7190 (cond [(eq_attr "cpu" "athlon")
7191 (const_string "vector")
7192 (eq_attr "alternative" "1")
7193 (const_string "vector")]
7194 (const_string "direct")))
7195 (set (attr "amdfam10_decode")
7196 (cond [(ior (match_test "<MODE>mode == HImode")
7197 (match_operand 1 "memory_operand"))
7198 (const_string "vector")]
7199 (const_string "direct")))
7200 (set (attr "bdver1_decode")
7202 (match_test "<MODE>mode == HImode")
7203 (const_string "double")
7204 (const_string "direct")))
7205 (set_attr "mode" "<MODE>")
7206 (set (attr "length_immediate")
7207 (cond [(eq_attr "alternative" "0")
7209 (match_test "<MODE_SIZE> == 8")
7211 (const_string "<MODE_SIZE>")))])
7213 (define_expand "umulv<mode>4"
7214 [(parallel [(set (reg:CCO FLAGS_REG)
7217 (match_operand:SWI248 1
7218 "nonimmediate_operand"))
7220 (match_operand:SWI248 2
7221 "nonimmediate_operand")))
7223 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7224 (set (match_operand:SWI248 0 "register_operand")
7225 (mult:SWI248 (match_dup 1) (match_dup 2)))
7226 (clobber (match_scratch:SWI248 4))])
7227 (set (pc) (if_then_else
7228 (eq (reg:CCO FLAGS_REG) (const_int 0))
7229 (label_ref (match_operand 3))
7233 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7234 operands[1] = force_reg (<MODE>mode, operands[1]);
7237 (define_insn "*umulv<mode>4"
7238 [(set (reg:CCO FLAGS_REG)
7241 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7243 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7245 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7246 (set (match_operand:SWI248 0 "register_operand" "=a")
7247 (mult:SWI248 (match_dup 1) (match_dup 2)))
7248 (clobber (match_scratch:SWI248 3 "=d"))]
7249 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7250 "mul{<imodesuffix>}\t%2"
7251 [(set_attr "type" "imul")
7252 (set_attr "length_immediate" "0")
7253 (set (attr "athlon_decode")
7254 (if_then_else (eq_attr "cpu" "athlon")
7255 (const_string "vector")
7256 (const_string "double")))
7257 (set_attr "amdfam10_decode" "double")
7258 (set_attr "bdver1_decode" "direct")
7259 (set_attr "mode" "<MODE>")])
7261 (define_expand "<u>mulvqi4"
7262 [(parallel [(set (reg:CCO FLAGS_REG)
7265 (match_operand:QI 1 "nonimmediate_operand"))
7267 (match_operand:QI 2 "nonimmediate_operand")))
7269 (mult:QI (match_dup 1) (match_dup 2)))))
7270 (set (match_operand:QI 0 "register_operand")
7271 (mult:QI (match_dup 1) (match_dup 2)))])
7272 (set (pc) (if_then_else
7273 (eq (reg:CCO FLAGS_REG) (const_int 0))
7274 (label_ref (match_operand 3))
7276 "TARGET_QIMODE_MATH"
7278 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7279 operands[1] = force_reg (QImode, operands[1]);
7282 (define_insn "*<u>mulvqi4"
7283 [(set (reg:CCO FLAGS_REG)
7286 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7288 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7290 (mult:QI (match_dup 1) (match_dup 2)))))
7291 (set (match_operand:QI 0 "register_operand" "=a")
7292 (mult:QI (match_dup 1) (match_dup 2)))]
7294 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7295 "<sgnprefix>mul{b}\t%2"
7296 [(set_attr "type" "imul")
7297 (set_attr "length_immediate" "0")
7298 (set (attr "athlon_decode")
7299 (if_then_else (eq_attr "cpu" "athlon")
7300 (const_string "vector")
7301 (const_string "direct")))
7302 (set_attr "amdfam10_decode" "direct")
7303 (set_attr "bdver1_decode" "direct")
7304 (set_attr "mode" "QI")])
7306 (define_expand "<u>mul<mode><dwi>3"
7307 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7310 (match_operand:DWIH 1 "nonimmediate_operand"))
7312 (match_operand:DWIH 2 "register_operand"))))
7313 (clobber (reg:CC FLAGS_REG))])])
7315 (define_expand "<u>mulqihi3"
7316 [(parallel [(set (match_operand:HI 0 "register_operand")
7319 (match_operand:QI 1 "nonimmediate_operand"))
7321 (match_operand:QI 2 "register_operand"))))
7322 (clobber (reg:CC FLAGS_REG))])]
7323 "TARGET_QIMODE_MATH")
7325 (define_insn "*bmi2_umul<mode><dwi>3_1"
7326 [(set (match_operand:DWIH 0 "register_operand" "=r")
7328 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7329 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7330 (set (match_operand:DWIH 1 "register_operand" "=r")
7333 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7334 (zero_extend:<DWI> (match_dup 3)))
7335 (match_operand:QI 4 "const_int_operand" "n"))))]
7336 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7337 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7338 "mulx\t{%3, %0, %1|%1, %0, %3}"
7339 [(set_attr "type" "imulx")
7340 (set_attr "prefix" "vex")
7341 (set_attr "mode" "<MODE>")])
7343 (define_insn "*umul<mode><dwi>3_1"
7344 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7347 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7349 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7350 (clobber (reg:CC FLAGS_REG))]
7351 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7354 mul{<imodesuffix>}\t%2"
7355 [(set_attr "isa" "bmi2,*")
7356 (set_attr "type" "imulx,imul")
7357 (set_attr "length_immediate" "*,0")
7358 (set (attr "athlon_decode")
7359 (cond [(eq_attr "alternative" "1")
7360 (if_then_else (eq_attr "cpu" "athlon")
7361 (const_string "vector")
7362 (const_string "double"))]
7363 (const_string "*")))
7364 (set_attr "amdfam10_decode" "*,double")
7365 (set_attr "bdver1_decode" "*,direct")
7366 (set_attr "prefix" "vex,orig")
7367 (set_attr "mode" "<MODE>")])
7369 ;; Convert mul to the mulx pattern to avoid flags dependency.
7371 [(set (match_operand:<DWI> 0 "register_operand")
7374 (match_operand:DWIH 1 "register_operand"))
7376 (match_operand:DWIH 2 "nonimmediate_operand"))))
7377 (clobber (reg:CC FLAGS_REG))]
7378 "TARGET_BMI2 && reload_completed
7379 && REGNO (operands[1]) == DX_REG"
7380 [(parallel [(set (match_dup 3)
7381 (mult:DWIH (match_dup 1) (match_dup 2)))
7385 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7386 (zero_extend:<DWI> (match_dup 2)))
7389 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7391 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7394 (define_insn "*mul<mode><dwi>3_1"
7395 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7398 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7400 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7401 (clobber (reg:CC FLAGS_REG))]
7402 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7403 "imul{<imodesuffix>}\t%2"
7404 [(set_attr "type" "imul")
7405 (set_attr "length_immediate" "0")
7406 (set (attr "athlon_decode")
7407 (if_then_else (eq_attr "cpu" "athlon")
7408 (const_string "vector")
7409 (const_string "double")))
7410 (set_attr "amdfam10_decode" "double")
7411 (set_attr "bdver1_decode" "direct")
7412 (set_attr "mode" "<MODE>")])
7414 (define_insn "*<u>mulqihi3_1"
7415 [(set (match_operand:HI 0 "register_operand" "=a")
7418 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7420 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7421 (clobber (reg:CC FLAGS_REG))]
7423 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7424 "<sgnprefix>mul{b}\t%2"
7425 [(set_attr "type" "imul")
7426 (set_attr "length_immediate" "0")
7427 (set (attr "athlon_decode")
7428 (if_then_else (eq_attr "cpu" "athlon")
7429 (const_string "vector")
7430 (const_string "direct")))
7431 (set_attr "amdfam10_decode" "direct")
7432 (set_attr "bdver1_decode" "direct")
7433 (set_attr "mode" "QI")])
7435 (define_expand "<s>mul<mode>3_highpart"
7436 [(parallel [(set (match_operand:SWI48 0 "register_operand")
7441 (match_operand:SWI48 1 "nonimmediate_operand"))
7443 (match_operand:SWI48 2 "register_operand")))
7445 (clobber (match_scratch:SWI48 4))
7446 (clobber (reg:CC FLAGS_REG))])]
7448 "operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7450 (define_insn "*<s>muldi3_highpart_1"
7451 [(set (match_operand:DI 0 "register_operand" "=d")
7456 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7458 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7460 (clobber (match_scratch:DI 3 "=1"))
7461 (clobber (reg:CC FLAGS_REG))]
7463 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7464 "<sgnprefix>mul{q}\t%2"
7465 [(set_attr "type" "imul")
7466 (set_attr "length_immediate" "0")
7467 (set (attr "athlon_decode")
7468 (if_then_else (eq_attr "cpu" "athlon")
7469 (const_string "vector")
7470 (const_string "double")))
7471 (set_attr "amdfam10_decode" "double")
7472 (set_attr "bdver1_decode" "direct")
7473 (set_attr "mode" "DI")])
7475 (define_insn "*<s>mulsi3_highpart_zext"
7476 [(set (match_operand:DI 0 "register_operand" "=d")
7477 (zero_extend:DI (truncate:SI
7479 (mult:DI (any_extend:DI
7480 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7482 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7484 (clobber (match_scratch:SI 3 "=1"))
7485 (clobber (reg:CC FLAGS_REG))]
7487 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7488 "<sgnprefix>mul{l}\t%2"
7489 [(set_attr "type" "imul")
7490 (set_attr "length_immediate" "0")
7491 (set (attr "athlon_decode")
7492 (if_then_else (eq_attr "cpu" "athlon")
7493 (const_string "vector")
7494 (const_string "double")))
7495 (set_attr "amdfam10_decode" "double")
7496 (set_attr "bdver1_decode" "direct")
7497 (set_attr "mode" "SI")])
7499 (define_insn "*<s>mulsi3_highpart_1"
7500 [(set (match_operand:SI 0 "register_operand" "=d")
7505 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7507 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7509 (clobber (match_scratch:SI 3 "=1"))
7510 (clobber (reg:CC FLAGS_REG))]
7511 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7512 "<sgnprefix>mul{l}\t%2"
7513 [(set_attr "type" "imul")
7514 (set_attr "length_immediate" "0")
7515 (set (attr "athlon_decode")
7516 (if_then_else (eq_attr "cpu" "athlon")
7517 (const_string "vector")
7518 (const_string "double")))
7519 (set_attr "amdfam10_decode" "double")
7520 (set_attr "bdver1_decode" "direct")
7521 (set_attr "mode" "SI")])
7523 ;; The patterns that match these are at the end of this file.
7525 (define_expand "mulxf3"
7526 [(set (match_operand:XF 0 "register_operand")
7527 (mult:XF (match_operand:XF 1 "register_operand")
7528 (match_operand:XF 2 "register_operand")))]
7531 (define_expand "mul<mode>3"
7532 [(set (match_operand:MODEF 0 "register_operand")
7533 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7534 (match_operand:MODEF 2 "nonimmediate_operand")))]
7535 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7536 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7538 ;; Divide instructions
7540 ;; The patterns that match these are at the end of this file.
7542 (define_expand "divxf3"
7543 [(set (match_operand:XF 0 "register_operand")
7544 (div:XF (match_operand:XF 1 "register_operand")
7545 (match_operand:XF 2 "register_operand")))]
7548 (define_expand "div<mode>3"
7549 [(set (match_operand:MODEF 0 "register_operand")
7550 (div:MODEF (match_operand:MODEF 1 "register_operand")
7551 (match_operand:MODEF 2 "nonimmediate_operand")))]
7552 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7553 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7555 if (<MODE>mode == SFmode
7556 && TARGET_SSE && TARGET_SSE_MATH
7558 && optimize_insn_for_speed_p ()
7559 && flag_finite_math_only && !flag_trapping_math
7560 && flag_unsafe_math_optimizations)
7562 ix86_emit_swdivsf (operands[0], operands[1],
7563 operands[2], SFmode);
7568 ;; Divmod instructions.
7570 (define_expand "divmod<mode>4"
7571 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7573 (match_operand:SWIM248 1 "register_operand")
7574 (match_operand:SWIM248 2 "nonimmediate_operand")))
7575 (set (match_operand:SWIM248 3 "register_operand")
7576 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7577 (clobber (reg:CC FLAGS_REG))])])
7579 ;; Split with 8bit unsigned divide:
7580 ;; if (dividend an divisor are in [0-255])
7581 ;; use 8bit unsigned integer divide
7583 ;; use original integer divide
7585 [(set (match_operand:SWI48 0 "register_operand")
7586 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7587 (match_operand:SWI48 3 "nonimmediate_operand")))
7588 (set (match_operand:SWI48 1 "register_operand")
7589 (mod:SWI48 (match_dup 2) (match_dup 3)))
7590 (clobber (reg:CC FLAGS_REG))]
7591 "TARGET_USE_8BIT_IDIV
7592 && TARGET_QIMODE_MATH
7593 && can_create_pseudo_p ()
7594 && !optimize_insn_for_size_p ()"
7596 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7598 (define_insn_and_split "divmod<mode>4_1"
7599 [(set (match_operand:SWI48 0 "register_operand" "=a")
7600 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7601 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7602 (set (match_operand:SWI48 1 "register_operand" "=&d")
7603 (mod:SWI48 (match_dup 2) (match_dup 3)))
7604 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7605 (clobber (reg:CC FLAGS_REG))]
7609 [(parallel [(set (match_dup 1)
7610 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7611 (clobber (reg:CC FLAGS_REG))])
7612 (parallel [(set (match_dup 0)
7613 (div:SWI48 (match_dup 2) (match_dup 3)))
7615 (mod:SWI48 (match_dup 2) (match_dup 3)))
7617 (clobber (reg:CC FLAGS_REG))])]
7619 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7621 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7622 operands[4] = operands[2];
7625 /* Avoid use of cltd in favor of a mov+shift. */
7626 emit_move_insn (operands[1], operands[2]);
7627 operands[4] = operands[1];
7630 [(set_attr "type" "multi")
7631 (set_attr "mode" "<MODE>")])
7633 (define_insn_and_split "*divmod<mode>4"
7634 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7635 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7636 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7637 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7638 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7639 (clobber (reg:CC FLAGS_REG))]
7643 [(parallel [(set (match_dup 1)
7644 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7645 (clobber (reg:CC FLAGS_REG))])
7646 (parallel [(set (match_dup 0)
7647 (div:SWIM248 (match_dup 2) (match_dup 3)))
7649 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7651 (clobber (reg:CC FLAGS_REG))])]
7653 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7655 if (<MODE>mode != HImode
7656 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7657 operands[4] = operands[2];
7660 /* Avoid use of cltd in favor of a mov+shift. */
7661 emit_move_insn (operands[1], operands[2]);
7662 operands[4] = operands[1];
7665 [(set_attr "type" "multi")
7666 (set_attr "mode" "<MODE>")])
7668 (define_insn "*divmod<mode>4_noext"
7669 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7670 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7671 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7672 (set (match_operand:SWIM248 1 "register_operand" "=d")
7673 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7674 (use (match_operand:SWIM248 4 "register_operand" "1"))
7675 (clobber (reg:CC FLAGS_REG))]
7677 "idiv{<imodesuffix>}\t%3"
7678 [(set_attr "type" "idiv")
7679 (set_attr "mode" "<MODE>")])
7681 (define_expand "divmodqi4"
7682 [(parallel [(set (match_operand:QI 0 "register_operand")
7684 (match_operand:QI 1 "register_operand")
7685 (match_operand:QI 2 "nonimmediate_operand")))
7686 (set (match_operand:QI 3 "register_operand")
7687 (mod:QI (match_dup 1) (match_dup 2)))
7688 (clobber (reg:CC FLAGS_REG))])]
7689 "TARGET_QIMODE_MATH"
7694 tmp0 = gen_reg_rtx (HImode);
7695 tmp1 = gen_reg_rtx (HImode);
7697 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
7698 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7699 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7701 /* Extract remainder from AH. */
7702 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7703 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
7704 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7706 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7707 set_unique_reg_note (insn, REG_EQUAL, mod);
7709 /* Extract quotient from AL. */
7710 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7712 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7713 set_unique_reg_note (insn, REG_EQUAL, div);
7718 ;; Divide AX by r/m8, with result stored in
7721 ;; Change div/mod to HImode and extend the second argument to HImode
7722 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7723 ;; combine may fail.
7724 (define_insn "divmodhiqi3"
7725 [(set (match_operand:HI 0 "register_operand" "=a")
7730 (mod:HI (match_operand:HI 1 "register_operand" "0")
7732 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7736 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7737 (clobber (reg:CC FLAGS_REG))]
7738 "TARGET_QIMODE_MATH"
7740 [(set_attr "type" "idiv")
7741 (set_attr "mode" "QI")])
7743 (define_expand "udivmod<mode>4"
7744 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7746 (match_operand:SWIM248 1 "register_operand")
7747 (match_operand:SWIM248 2 "nonimmediate_operand")))
7748 (set (match_operand:SWIM248 3 "register_operand")
7749 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7750 (clobber (reg:CC FLAGS_REG))])])
7752 ;; Split with 8bit unsigned divide:
7753 ;; if (dividend an divisor are in [0-255])
7754 ;; use 8bit unsigned integer divide
7756 ;; use original integer divide
7758 [(set (match_operand:SWI48 0 "register_operand")
7759 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7760 (match_operand:SWI48 3 "nonimmediate_operand")))
7761 (set (match_operand:SWI48 1 "register_operand")
7762 (umod:SWI48 (match_dup 2) (match_dup 3)))
7763 (clobber (reg:CC FLAGS_REG))]
7764 "TARGET_USE_8BIT_IDIV
7765 && TARGET_QIMODE_MATH
7766 && can_create_pseudo_p ()
7767 && !optimize_insn_for_size_p ()"
7769 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7771 (define_insn_and_split "udivmod<mode>4_1"
7772 [(set (match_operand:SWI48 0 "register_operand" "=a")
7773 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7774 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7775 (set (match_operand:SWI48 1 "register_operand" "=&d")
7776 (umod:SWI48 (match_dup 2) (match_dup 3)))
7777 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7778 (clobber (reg:CC FLAGS_REG))]
7782 [(set (match_dup 1) (const_int 0))
7783 (parallel [(set (match_dup 0)
7784 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7786 (umod:SWI48 (match_dup 2) (match_dup 3)))
7788 (clobber (reg:CC FLAGS_REG))])]
7790 [(set_attr "type" "multi")
7791 (set_attr "mode" "<MODE>")])
7793 (define_insn_and_split "*udivmod<mode>4"
7794 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7795 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7796 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7797 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7798 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7799 (clobber (reg:CC FLAGS_REG))]
7803 [(set (match_dup 1) (const_int 0))
7804 (parallel [(set (match_dup 0)
7805 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7807 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7809 (clobber (reg:CC FLAGS_REG))])]
7811 [(set_attr "type" "multi")
7812 (set_attr "mode" "<MODE>")])
7814 ;; Optimize division or modulo by constant power of 2, if the constant
7815 ;; materializes only after expansion.
7816 (define_insn_and_split "*udivmod<mode>4_pow2"
7817 [(set (match_operand:SWI48 0 "register_operand" "=r")
7818 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7819 (match_operand:SWI48 3 "const_int_operand" "n")))
7820 (set (match_operand:SWI48 1 "register_operand" "=r")
7821 (umod:SWI48 (match_dup 2) (match_dup 3)))
7822 (clobber (reg:CC FLAGS_REG))]
7823 "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
7824 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
7827 [(set (match_dup 1) (match_dup 2))
7828 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7829 (clobber (reg:CC FLAGS_REG))])
7830 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7831 (clobber (reg:CC FLAGS_REG))])]
7833 int v = exact_log2 (UINTVAL (operands[3]));
7834 operands[4] = GEN_INT (v);
7835 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7837 [(set_attr "type" "multi")
7838 (set_attr "mode" "<MODE>")])
7840 (define_insn "*udivmod<mode>4_noext"
7841 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7842 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7843 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7844 (set (match_operand:SWIM248 1 "register_operand" "=d")
7845 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7846 (use (match_operand:SWIM248 4 "register_operand" "1"))
7847 (clobber (reg:CC FLAGS_REG))]
7849 "div{<imodesuffix>}\t%3"
7850 [(set_attr "type" "idiv")
7851 (set_attr "mode" "<MODE>")])
7853 (define_expand "udivmodqi4"
7854 [(parallel [(set (match_operand:QI 0 "register_operand")
7856 (match_operand:QI 1 "register_operand")
7857 (match_operand:QI 2 "nonimmediate_operand")))
7858 (set (match_operand:QI 3 "register_operand")
7859 (umod:QI (match_dup 1) (match_dup 2)))
7860 (clobber (reg:CC FLAGS_REG))])]
7861 "TARGET_QIMODE_MATH"
7866 tmp0 = gen_reg_rtx (HImode);
7867 tmp1 = gen_reg_rtx (HImode);
7869 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
7870 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7871 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7873 /* Extract remainder from AH. */
7874 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7875 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
7876 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7878 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7879 set_unique_reg_note (insn, REG_EQUAL, mod);
7881 /* Extract quotient from AL. */
7882 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7884 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7885 set_unique_reg_note (insn, REG_EQUAL, div);
7890 (define_insn "udivmodhiqi3"
7891 [(set (match_operand:HI 0 "register_operand" "=a")
7896 (mod:HI (match_operand:HI 1 "register_operand" "0")
7898 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7902 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7903 (clobber (reg:CC FLAGS_REG))]
7904 "TARGET_QIMODE_MATH"
7906 [(set_attr "type" "idiv")
7907 (set_attr "mode" "QI")])
7909 ;; We cannot use div/idiv for double division, because it causes
7910 ;; "division by zero" on the overflow and that's not what we expect
7911 ;; from truncate. Because true (non truncating) double division is
7912 ;; never generated, we can't create this insn anyway.
7915 ; [(set (match_operand:SI 0 "register_operand" "=a")
7917 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7919 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7920 ; (set (match_operand:SI 3 "register_operand" "=d")
7922 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7923 ; (clobber (reg:CC FLAGS_REG))]
7925 ; "div{l}\t{%2, %0|%0, %2}"
7926 ; [(set_attr "type" "idiv")])
7928 ;;- Logical AND instructions
7930 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7931 ;; Note that this excludes ah.
7933 (define_expand "testsi_ccno_1"
7934 [(set (reg:CCNO FLAGS_REG)
7936 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7937 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7940 (define_expand "testqi_ccz_1"
7941 [(set (reg:CCZ FLAGS_REG)
7942 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7943 (match_operand:QI 1 "nonmemory_operand"))
7946 (define_expand "testdi_ccno_1"
7947 [(set (reg:CCNO FLAGS_REG)
7949 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7950 (match_operand:DI 1 "x86_64_szext_general_operand"))
7952 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7954 (define_insn "*testdi_1"
7955 [(set (reg FLAGS_REG)
7958 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7959 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7961 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7962 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7964 test{l}\t{%k1, %k0|%k0, %k1}
7965 test{l}\t{%k1, %k0|%k0, %k1}
7966 test{q}\t{%1, %0|%0, %1}
7967 test{q}\t{%1, %0|%0, %1}
7968 test{q}\t{%1, %0|%0, %1}"
7969 [(set_attr "type" "test")
7970 (set_attr "modrm" "0,1,0,1,1")
7971 (set_attr "mode" "SI,SI,DI,DI,DI")])
7973 (define_insn "*testqi_1_maybe_si"
7974 [(set (reg FLAGS_REG)
7977 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7978 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7980 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7981 && ix86_match_ccmode (insn,
7982 CONST_INT_P (operands[1])
7983 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7985 if (which_alternative == 3)
7987 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7988 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7989 return "test{l}\t{%1, %k0|%k0, %1}";
7991 return "test{b}\t{%1, %0|%0, %1}";
7993 [(set_attr "type" "test")
7994 (set_attr "modrm" "0,1,1,1")
7995 (set_attr "mode" "QI,QI,QI,SI")
7996 (set_attr "pent_pair" "uv,np,uv,np")])
7998 (define_insn "*test<mode>_1"
7999 [(set (reg FLAGS_REG)
8002 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8003 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
8005 "ix86_match_ccmode (insn, CCNOmode)
8006 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8007 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8008 [(set_attr "type" "test")
8009 (set_attr "modrm" "0,1,1")
8010 (set_attr "mode" "<MODE>")
8011 (set_attr "pent_pair" "uv,np,uv")])
8013 (define_expand "testqi_ext_1_ccno"
8014 [(set (reg:CCNO FLAGS_REG)
8018 (zero_extract:SI (match_operand 0 "ext_register_operand")
8021 (match_operand 1 "const_int_operand"))
8024 (define_insn "*testqi_ext_1"
8025 [(set (reg FLAGS_REG)
8029 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q,Q")
8032 (match_operand:QI 1 "general_operand" "QnBc,m"))
8034 "ix86_match_ccmode (insn, CCNOmode)"
8035 "test{b}\t{%1, %h0|%h0, %1}"
8036 [(set_attr "isa" "*,nox64")
8037 (set_attr "type" "test")
8038 (set_attr "mode" "QI")])
8040 (define_insn "*testqi_ext_2"
8041 [(set (reg FLAGS_REG)
8045 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q")
8049 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
8053 "ix86_match_ccmode (insn, CCNOmode)"
8054 "test{b}\t{%h1, %h0|%h0, %h1}"
8055 [(set_attr "type" "test")
8056 (set_attr "mode" "QI")])
8058 ;; Combine likes to form bit extractions for some tests. Humor it.
8059 (define_insn_and_split "*testqi_ext_3"
8060 [(set (match_operand 0 "flags_reg_operand")
8061 (match_operator 1 "compare_operator"
8062 [(zero_extract:SWI248
8063 (match_operand 2 "nonimmediate_operand" "rm")
8064 (match_operand 3 "const_int_operand" "n")
8065 (match_operand 4 "const_int_operand" "n"))
8067 "ix86_match_ccmode (insn, CCNOmode)
8068 && ((TARGET_64BIT && GET_MODE (operands[2]) == DImode)
8069 || GET_MODE (operands[2]) == SImode
8070 || GET_MODE (operands[2]) == HImode
8071 || GET_MODE (operands[2]) == QImode)
8072 /* Ensure that resulting mask is zero or sign extended operand. */
8073 && INTVAL (operands[4]) >= 0
8074 && ((INTVAL (operands[3]) > 0
8075 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
8076 || (<MODE>mode == DImode
8077 && INTVAL (operands[3]) > 32
8078 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))"
8081 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8083 rtx val = operands[2];
8084 HOST_WIDE_INT len = INTVAL (operands[3]);
8085 HOST_WIDE_INT pos = INTVAL (operands[4]);
8086 machine_mode mode = GET_MODE (val);
8090 machine_mode submode = GET_MODE (SUBREG_REG (val));
8092 /* Narrow paradoxical subregs to prevent partial register stalls. */
8093 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
8094 && GET_MODE_CLASS (submode) == MODE_INT)
8096 val = SUBREG_REG (val);
8101 /* Small HImode tests can be converted to QImode. */
8102 if (register_operand (val, HImode) && pos + len <= 8)
8104 val = gen_lowpart (QImode, val);
8108 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
8111 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
8113 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
8116 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8117 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8118 ;; this is relatively important trick.
8119 ;; Do the conversion only post-reload to avoid limiting of the register class
8122 [(set (match_operand 0 "flags_reg_operand")
8123 (match_operator 1 "compare_operator"
8124 [(and (match_operand 2 "QIreg_operand")
8125 (match_operand 3 "const_int_operand"))
8128 && GET_MODE (operands[2]) != QImode
8129 && ((ix86_match_ccmode (insn, CCZmode)
8130 && !(INTVAL (operands[3]) & ~(255 << 8)))
8131 || (ix86_match_ccmode (insn, CCNOmode)
8132 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8137 (zero_extract:SI (match_dup 2)
8143 operands[2] = gen_lowpart (SImode, operands[2]);
8144 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
8148 [(set (match_operand 0 "flags_reg_operand")
8149 (match_operator 1 "compare_operator"
8150 [(and (match_operand 2 "nonimmediate_operand")
8151 (match_operand 3 "const_int_operand"))
8154 && GET_MODE (operands[2]) != QImode
8155 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8156 && ((ix86_match_ccmode (insn, CCZmode)
8157 && !(INTVAL (operands[3]) & ~255))
8158 || (ix86_match_ccmode (insn, CCNOmode)
8159 && !(INTVAL (operands[3]) & ~127)))"
8161 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8164 operands[2] = gen_lowpart (QImode, operands[2]);
8165 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
8168 ;; %%% This used to optimize known byte-wide and operations to memory,
8169 ;; and sometimes to QImode registers. If this is considered useful,
8170 ;; it should be done with splitters.
8172 (define_expand "and<mode>3"
8173 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8174 (and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8175 (match_operand:SWIM1248x 2 "<general_szext_operand>")))]
8178 machine_mode mode = <MODE>mode;
8179 rtx (*insn) (rtx, rtx);
8181 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
8183 HOST_WIDE_INT ival = INTVAL (operands[2]);
8185 if (ival == (HOST_WIDE_INT) 0xffffffff)
8187 else if (ival == 0xffff)
8189 else if (ival == 0xff)
8193 if (mode == <MODE>mode)
8195 ix86_expand_binary_operator (AND, <MODE>mode, operands);
8199 if (<MODE>mode == DImode)
8200 insn = (mode == SImode)
8201 ? gen_zero_extendsidi2
8203 ? gen_zero_extendhidi2
8204 : gen_zero_extendqidi2;
8205 else if (<MODE>mode == SImode)
8206 insn = (mode == HImode)
8207 ? gen_zero_extendhisi2
8208 : gen_zero_extendqisi2;
8209 else if (<MODE>mode == HImode)
8210 insn = gen_zero_extendqihi2;
8214 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8218 (define_insn_and_split "*anddi3_doubleword"
8219 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8221 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8222 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8223 (clobber (reg:CC FLAGS_REG))]
8224 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8225 && ix86_binary_operator_ok (AND, DImode, operands)"
8227 "&& reload_completed"
8230 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8231 if (operands[2] == const0_rtx)
8233 operands[1] = const0_rtx;
8234 ix86_expand_move (SImode, &operands[0]);
8236 else if (operands[2] != constm1_rtx)
8237 ix86_expand_binary_operator (AND, SImode, &operands[0]);
8238 else if (operands[5] == constm1_rtx)
8239 emit_note (NOTE_INSN_DELETED);
8240 if (operands[5] == const0_rtx)
8242 operands[4] = const0_rtx;
8243 ix86_expand_move (SImode, &operands[3]);
8245 else if (operands[5] != constm1_rtx)
8246 ix86_expand_binary_operator (AND, SImode, &operands[3]);
8250 (define_insn "*anddi_1"
8251 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8253 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8254 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8255 (clobber (reg:CC FLAGS_REG))]
8256 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8258 and{l}\t{%k2, %k0|%k0, %k2}
8259 and{q}\t{%2, %0|%0, %2}
8260 and{q}\t{%2, %0|%0, %2}
8262 [(set_attr "type" "alu,alu,alu,imovx")
8263 (set_attr "length_immediate" "*,*,*,0")
8264 (set (attr "prefix_rex")
8266 (and (eq_attr "type" "imovx")
8267 (and (match_test "INTVAL (operands[2]) == 0xff")
8268 (match_operand 1 "ext_QIreg_operand")))
8270 (const_string "*")))
8271 (set_attr "mode" "SI,DI,DI,SI")])
8273 (define_insn_and_split "*anddi_1_btr"
8274 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
8276 (match_operand:DI 1 "nonimmediate_operand" "%0")
8277 (match_operand:DI 2 "const_int_operand" "n")))
8278 (clobber (reg:CC FLAGS_REG))]
8279 "TARGET_64BIT && TARGET_USE_BT
8280 && ix86_binary_operator_ok (AND, DImode, operands)
8281 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
8283 "&& reload_completed"
8284 [(parallel [(set (zero_extract:DI (match_dup 0)
8288 (clobber (reg:CC FLAGS_REG))])]
8289 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
8290 [(set_attr "type" "alu1")
8291 (set_attr "prefix_0f" "1")
8292 (set_attr "znver1_decode" "double")
8293 (set_attr "mode" "DI")])
8295 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8297 [(set (match_operand:DI 0 "register_operand")
8298 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8299 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8300 (clobber (reg:CC FLAGS_REG))]
8302 [(parallel [(set (match_dup 0)
8303 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8304 (clobber (reg:CC FLAGS_REG))])]
8305 "operands[2] = gen_lowpart (SImode, operands[2]);")
8307 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8308 (define_insn "*andsi_1_zext"
8309 [(set (match_operand:DI 0 "register_operand" "=r")
8311 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8312 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8313 (clobber (reg:CC FLAGS_REG))]
8314 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8315 "and{l}\t{%2, %k0|%k0, %2}"
8316 [(set_attr "type" "alu")
8317 (set_attr "mode" "SI")])
8319 (define_insn "*and<mode>_1"
8320 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya")
8321 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm")
8322 (match_operand:SWI24 2 "<general_operand>" "r<i>,rm,L")))
8323 (clobber (reg:CC FLAGS_REG))]
8324 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8326 and{<imodesuffix>}\t{%2, %0|%0, %2}
8327 and{<imodesuffix>}\t{%2, %0|%0, %2}
8329 [(set_attr "type" "alu,alu,imovx")
8330 (set_attr "length_immediate" "*,*,0")
8331 (set (attr "prefix_rex")
8333 (and (eq_attr "type" "imovx")
8334 (and (match_test "INTVAL (operands[2]) == 0xff")
8335 (match_operand 1 "ext_QIreg_operand")))
8337 (const_string "*")))
8338 (set_attr "mode" "<MODE>,<MODE>,SI")])
8340 (define_insn "*andqi_1"
8341 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8342 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8343 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8344 (clobber (reg:CC FLAGS_REG))]
8345 "ix86_binary_operator_ok (AND, QImode, operands)"
8347 and{b}\t{%2, %0|%0, %2}
8348 and{b}\t{%2, %0|%0, %2}
8349 and{l}\t{%k2, %k0|%k0, %k2}"
8350 [(set_attr "type" "alu")
8351 (set_attr "mode" "QI,QI,SI")
8352 ;; Potential partial reg stall on alternative 2.
8353 (set (attr "preferred_for_speed")
8354 (cond [(eq_attr "alternative" "2")
8355 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8356 (symbol_ref "true")))])
8358 (define_insn "*andqi_1_slp"
8359 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8360 (and:QI (match_dup 0)
8361 (match_operand:QI 1 "general_operand" "qn,qmn")))
8362 (clobber (reg:CC FLAGS_REG))]
8363 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8364 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8365 "and{b}\t{%1, %0|%0, %1}"
8366 [(set_attr "type" "alu1")
8367 (set_attr "mode" "QI")])
8370 [(set (match_operand:SWI248 0 "register_operand")
8371 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8372 (match_operand:SWI248 2 "const_int_operand")))
8373 (clobber (reg:CC FLAGS_REG))]
8375 && (!REG_P (operands[1])
8376 || REGNO (operands[0]) != REGNO (operands[1]))"
8379 HOST_WIDE_INT ival = INTVAL (operands[2]);
8381 rtx (*insn) (rtx, rtx);
8383 if (ival == (HOST_WIDE_INT) 0xffffffff)
8385 else if (ival == 0xffff)
8389 gcc_assert (ival == 0xff);
8393 if (<MODE>mode == DImode)
8394 insn = (mode == SImode)
8395 ? gen_zero_extendsidi2
8397 ? gen_zero_extendhidi2
8398 : gen_zero_extendqidi2;
8401 if (<MODE>mode != SImode)
8402 /* Zero extend to SImode to avoid partial register stalls. */
8403 operands[0] = gen_lowpart (SImode, operands[0]);
8405 insn = (mode == HImode)
8406 ? gen_zero_extendhisi2
8407 : gen_zero_extendqisi2;
8409 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8414 [(set (match_operand:SWI48 0 "register_operand")
8415 (and:SWI48 (match_dup 0)
8416 (const_int -65536)))
8417 (clobber (reg:CC FLAGS_REG))]
8418 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8419 || optimize_function_for_size_p (cfun)"
8420 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8421 "operands[1] = gen_lowpart (HImode, operands[0]);")
8424 [(set (match_operand:SWI248 0 "any_QIreg_operand")
8425 (and:SWI248 (match_dup 0)
8427 (clobber (reg:CC FLAGS_REG))]
8428 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8429 && reload_completed"
8430 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8431 "operands[1] = gen_lowpart (QImode, operands[0]);")
8434 [(set (match_operand:SWI248 0 "QIreg_operand")
8435 (and:SWI248 (match_dup 0)
8436 (const_int -65281)))
8437 (clobber (reg:CC FLAGS_REG))]
8438 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8439 && reload_completed"
8441 [(set (zero_extract:SI (match_dup 0)
8447 (zero_extract:SI (match_dup 0)
8451 (zero_extract:SI (match_dup 0)
8453 (const_int 8)) 0)) 0))
8454 (clobber (reg:CC FLAGS_REG))])]
8455 "operands[0] = gen_lowpart (SImode, operands[0]);")
8457 (define_insn "*anddi_2"
8458 [(set (reg FLAGS_REG)
8461 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8462 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8464 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8465 (and:DI (match_dup 1) (match_dup 2)))]
8467 && ix86_match_ccmode
8469 /* If we are going to emit andl instead of andq, and the operands[2]
8470 constant might have the SImode sign bit set, make sure the sign
8471 flag isn't tested, because the instruction will set the sign flag
8472 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8473 conservatively assume it might have bit 31 set. */
8474 (satisfies_constraint_Z (operands[2])
8475 && (!CONST_INT_P (operands[2])
8476 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8477 ? CCZmode : CCNOmode)
8478 && ix86_binary_operator_ok (AND, DImode, operands)"
8480 and{l}\t{%k2, %k0|%k0, %k2}
8481 and{q}\t{%2, %0|%0, %2}
8482 and{q}\t{%2, %0|%0, %2}"
8483 [(set_attr "type" "alu")
8484 (set_attr "mode" "SI,DI,DI")])
8486 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8487 (define_insn "*andsi_2_zext"
8488 [(set (reg FLAGS_REG)
8490 (match_operand:SI 1 "nonimmediate_operand" "%0")
8491 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8493 (set (match_operand:DI 0 "register_operand" "=r")
8494 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8495 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8496 && ix86_binary_operator_ok (AND, SImode, operands)"
8497 "and{l}\t{%2, %k0|%k0, %2}"
8498 [(set_attr "type" "alu")
8499 (set_attr "mode" "SI")])
8501 (define_insn "*andqi_2_maybe_si"
8502 [(set (reg FLAGS_REG)
8504 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8505 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8507 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8508 (and:QI (match_dup 1) (match_dup 2)))]
8509 "ix86_binary_operator_ok (AND, QImode, operands)
8510 && ix86_match_ccmode (insn,
8511 CONST_INT_P (operands[2])
8512 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8514 if (which_alternative == 2)
8516 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8517 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8518 return "and{l}\t{%2, %k0|%k0, %2}";
8520 return "and{b}\t{%2, %0|%0, %2}";
8522 [(set_attr "type" "alu")
8523 (set_attr "mode" "QI,QI,SI")])
8525 (define_insn "*and<mode>_2"
8526 [(set (reg FLAGS_REG)
8527 (compare (and:SWI124
8528 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8529 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8531 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8532 (and:SWI124 (match_dup 1) (match_dup 2)))]
8533 "ix86_match_ccmode (insn, CCNOmode)
8534 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8535 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8536 [(set_attr "type" "alu")
8537 (set_attr "mode" "<MODE>")])
8539 (define_insn "*andqi_2_slp"
8540 [(set (reg FLAGS_REG)
8542 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8543 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8545 (set (strict_low_part (match_dup 0))
8546 (and:QI (match_dup 0) (match_dup 1)))]
8547 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8548 && ix86_match_ccmode (insn, CCNOmode)
8549 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8550 "and{b}\t{%1, %0|%0, %1}"
8551 [(set_attr "type" "alu1")
8552 (set_attr "mode" "QI")])
8554 (define_insn "andqi_ext_1"
8555 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8561 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
8564 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
8565 (clobber (reg:CC FLAGS_REG))]
8567 "and{b}\t{%2, %h0|%h0, %2}"
8568 [(set_attr "isa" "*,nox64")
8569 (set_attr "type" "alu")
8570 (set_attr "mode" "QI")])
8572 ;; Generated by peephole translating test to and. This shows up
8573 ;; often in fp comparisons.
8574 (define_insn "*andqi_ext_1_cc"
8575 [(set (reg FLAGS_REG)
8579 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
8582 (match_operand:QI 2 "general_operand" "QnBc,m"))
8584 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8590 (zero_extract:SI (match_dup 1)
8594 "ix86_match_ccmode (insn, CCNOmode)"
8595 "and{b}\t{%2, %h0|%h0, %2}"
8596 [(set_attr "isa" "*,nox64")
8597 (set_attr "type" "alu")
8598 (set_attr "mode" "QI")])
8600 (define_insn "*andqi_ext_2"
8601 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8607 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
8611 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8613 (const_int 8)) 0)) 0))
8614 (clobber (reg:CC FLAGS_REG))]
8616 "and{b}\t{%h2, %h0|%h0, %h2}"
8617 [(set_attr "type" "alu")
8618 (set_attr "mode" "QI")])
8620 ;; Convert wide AND instructions with immediate operand to shorter QImode
8621 ;; equivalents when possible.
8622 ;; Don't do the splitting with memory operands, since it introduces risk
8623 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8624 ;; for size, but that can (should?) be handled by generic code instead.
8626 [(set (match_operand:SWI248 0 "QIreg_operand")
8627 (and:SWI248 (match_operand:SWI248 1 "register_operand")
8628 (match_operand:SWI248 2 "const_int_operand")))
8629 (clobber (reg:CC FLAGS_REG))]
8631 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8632 && !(~INTVAL (operands[2]) & ~(255 << 8))"
8634 [(set (zero_extract:SI (match_dup 0)
8640 (zero_extract:SI (match_dup 1)
8644 (clobber (reg:CC FLAGS_REG))])]
8646 operands[0] = gen_lowpart (SImode, operands[0]);
8647 operands[1] = gen_lowpart (SImode, operands[1]);
8648 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
8651 ;; Since AND can be encoded with sign extended immediate, this is only
8652 ;; profitable when 7th bit is not set.
8654 [(set (match_operand:SWI248 0 "any_QIreg_operand")
8655 (and:SWI248 (match_operand:SWI248 1 "general_operand")
8656 (match_operand:SWI248 2 "const_int_operand")))
8657 (clobber (reg:CC FLAGS_REG))]
8659 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8660 && !(~INTVAL (operands[2]) & ~255)
8661 && !(INTVAL (operands[2]) & 128)"
8662 [(parallel [(set (strict_low_part (match_dup 0))
8663 (and:QI (match_dup 1)
8665 (clobber (reg:CC FLAGS_REG))])]
8667 operands[0] = gen_lowpart (QImode, operands[0]);
8668 operands[1] = gen_lowpart (QImode, operands[1]);
8669 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
8672 (define_insn "*andndi3_doubleword"
8673 [(set (match_operand:DI 0 "register_operand" "=r,&r")
8675 (not:DI (match_operand:DI 1 "register_operand" "r,0"))
8676 (match_operand:DI 2 "nonimmediate_operand" "rm,rm")))
8677 (clobber (reg:CC FLAGS_REG))]
8678 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
8680 [(set_attr "isa" "bmi,*")])
8683 [(set (match_operand:DI 0 "register_operand")
8685 (not:DI (match_operand:DI 1 "register_operand"))
8686 (match_operand:DI 2 "nonimmediate_operand")))
8687 (clobber (reg:CC FLAGS_REG))]
8688 "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2
8689 && reload_completed"
8690 [(parallel [(set (match_dup 0)
8691 (and:SI (not:SI (match_dup 1)) (match_dup 2)))
8692 (clobber (reg:CC FLAGS_REG))])
8693 (parallel [(set (match_dup 3)
8694 (and:SI (not:SI (match_dup 4)) (match_dup 5)))
8695 (clobber (reg:CC FLAGS_REG))])]
8696 "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
8699 [(set (match_operand:DI 0 "register_operand")
8701 (not:DI (match_dup 0))
8702 (match_operand:DI 1 "nonimmediate_operand")))
8703 (clobber (reg:CC FLAGS_REG))]
8704 "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2
8705 && reload_completed"
8706 [(set (match_dup 0) (not:SI (match_dup 0)))
8707 (parallel [(set (match_dup 0)
8708 (and:SI (match_dup 0) (match_dup 1)))
8709 (clobber (reg:CC FLAGS_REG))])
8710 (set (match_dup 2) (not:SI (match_dup 2)))
8711 (parallel [(set (match_dup 2)
8712 (and:SI (match_dup 2) (match_dup 3)))
8713 (clobber (reg:CC FLAGS_REG))])]
8714 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
8716 (define_insn "*andn<mode>_1"
8717 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
8719 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
8720 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
8721 (clobber (reg:CC FLAGS_REG))]
8723 "andn\t{%2, %1, %0|%0, %1, %2}"
8724 [(set_attr "type" "bitmanip")
8725 (set_attr "btver2_decode" "direct, double")
8726 (set_attr "mode" "<MODE>")])
8728 (define_insn "*andn<mode>_1"
8729 [(set (match_operand:SWI12 0 "register_operand" "=r")
8731 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r"))
8732 (match_operand:SWI12 2 "register_operand" "r")))
8733 (clobber (reg:CC FLAGS_REG))]
8735 "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}"
8736 [(set_attr "type" "bitmanip")
8737 (set_attr "btver2_decode" "direct")
8738 (set_attr "mode" "SI")])
8740 (define_insn "*andn_<mode>_ccno"
8741 [(set (reg FLAGS_REG)
8744 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
8745 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
8747 (clobber (match_scratch:SWI48 0 "=r,r"))]
8748 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
8749 "andn\t{%2, %1, %0|%0, %1, %2}"
8750 [(set_attr "type" "bitmanip")
8751 (set_attr "btver2_decode" "direct, double")
8752 (set_attr "mode" "<MODE>")])
8754 ;; Logical inclusive and exclusive OR instructions
8756 ;; %%% This used to optimize known byte-wide and operations to memory.
8757 ;; If this is considered useful, it should be done with splitters.
8759 (define_expand "<code><mode>3"
8760 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8761 (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8762 (match_operand:SWIM1248x 2 "<general_operand>")))]
8764 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8766 (define_insn_and_split "*<code>di3_doubleword"
8767 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8769 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8770 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8771 (clobber (reg:CC FLAGS_REG))]
8772 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8773 && ix86_binary_operator_ok (<CODE>, DImode, operands)"
8775 "&& reload_completed"
8778 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8779 if (operands[2] == constm1_rtx)
8783 operands[1] = constm1_rtx;
8784 ix86_expand_move (SImode, &operands[0]);
8787 ix86_expand_unary_operator (NOT, SImode, &operands[0]);
8789 else if (operands[2] != const0_rtx)
8790 ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
8791 else if (operands[5] == const0_rtx)
8792 emit_note (NOTE_INSN_DELETED);
8793 if (operands[5] == constm1_rtx)
8797 operands[4] = constm1_rtx;
8798 ix86_expand_move (SImode, &operands[3]);
8801 ix86_expand_unary_operator (NOT, SImode, &operands[3]);
8803 else if (operands[5] != const0_rtx)
8804 ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
8808 (define_insn "*<code><mode>_1"
8809 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8811 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8812 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8813 (clobber (reg:CC FLAGS_REG))]
8814 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8815 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8816 [(set_attr "type" "alu")
8817 (set_attr "mode" "<MODE>")])
8819 (define_insn_and_split "*iordi_1_bts"
8820 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
8822 (match_operand:DI 1 "nonimmediate_operand" "%0")
8823 (match_operand:DI 2 "const_int_operand" "n")))
8824 (clobber (reg:CC FLAGS_REG))]
8825 "TARGET_64BIT && TARGET_USE_BT
8826 && ix86_binary_operator_ok (IOR, DImode, operands)
8827 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
8829 "&& reload_completed"
8830 [(parallel [(set (zero_extract:DI (match_dup 0)
8834 (clobber (reg:CC FLAGS_REG))])]
8835 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
8836 [(set_attr "type" "alu1")
8837 (set_attr "prefix_0f" "1")
8838 (set_attr "znver1_decode" "double")
8839 (set_attr "mode" "DI")])
8841 (define_insn_and_split "*xordi_1_btc"
8842 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
8844 (match_operand:DI 1 "nonimmediate_operand" "%0")
8845 (match_operand:DI 2 "const_int_operand" "n")))
8846 (clobber (reg:CC FLAGS_REG))]
8847 "TARGET_64BIT && TARGET_USE_BT
8848 && ix86_binary_operator_ok (XOR, DImode, operands)
8849 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
8851 "&& reload_completed"
8852 [(parallel [(set (zero_extract:DI (match_dup 0)
8855 (not:DI (zero_extract:DI (match_dup 0)
8858 (clobber (reg:CC FLAGS_REG))])]
8859 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
8860 [(set_attr "type" "alu1")
8861 (set_attr "prefix_0f" "1")
8862 (set_attr "znver1_decode" "double")
8863 (set_attr "mode" "DI")])
8865 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8866 (define_insn "*<code>si_1_zext"
8867 [(set (match_operand:DI 0 "register_operand" "=r")
8869 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8870 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8871 (clobber (reg:CC FLAGS_REG))]
8872 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8873 "<logic>{l}\t{%2, %k0|%k0, %2}"
8874 [(set_attr "type" "alu")
8875 (set_attr "mode" "SI")])
8877 (define_insn "*<code>si_1_zext_imm"
8878 [(set (match_operand:DI 0 "register_operand" "=r")
8880 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8881 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8882 (clobber (reg:CC FLAGS_REG))]
8883 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8884 "<logic>{l}\t{%2, %k0|%k0, %2}"
8885 [(set_attr "type" "alu")
8886 (set_attr "mode" "SI")])
8888 (define_insn "*<code>qi_1"
8889 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8890 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8891 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8892 (clobber (reg:CC FLAGS_REG))]
8893 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8895 <logic>{b}\t{%2, %0|%0, %2}
8896 <logic>{b}\t{%2, %0|%0, %2}
8897 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8898 [(set_attr "type" "alu")
8899 (set_attr "mode" "QI,QI,SI")
8900 ;; Potential partial reg stall on alternative 2.
8901 (set (attr "preferred_for_speed")
8902 (cond [(eq_attr "alternative" "2")
8903 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8904 (symbol_ref "true")))])
8906 (define_insn "*<code>qi_1_slp"
8907 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8908 (any_or:QI (match_dup 0)
8909 (match_operand:QI 1 "general_operand" "qmn,qn")))
8910 (clobber (reg:CC FLAGS_REG))]
8911 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8912 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8913 "<logic>{b}\t{%1, %0|%0, %1}"
8914 [(set_attr "type" "alu1")
8915 (set_attr "mode" "QI")])
8917 (define_insn "*<code><mode>_2"
8918 [(set (reg FLAGS_REG)
8919 (compare (any_or:SWI
8920 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8921 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8923 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8924 (any_or:SWI (match_dup 1) (match_dup 2)))]
8925 "ix86_match_ccmode (insn, CCNOmode)
8926 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8927 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8928 [(set_attr "type" "alu")
8929 (set_attr "mode" "<MODE>")])
8931 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8932 ;; ??? Special case for immediate operand is missing - it is tricky.
8933 (define_insn "*<code>si_2_zext"
8934 [(set (reg FLAGS_REG)
8935 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8936 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8938 (set (match_operand:DI 0 "register_operand" "=r")
8939 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8940 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8941 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8942 "<logic>{l}\t{%2, %k0|%k0, %2}"
8943 [(set_attr "type" "alu")
8944 (set_attr "mode" "SI")])
8946 (define_insn "*<code>si_2_zext_imm"
8947 [(set (reg FLAGS_REG)
8949 (match_operand:SI 1 "nonimmediate_operand" "%0")
8950 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8952 (set (match_operand:DI 0 "register_operand" "=r")
8953 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8954 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8955 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8956 "<logic>{l}\t{%2, %k0|%k0, %2}"
8957 [(set_attr "type" "alu")
8958 (set_attr "mode" "SI")])
8960 (define_insn "*<code>qi_2_slp"
8961 [(set (reg FLAGS_REG)
8962 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8963 (match_operand:QI 1 "general_operand" "qmn,qn"))
8965 (set (strict_low_part (match_dup 0))
8966 (any_or:QI (match_dup 0) (match_dup 1)))]
8967 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8968 && ix86_match_ccmode (insn, CCNOmode)
8969 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8970 "<logic>{b}\t{%1, %0|%0, %1}"
8971 [(set_attr "type" "alu1")
8972 (set_attr "mode" "QI")])
8974 (define_insn "*<code><mode>_3"
8975 [(set (reg FLAGS_REG)
8976 (compare (any_or:SWI
8977 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8978 (match_operand:SWI 2 "<general_operand>" "<g>"))
8980 (clobber (match_scratch:SWI 0 "=<r>"))]
8981 "ix86_match_ccmode (insn, CCNOmode)
8982 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8983 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8984 [(set_attr "type" "alu")
8985 (set_attr "mode" "<MODE>")])
8987 (define_insn "*<code>qi_ext_1"
8988 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8994 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
8997 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
8998 (clobber (reg:CC FLAGS_REG))]
8999 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9000 "<logic>{b}\t{%2, %h0|%h0, %2}"
9001 [(set_attr "isa" "*,nox64")
9002 (set_attr "type" "alu")
9003 (set_attr "mode" "QI")])
9005 (define_insn "*<code>qi_ext_2"
9006 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9012 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9016 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9018 (const_int 8)) 0)) 0))
9019 (clobber (reg:CC FLAGS_REG))]
9020 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9021 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9022 [(set_attr "type" "alu")
9023 (set_attr "mode" "QI")])
9025 ;; Convert wide OR instructions with immediate operand to shorter QImode
9026 ;; equivalents when possible.
9027 ;; Don't do the splitting with memory operands, since it introduces risk
9028 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9029 ;; for size, but that can (should?) be handled by generic code instead.
9031 [(set (match_operand:SWI248 0 "QIreg_operand")
9032 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
9033 (match_operand:SWI248 2 "const_int_operand")))
9034 (clobber (reg:CC FLAGS_REG))]
9036 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9037 && !(INTVAL (operands[2]) & ~(255 << 8))"
9039 [(set (zero_extract:SI (match_dup 0)
9045 (zero_extract:SI (match_dup 1)
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, QImode);
9056 ;; Since OR can be encoded with sign extended immediate, this is only
9057 ;; profitable when 7th bit is set.
9059 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9060 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
9061 (match_operand:SWI248 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 [(parallel [(set (strict_low_part (match_dup 0))
9068 (any_or:QI (match_dup 1)
9070 (clobber (reg:CC FLAGS_REG))])]
9072 operands[0] = gen_lowpart (QImode, operands[0]);
9073 operands[1] = gen_lowpart (QImode, operands[1]);
9074 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9077 (define_expand "xorqi_ext_1_cc"
9079 (set (reg:CCNO FLAGS_REG)
9083 (zero_extract:SI (match_operand 1 "ext_register_operand")
9086 (match_operand 2 "const_int_operand"))
9088 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9094 (zero_extract:SI (match_dup 1)
9097 (match_dup 2)) 0))])])
9099 (define_insn "*xorqi_ext_1_cc"
9100 [(set (reg FLAGS_REG)
9104 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9107 (match_operand:QI 2 "general_operand" "QnBc,m"))
9109 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
9115 (zero_extract:SI (match_dup 1)
9119 "ix86_match_ccmode (insn, CCNOmode)"
9120 "xor{b}\t{%2, %h0|%h0, %2}"
9121 [(set_attr "isa" "*,nox64")
9122 (set_attr "type" "alu")
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:SWIM1248x 0 "nonimmediate_operand")
9516 (not:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")))]
9518 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9520 (define_insn_and_split "*one_cmpldi2_doubleword"
9521 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9522 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9523 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9524 && ix86_unary_operator_ok (NOT, DImode, operands)"
9526 "&& reload_completed"
9528 (not:SI (match_dup 1)))
9530 (not:SI (match_dup 3)))]
9531 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
9533 (define_insn "*one_cmpl<mode>2_1"
9534 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9535 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9536 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9537 "not{<imodesuffix>}\t%0"
9538 [(set_attr "type" "negnot")
9539 (set_attr "mode" "<MODE>")])
9541 ;; ??? Currently never generated - xor is used instead.
9542 (define_insn "*one_cmplsi2_1_zext"
9543 [(set (match_operand:DI 0 "register_operand" "=r")
9545 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9546 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9548 [(set_attr "type" "negnot")
9549 (set_attr "mode" "SI")])
9551 (define_insn "*one_cmplqi2_1"
9552 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9553 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9554 "ix86_unary_operator_ok (NOT, QImode, operands)"
9558 [(set_attr "type" "negnot")
9559 (set_attr "mode" "QI,SI")
9560 ;; Potential partial reg stall on alternative 1.
9561 (set (attr "preferred_for_speed")
9562 (cond [(eq_attr "alternative" "1")
9563 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9564 (symbol_ref "true")))])
9566 (define_insn "*one_cmpl<mode>2_2"
9567 [(set (reg FLAGS_REG)
9568 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9570 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9571 (not:SWI (match_dup 1)))]
9572 "ix86_match_ccmode (insn, CCNOmode)
9573 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9575 [(set_attr "type" "alu1")
9576 (set_attr "mode" "<MODE>")])
9579 [(set (match_operand 0 "flags_reg_operand")
9580 (match_operator 2 "compare_operator"
9581 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9583 (set (match_operand:SWI 1 "nonimmediate_operand")
9584 (not:SWI (match_dup 3)))]
9585 "ix86_match_ccmode (insn, CCNOmode)"
9586 [(parallel [(set (match_dup 0)
9587 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9590 (xor:SWI (match_dup 3) (const_int -1)))])])
9592 ;; ??? Currently never generated - xor is used instead.
9593 (define_insn "*one_cmplsi2_2_zext"
9594 [(set (reg FLAGS_REG)
9595 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9597 (set (match_operand:DI 0 "register_operand" "=r")
9598 (zero_extend:DI (not:SI (match_dup 1))))]
9599 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9600 && ix86_unary_operator_ok (NOT, SImode, operands)"
9602 [(set_attr "type" "alu1")
9603 (set_attr "mode" "SI")])
9606 [(set (match_operand 0 "flags_reg_operand")
9607 (match_operator 2 "compare_operator"
9608 [(not:SI (match_operand:SI 3 "register_operand"))
9610 (set (match_operand:DI 1 "register_operand")
9611 (zero_extend:DI (not:SI (match_dup 3))))]
9612 "ix86_match_ccmode (insn, CCNOmode)"
9613 [(parallel [(set (match_dup 0)
9614 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9617 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9619 ;; Shift instructions
9621 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9622 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9623 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9624 ;; from the assembler input.
9626 ;; This instruction shifts the target reg/mem as usual, but instead of
9627 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9628 ;; is a left shift double, bits are taken from the high order bits of
9629 ;; reg, else if the insn is a shift right double, bits are taken from the
9630 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9631 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9633 ;; Since sh[lr]d does not change the `reg' operand, that is done
9634 ;; separately, making all shifts emit pairs of shift double and normal
9635 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9636 ;; support a 63 bit shift, each shift where the count is in a reg expands
9637 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9639 ;; If the shift count is a constant, we need never emit more than one
9640 ;; shift pair, instead using moves and sign extension for counts greater
9643 (define_expand "ashl<mode>3"
9644 [(set (match_operand:SDWIM 0 "<shift_operand>")
9645 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9646 (match_operand:QI 2 "nonmemory_operand")))]
9648 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9650 (define_insn "*ashl<mode>3_doubleword"
9651 [(set (match_operand:DWI 0 "register_operand" "=&r")
9652 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
9653 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9654 (clobber (reg:CC FLAGS_REG))]
9657 [(set_attr "type" "multi")])
9660 [(set (match_operand:DWI 0 "register_operand")
9661 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9662 (match_operand:QI 2 "nonmemory_operand")))
9663 (clobber (reg:CC FLAGS_REG))]
9664 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9666 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9668 ;; By default we don't ask for a scratch register, because when DWImode
9669 ;; values are manipulated, registers are already at a premium. But if
9670 ;; we have one handy, we won't turn it away.
9673 [(match_scratch:DWIH 3 "r")
9674 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9676 (match_operand:<DWI> 1 "nonmemory_operand")
9677 (match_operand:QI 2 "nonmemory_operand")))
9678 (clobber (reg:CC FLAGS_REG))])
9682 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9684 (define_insn "x86_64_shld"
9685 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9686 (ior:DI (ashift:DI (match_dup 0)
9687 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9688 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9689 (minus:QI (const_int 64) (match_dup 2)))))
9690 (clobber (reg:CC FLAGS_REG))]
9692 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9693 [(set_attr "type" "ishift")
9694 (set_attr "prefix_0f" "1")
9695 (set_attr "mode" "DI")
9696 (set_attr "athlon_decode" "vector")
9697 (set_attr "amdfam10_decode" "vector")
9698 (set_attr "bdver1_decode" "vector")])
9700 (define_insn "x86_shld"
9701 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9702 (ior:SI (ashift:SI (match_dup 0)
9703 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9704 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9705 (minus:QI (const_int 32) (match_dup 2)))))
9706 (clobber (reg:CC FLAGS_REG))]
9708 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9709 [(set_attr "type" "ishift")
9710 (set_attr "prefix_0f" "1")
9711 (set_attr "mode" "SI")
9712 (set_attr "pent_pair" "np")
9713 (set_attr "athlon_decode" "vector")
9714 (set_attr "amdfam10_decode" "vector")
9715 (set_attr "bdver1_decode" "vector")])
9717 (define_expand "x86_shift<mode>_adj_1"
9718 [(set (reg:CCZ FLAGS_REG)
9719 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9722 (set (match_operand:SWI48 0 "register_operand")
9723 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9724 (match_operand:SWI48 1 "register_operand")
9727 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9728 (match_operand:SWI48 3 "register_operand")
9731 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9733 (define_expand "x86_shift<mode>_adj_2"
9734 [(use (match_operand:SWI48 0 "register_operand"))
9735 (use (match_operand:SWI48 1 "register_operand"))
9736 (use (match_operand:QI 2 "register_operand"))]
9739 rtx_code_label *label = gen_label_rtx ();
9742 emit_insn (gen_testqi_ccz_1 (operands[2],
9743 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9745 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9746 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9747 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9748 gen_rtx_LABEL_REF (VOIDmode, label),
9750 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
9751 JUMP_LABEL (tmp) = label;
9753 emit_move_insn (operands[0], operands[1]);
9754 ix86_expand_clear (operands[1]);
9757 LABEL_NUSES (label) = 1;
9762 ;; Avoid useless masking of count operand.
9763 (define_insn_and_split "*ashl<mode>3_mask"
9764 [(set (match_operand:SWI48 0 "nonimmediate_operand")
9766 (match_operand:SWI48 1 "nonimmediate_operand")
9769 (match_operand:SI 2 "register_operand")
9770 (match_operand:SI 3 "const_int_operand")) 0)))
9771 (clobber (reg:CC FLAGS_REG))]
9772 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9773 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9774 == GET_MODE_BITSIZE (<MODE>mode)-1
9775 && can_create_pseudo_p ()"
9780 (ashift:SWI48 (match_dup 1)
9782 (clobber (reg:CC FLAGS_REG))])]
9783 "operands[2] = gen_lowpart (QImode, operands[2]);")
9785 (define_insn "*bmi2_ashl<mode>3_1"
9786 [(set (match_operand:SWI48 0 "register_operand" "=r")
9787 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9788 (match_operand:SWI48 2 "register_operand" "r")))]
9790 "shlx\t{%2, %1, %0|%0, %1, %2}"
9791 [(set_attr "type" "ishiftx")
9792 (set_attr "mode" "<MODE>")])
9794 (define_insn "*ashl<mode>3_1"
9795 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9796 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9797 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9798 (clobber (reg:CC FLAGS_REG))]
9799 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9801 switch (get_attr_type (insn))
9808 gcc_assert (operands[2] == const1_rtx);
9809 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9810 return "add{<imodesuffix>}\t%0, %0";
9813 if (operands[2] == const1_rtx
9814 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9815 return "sal{<imodesuffix>}\t%0";
9817 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9820 [(set_attr "isa" "*,*,bmi2")
9822 (cond [(eq_attr "alternative" "1")
9823 (const_string "lea")
9824 (eq_attr "alternative" "2")
9825 (const_string "ishiftx")
9826 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9827 (match_operand 0 "register_operand"))
9828 (match_operand 2 "const1_operand"))
9829 (const_string "alu")
9831 (const_string "ishift")))
9832 (set (attr "length_immediate")
9834 (ior (eq_attr "type" "alu")
9835 (and (eq_attr "type" "ishift")
9836 (and (match_operand 2 "const1_operand")
9837 (ior (match_test "TARGET_SHIFT1")
9838 (match_test "optimize_function_for_size_p (cfun)")))))
9840 (const_string "*")))
9841 (set_attr "mode" "<MODE>")])
9843 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9845 [(set (match_operand:SWI48 0 "register_operand")
9846 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9847 (match_operand:QI 2 "register_operand")))
9848 (clobber (reg:CC FLAGS_REG))]
9849 "TARGET_BMI2 && reload_completed"
9851 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9852 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9854 (define_insn "*bmi2_ashlsi3_1_zext"
9855 [(set (match_operand:DI 0 "register_operand" "=r")
9857 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9858 (match_operand:SI 2 "register_operand" "r"))))]
9859 "TARGET_64BIT && TARGET_BMI2"
9860 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9861 [(set_attr "type" "ishiftx")
9862 (set_attr "mode" "SI")])
9864 (define_insn "*ashlsi3_1_zext"
9865 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9867 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9868 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9869 (clobber (reg:CC FLAGS_REG))]
9870 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9872 switch (get_attr_type (insn))
9879 gcc_assert (operands[2] == const1_rtx);
9880 return "add{l}\t%k0, %k0";
9883 if (operands[2] == const1_rtx
9884 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9885 return "sal{l}\t%k0";
9887 return "sal{l}\t{%2, %k0|%k0, %2}";
9890 [(set_attr "isa" "*,*,bmi2")
9892 (cond [(eq_attr "alternative" "1")
9893 (const_string "lea")
9894 (eq_attr "alternative" "2")
9895 (const_string "ishiftx")
9896 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9897 (match_operand 2 "const1_operand"))
9898 (const_string "alu")
9900 (const_string "ishift")))
9901 (set (attr "length_immediate")
9903 (ior (eq_attr "type" "alu")
9904 (and (eq_attr "type" "ishift")
9905 (and (match_operand 2 "const1_operand")
9906 (ior (match_test "TARGET_SHIFT1")
9907 (match_test "optimize_function_for_size_p (cfun)")))))
9909 (const_string "*")))
9910 (set_attr "mode" "SI")])
9912 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9914 [(set (match_operand:DI 0 "register_operand")
9916 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9917 (match_operand:QI 2 "register_operand"))))
9918 (clobber (reg:CC FLAGS_REG))]
9919 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9921 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9922 "operands[2] = gen_lowpart (SImode, operands[2]);")
9924 (define_insn "*ashlhi3_1"
9925 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9926 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9927 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9928 (clobber (reg:CC FLAGS_REG))]
9929 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9931 switch (get_attr_type (insn))
9937 gcc_assert (operands[2] == const1_rtx);
9938 return "add{w}\t%0, %0";
9941 if (operands[2] == const1_rtx
9942 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9943 return "sal{w}\t%0";
9945 return "sal{w}\t{%2, %0|%0, %2}";
9949 (cond [(eq_attr "alternative" "1")
9950 (const_string "lea")
9951 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9952 (match_operand 0 "register_operand"))
9953 (match_operand 2 "const1_operand"))
9954 (const_string "alu")
9956 (const_string "ishift")))
9957 (set (attr "length_immediate")
9959 (ior (eq_attr "type" "alu")
9960 (and (eq_attr "type" "ishift")
9961 (and (match_operand 2 "const1_operand")
9962 (ior (match_test "TARGET_SHIFT1")
9963 (match_test "optimize_function_for_size_p (cfun)")))))
9965 (const_string "*")))
9966 (set_attr "mode" "HI,SI")])
9968 (define_insn "*ashlqi3_1"
9969 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9970 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9971 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9972 (clobber (reg:CC FLAGS_REG))]
9973 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9975 switch (get_attr_type (insn))
9981 gcc_assert (operands[2] == const1_rtx);
9982 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
9983 return "add{l}\t%k0, %k0";
9985 return "add{b}\t%0, %0";
9988 if (operands[2] == const1_rtx
9989 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9991 if (get_attr_mode (insn) == MODE_SI)
9992 return "sal{l}\t%k0";
9994 return "sal{b}\t%0";
9998 if (get_attr_mode (insn) == MODE_SI)
9999 return "sal{l}\t{%2, %k0|%k0, %2}";
10001 return "sal{b}\t{%2, %0|%0, %2}";
10005 [(set (attr "type")
10006 (cond [(eq_attr "alternative" "2")
10007 (const_string "lea")
10008 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10009 (match_operand 0 "register_operand"))
10010 (match_operand 2 "const1_operand"))
10011 (const_string "alu")
10013 (const_string "ishift")))
10014 (set (attr "length_immediate")
10016 (ior (eq_attr "type" "alu")
10017 (and (eq_attr "type" "ishift")
10018 (and (match_operand 2 "const1_operand")
10019 (ior (match_test "TARGET_SHIFT1")
10020 (match_test "optimize_function_for_size_p (cfun)")))))
10022 (const_string "*")))
10023 (set_attr "mode" "QI,SI,SI")
10024 ;; Potential partial reg stall on alternative 1.
10025 (set (attr "preferred_for_speed")
10026 (cond [(eq_attr "alternative" "1")
10027 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10028 (symbol_ref "true")))])
10030 (define_insn "*ashlqi3_1_slp"
10031 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10032 (ashift:QI (match_dup 0)
10033 (match_operand:QI 1 "nonmemory_operand" "cI")))
10034 (clobber (reg:CC FLAGS_REG))]
10035 "(optimize_function_for_size_p (cfun)
10036 || !TARGET_PARTIAL_FLAG_REG_STALL
10037 || (operands[1] == const1_rtx
10039 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10041 switch (get_attr_type (insn))
10044 gcc_assert (operands[1] == const1_rtx);
10045 return "add{b}\t%0, %0";
10048 if (operands[1] == const1_rtx
10049 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10050 return "sal{b}\t%0";
10052 return "sal{b}\t{%1, %0|%0, %1}";
10055 [(set (attr "type")
10056 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10057 (match_operand 0 "register_operand"))
10058 (match_operand 1 "const1_operand"))
10059 (const_string "alu")
10061 (const_string "ishift1")))
10062 (set (attr "length_immediate")
10064 (ior (eq_attr "type" "alu")
10065 (and (eq_attr "type" "ishift1")
10066 (and (match_operand 1 "const1_operand")
10067 (ior (match_test "TARGET_SHIFT1")
10068 (match_test "optimize_function_for_size_p (cfun)")))))
10070 (const_string "*")))
10071 (set_attr "mode" "QI")])
10073 ;; Convert ashift to the lea pattern to avoid flags dependency.
10075 [(set (match_operand:SWI 0 "register_operand")
10076 (ashift:SWI (match_operand:SWI 1 "index_register_operand")
10077 (match_operand 2 "const_0_to_3_operand")))
10078 (clobber (reg:CC FLAGS_REG))]
10080 && REGNO (operands[0]) != REGNO (operands[1])"
10081 [(set (match_dup 0)
10082 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
10084 if (<MODE>mode != <LEAMODE>mode)
10086 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
10087 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
10089 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10092 ;; Convert ashift to the lea pattern to avoid flags dependency.
10094 [(set (match_operand:DI 0 "register_operand")
10096 (ashift:SI (match_operand:SI 1 "index_register_operand")
10097 (match_operand 2 "const_0_to_3_operand"))))
10098 (clobber (reg:CC FLAGS_REG))]
10099 "TARGET_64BIT && reload_completed
10100 && REGNO (operands[0]) != REGNO (operands[1])"
10101 [(set (match_dup 0)
10102 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10104 operands[1] = gen_lowpart (SImode, operands[1]);
10105 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10108 ;; This pattern can't accept a variable shift count, since shifts by
10109 ;; zero don't affect the flags. We assume that shifts by constant
10110 ;; zero are optimized away.
10111 (define_insn "*ashl<mode>3_cmp"
10112 [(set (reg FLAGS_REG)
10114 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10115 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10117 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10118 (ashift:SWI (match_dup 1) (match_dup 2)))]
10119 "(optimize_function_for_size_p (cfun)
10120 || !TARGET_PARTIAL_FLAG_REG_STALL
10121 || (operands[2] == const1_rtx
10123 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10124 && ix86_match_ccmode (insn, CCGOCmode)
10125 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10127 switch (get_attr_type (insn))
10130 gcc_assert (operands[2] == const1_rtx);
10131 return "add{<imodesuffix>}\t%0, %0";
10134 if (operands[2] == const1_rtx
10135 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10136 return "sal{<imodesuffix>}\t%0";
10138 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10141 [(set (attr "type")
10142 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10143 (match_operand 0 "register_operand"))
10144 (match_operand 2 "const1_operand"))
10145 (const_string "alu")
10147 (const_string "ishift")))
10148 (set (attr "length_immediate")
10150 (ior (eq_attr "type" "alu")
10151 (and (eq_attr "type" "ishift")
10152 (and (match_operand 2 "const1_operand")
10153 (ior (match_test "TARGET_SHIFT1")
10154 (match_test "optimize_function_for_size_p (cfun)")))))
10156 (const_string "*")))
10157 (set_attr "mode" "<MODE>")])
10159 (define_insn "*ashlsi3_cmp_zext"
10160 [(set (reg FLAGS_REG)
10162 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10163 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10165 (set (match_operand:DI 0 "register_operand" "=r")
10166 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10168 && (optimize_function_for_size_p (cfun)
10169 || !TARGET_PARTIAL_FLAG_REG_STALL
10170 || (operands[2] == const1_rtx
10172 || TARGET_DOUBLE_WITH_ADD)))
10173 && ix86_match_ccmode (insn, CCGOCmode)
10174 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10176 switch (get_attr_type (insn))
10179 gcc_assert (operands[2] == const1_rtx);
10180 return "add{l}\t%k0, %k0";
10183 if (operands[2] == const1_rtx
10184 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10185 return "sal{l}\t%k0";
10187 return "sal{l}\t{%2, %k0|%k0, %2}";
10190 [(set (attr "type")
10191 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
10192 (match_operand 2 "const1_operand"))
10193 (const_string "alu")
10195 (const_string "ishift")))
10196 (set (attr "length_immediate")
10198 (ior (eq_attr "type" "alu")
10199 (and (eq_attr "type" "ishift")
10200 (and (match_operand 2 "const1_operand")
10201 (ior (match_test "TARGET_SHIFT1")
10202 (match_test "optimize_function_for_size_p (cfun)")))))
10204 (const_string "*")))
10205 (set_attr "mode" "SI")])
10207 (define_insn "*ashl<mode>3_cconly"
10208 [(set (reg FLAGS_REG)
10210 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
10211 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10213 (clobber (match_scratch:SWI 0 "=<r>"))]
10214 "(optimize_function_for_size_p (cfun)
10215 || !TARGET_PARTIAL_FLAG_REG_STALL
10216 || (operands[2] == const1_rtx
10218 || TARGET_DOUBLE_WITH_ADD)))
10219 && ix86_match_ccmode (insn, CCGOCmode)"
10221 switch (get_attr_type (insn))
10224 gcc_assert (operands[2] == const1_rtx);
10225 return "add{<imodesuffix>}\t%0, %0";
10228 if (operands[2] == const1_rtx
10229 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10230 return "sal{<imodesuffix>}\t%0";
10232 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10235 [(set (attr "type")
10236 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10237 (match_operand 0 "register_operand"))
10238 (match_operand 2 "const1_operand"))
10239 (const_string "alu")
10241 (const_string "ishift")))
10242 (set (attr "length_immediate")
10244 (ior (eq_attr "type" "alu")
10245 (and (eq_attr "type" "ishift")
10246 (and (match_operand 2 "const1_operand")
10247 (ior (match_test "TARGET_SHIFT1")
10248 (match_test "optimize_function_for_size_p (cfun)")))))
10250 (const_string "*")))
10251 (set_attr "mode" "<MODE>")])
10253 ;; See comment above `ashl<mode>3' about how this works.
10255 (define_expand "<shift_insn><mode>3"
10256 [(set (match_operand:SDWIM 0 "<shift_operand>")
10257 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
10258 (match_operand:QI 2 "nonmemory_operand")))]
10260 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10262 ;; Avoid useless masking of count operand.
10263 (define_insn_and_split "*<shift_insn><mode>3_mask"
10264 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10266 (match_operand:SWI48 1 "nonimmediate_operand")
10269 (match_operand:SI 2 "register_operand")
10270 (match_operand:SI 3 "const_int_operand")) 0)))
10271 (clobber (reg:CC FLAGS_REG))]
10272 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10273 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10274 == GET_MODE_BITSIZE (<MODE>mode)-1
10275 && can_create_pseudo_p ()"
10279 [(set (match_dup 0)
10280 (any_shiftrt:SWI48 (match_dup 1)
10282 (clobber (reg:CC FLAGS_REG))])]
10283 "operands[2] = gen_lowpart (QImode, operands[2]);")
10285 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
10286 [(set (match_operand:DWI 0 "register_operand" "=&r")
10287 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10288 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10289 (clobber (reg:CC FLAGS_REG))]
10292 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10294 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10295 [(set_attr "type" "multi")])
10297 ;; By default we don't ask for a scratch register, because when DWImode
10298 ;; values are manipulated, registers are already at a premium. But if
10299 ;; we have one handy, we won't turn it away.
10302 [(match_scratch:DWIH 3 "r")
10303 (parallel [(set (match_operand:<DWI> 0 "register_operand")
10305 (match_operand:<DWI> 1 "register_operand")
10306 (match_operand:QI 2 "nonmemory_operand")))
10307 (clobber (reg:CC FLAGS_REG))])
10311 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
10313 (define_insn "x86_64_shrd"
10314 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10315 (ior:DI (lshiftrt:DI (match_dup 0)
10316 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10317 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10318 (minus:QI (const_int 64) (match_dup 2)))))
10319 (clobber (reg:CC FLAGS_REG))]
10321 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10322 [(set_attr "type" "ishift")
10323 (set_attr "prefix_0f" "1")
10324 (set_attr "mode" "DI")
10325 (set_attr "athlon_decode" "vector")
10326 (set_attr "amdfam10_decode" "vector")
10327 (set_attr "bdver1_decode" "vector")])
10329 (define_insn "x86_shrd"
10330 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10331 (ior:SI (lshiftrt:SI (match_dup 0)
10332 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10333 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10334 (minus:QI (const_int 32) (match_dup 2)))))
10335 (clobber (reg:CC FLAGS_REG))]
10337 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10338 [(set_attr "type" "ishift")
10339 (set_attr "prefix_0f" "1")
10340 (set_attr "mode" "SI")
10341 (set_attr "pent_pair" "np")
10342 (set_attr "athlon_decode" "vector")
10343 (set_attr "amdfam10_decode" "vector")
10344 (set_attr "bdver1_decode" "vector")])
10346 (define_insn "ashrdi3_cvt"
10347 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10348 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10349 (match_operand:QI 2 "const_int_operand")))
10350 (clobber (reg:CC FLAGS_REG))]
10351 "TARGET_64BIT && INTVAL (operands[2]) == 63
10352 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10353 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10356 sar{q}\t{%2, %0|%0, %2}"
10357 [(set_attr "type" "imovx,ishift")
10358 (set_attr "prefix_0f" "0,*")
10359 (set_attr "length_immediate" "0,*")
10360 (set_attr "modrm" "0,1")
10361 (set_attr "mode" "DI")])
10363 (define_insn "*ashrsi3_cvt_zext"
10364 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10366 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10367 (match_operand:QI 2 "const_int_operand"))))
10368 (clobber (reg:CC FLAGS_REG))]
10369 "TARGET_64BIT && INTVAL (operands[2]) == 31
10370 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10371 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10374 sar{l}\t{%2, %k0|%k0, %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" "SI")])
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_expand "x86_shift<mode>_adj_3"
10399 [(use (match_operand:SWI48 0 "register_operand"))
10400 (use (match_operand:SWI48 1 "register_operand"))
10401 (use (match_operand:QI 2 "register_operand"))]
10404 rtx_code_label *label = gen_label_rtx ();
10407 emit_insn (gen_testqi_ccz_1 (operands[2],
10408 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10410 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10411 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10412 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10413 gen_rtx_LABEL_REF (VOIDmode, label),
10415 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10416 JUMP_LABEL (tmp) = label;
10418 emit_move_insn (operands[0], operands[1]);
10419 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10420 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10421 emit_label (label);
10422 LABEL_NUSES (label) = 1;
10427 (define_insn "*bmi2_<shift_insn><mode>3_1"
10428 [(set (match_operand:SWI48 0 "register_operand" "=r")
10429 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10430 (match_operand:SWI48 2 "register_operand" "r")))]
10432 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10433 [(set_attr "type" "ishiftx")
10434 (set_attr "mode" "<MODE>")])
10436 (define_insn "*<shift_insn><mode>3_1"
10437 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10439 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10440 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10441 (clobber (reg:CC FLAGS_REG))]
10442 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10444 switch (get_attr_type (insn))
10450 if (operands[2] == const1_rtx
10451 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10452 return "<shift>{<imodesuffix>}\t%0";
10454 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10457 [(set_attr "isa" "*,bmi2")
10458 (set_attr "type" "ishift,ishiftx")
10459 (set (attr "length_immediate")
10461 (and (match_operand 2 "const1_operand")
10462 (ior (match_test "TARGET_SHIFT1")
10463 (match_test "optimize_function_for_size_p (cfun)")))
10465 (const_string "*")))
10466 (set_attr "mode" "<MODE>")])
10468 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10470 [(set (match_operand:SWI48 0 "register_operand")
10471 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10472 (match_operand:QI 2 "register_operand")))
10473 (clobber (reg:CC FLAGS_REG))]
10474 "TARGET_BMI2 && reload_completed"
10475 [(set (match_dup 0)
10476 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10477 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10479 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10480 [(set (match_operand:DI 0 "register_operand" "=r")
10482 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10483 (match_operand:SI 2 "register_operand" "r"))))]
10484 "TARGET_64BIT && TARGET_BMI2"
10485 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10486 [(set_attr "type" "ishiftx")
10487 (set_attr "mode" "SI")])
10489 (define_insn "*<shift_insn>si3_1_zext"
10490 [(set (match_operand:DI 0 "register_operand" "=r,r")
10492 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10493 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10494 (clobber (reg:CC FLAGS_REG))]
10495 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10497 switch (get_attr_type (insn))
10503 if (operands[2] == const1_rtx
10504 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10505 return "<shift>{l}\t%k0";
10507 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10510 [(set_attr "isa" "*,bmi2")
10511 (set_attr "type" "ishift,ishiftx")
10512 (set (attr "length_immediate")
10514 (and (match_operand 2 "const1_operand")
10515 (ior (match_test "TARGET_SHIFT1")
10516 (match_test "optimize_function_for_size_p (cfun)")))
10518 (const_string "*")))
10519 (set_attr "mode" "SI")])
10521 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10523 [(set (match_operand:DI 0 "register_operand")
10525 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10526 (match_operand:QI 2 "register_operand"))))
10527 (clobber (reg:CC FLAGS_REG))]
10528 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10529 [(set (match_dup 0)
10530 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10531 "operands[2] = gen_lowpart (SImode, operands[2]);")
10533 (define_insn "*<shift_insn><mode>3_1"
10534 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10536 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10537 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10538 (clobber (reg:CC FLAGS_REG))]
10539 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10541 if (operands[2] == const1_rtx
10542 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10543 return "<shift>{<imodesuffix>}\t%0";
10545 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10547 [(set_attr "type" "ishift")
10548 (set (attr "length_immediate")
10550 (and (match_operand 2 "const1_operand")
10551 (ior (match_test "TARGET_SHIFT1")
10552 (match_test "optimize_function_for_size_p (cfun)")))
10554 (const_string "*")))
10555 (set_attr "mode" "<MODE>")])
10557 (define_insn "*<shift_insn>qi3_1_slp"
10558 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10559 (any_shiftrt:QI (match_dup 0)
10560 (match_operand:QI 1 "nonmemory_operand" "cI")))
10561 (clobber (reg:CC FLAGS_REG))]
10562 "(optimize_function_for_size_p (cfun)
10563 || !TARGET_PARTIAL_REG_STALL
10564 || (operands[1] == const1_rtx
10565 && TARGET_SHIFT1))"
10567 if (operands[1] == const1_rtx
10568 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10569 return "<shift>{b}\t%0";
10571 return "<shift>{b}\t{%1, %0|%0, %1}";
10573 [(set_attr "type" "ishift1")
10574 (set (attr "length_immediate")
10576 (and (match_operand 1 "const1_operand")
10577 (ior (match_test "TARGET_SHIFT1")
10578 (match_test "optimize_function_for_size_p (cfun)")))
10580 (const_string "*")))
10581 (set_attr "mode" "QI")])
10583 ;; This pattern can't accept a variable shift count, since shifts by
10584 ;; zero don't affect the flags. We assume that shifts by constant
10585 ;; zero are optimized away.
10586 (define_insn "*<shift_insn><mode>3_cmp"
10587 [(set (reg FLAGS_REG)
10590 (match_operand:SWI 1 "nonimmediate_operand" "0")
10591 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10593 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10594 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10595 "(optimize_function_for_size_p (cfun)
10596 || !TARGET_PARTIAL_FLAG_REG_STALL
10597 || (operands[2] == const1_rtx
10599 && ix86_match_ccmode (insn, CCGOCmode)
10600 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10602 if (operands[2] == const1_rtx
10603 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10604 return "<shift>{<imodesuffix>}\t%0";
10606 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10608 [(set_attr "type" "ishift")
10609 (set (attr "length_immediate")
10611 (and (match_operand 2 "const1_operand")
10612 (ior (match_test "TARGET_SHIFT1")
10613 (match_test "optimize_function_for_size_p (cfun)")))
10615 (const_string "*")))
10616 (set_attr "mode" "<MODE>")])
10618 (define_insn "*<shift_insn>si3_cmp_zext"
10619 [(set (reg FLAGS_REG)
10621 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10622 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10624 (set (match_operand:DI 0 "register_operand" "=r")
10625 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10627 && (optimize_function_for_size_p (cfun)
10628 || !TARGET_PARTIAL_FLAG_REG_STALL
10629 || (operands[2] == const1_rtx
10631 && ix86_match_ccmode (insn, CCGOCmode)
10632 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10634 if (operands[2] == const1_rtx
10635 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10636 return "<shift>{l}\t%k0";
10638 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10640 [(set_attr "type" "ishift")
10641 (set (attr "length_immediate")
10643 (and (match_operand 2 "const1_operand")
10644 (ior (match_test "TARGET_SHIFT1")
10645 (match_test "optimize_function_for_size_p (cfun)")))
10647 (const_string "*")))
10648 (set_attr "mode" "SI")])
10650 (define_insn "*<shift_insn><mode>3_cconly"
10651 [(set (reg FLAGS_REG)
10654 (match_operand:SWI 1 "register_operand" "0")
10655 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10657 (clobber (match_scratch:SWI 0 "=<r>"))]
10658 "(optimize_function_for_size_p (cfun)
10659 || !TARGET_PARTIAL_FLAG_REG_STALL
10660 || (operands[2] == const1_rtx
10662 && ix86_match_ccmode (insn, CCGOCmode)"
10664 if (operands[2] == const1_rtx
10665 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10666 return "<shift>{<imodesuffix>}\t%0";
10668 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10670 [(set_attr "type" "ishift")
10671 (set (attr "length_immediate")
10673 (and (match_operand 2 "const1_operand")
10674 (ior (match_test "TARGET_SHIFT1")
10675 (match_test "optimize_function_for_size_p (cfun)")))
10677 (const_string "*")))
10678 (set_attr "mode" "<MODE>")])
10680 ;; Rotate instructions
10682 (define_expand "<rotate_insn>ti3"
10683 [(set (match_operand:TI 0 "register_operand")
10684 (any_rotate:TI (match_operand:TI 1 "register_operand")
10685 (match_operand:QI 2 "nonmemory_operand")))]
10688 if (const_1_to_63_operand (operands[2], VOIDmode))
10689 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10690 (operands[0], operands[1], operands[2]));
10697 (define_expand "<rotate_insn>di3"
10698 [(set (match_operand:DI 0 "shiftdi_operand")
10699 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10700 (match_operand:QI 2 "nonmemory_operand")))]
10704 ix86_expand_binary_operator (<CODE>, DImode, operands);
10705 else if (const_1_to_31_operand (operands[2], VOIDmode))
10706 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10707 (operands[0], operands[1], operands[2]));
10714 (define_expand "<rotate_insn><mode>3"
10715 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10716 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10717 (match_operand:QI 2 "nonmemory_operand")))]
10719 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10721 ;; Avoid useless masking of count operand.
10722 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10723 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10725 (match_operand:SWI48 1 "nonimmediate_operand")
10728 (match_operand:SI 2 "register_operand")
10729 (match_operand:SI 3 "const_int_operand")) 0)))
10730 (clobber (reg:CC FLAGS_REG))]
10731 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10732 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10733 == GET_MODE_BITSIZE (<MODE>mode)-1
10734 && can_create_pseudo_p ()"
10738 [(set (match_dup 0)
10739 (any_rotate:SWI48 (match_dup 1)
10741 (clobber (reg:CC FLAGS_REG))])]
10742 "operands[2] = gen_lowpart (QImode, operands[2]);")
10744 ;; Implement rotation using two double-precision
10745 ;; shift instructions and a scratch register.
10747 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10748 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10749 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10750 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10751 (clobber (reg:CC FLAGS_REG))
10752 (clobber (match_scratch:DWIH 3 "=&r"))]
10756 [(set (match_dup 3) (match_dup 4))
10758 [(set (match_dup 4)
10759 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10760 (lshiftrt:DWIH (match_dup 5)
10761 (minus:QI (match_dup 6) (match_dup 2)))))
10762 (clobber (reg:CC FLAGS_REG))])
10764 [(set (match_dup 5)
10765 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10766 (lshiftrt:DWIH (match_dup 3)
10767 (minus:QI (match_dup 6) (match_dup 2)))))
10768 (clobber (reg:CC FLAGS_REG))])]
10770 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10772 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10775 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10776 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10777 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10778 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10779 (clobber (reg:CC FLAGS_REG))
10780 (clobber (match_scratch:DWIH 3 "=&r"))]
10784 [(set (match_dup 3) (match_dup 4))
10786 [(set (match_dup 4)
10787 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10788 (ashift:DWIH (match_dup 5)
10789 (minus:QI (match_dup 6) (match_dup 2)))))
10790 (clobber (reg:CC FLAGS_REG))])
10792 [(set (match_dup 5)
10793 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10794 (ashift:DWIH (match_dup 3)
10795 (minus:QI (match_dup 6) (match_dup 2)))))
10796 (clobber (reg:CC FLAGS_REG))])]
10798 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10800 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10803 (define_mode_attr rorx_immediate_operand
10804 [(SI "const_0_to_31_operand")
10805 (DI "const_0_to_63_operand")])
10807 (define_insn "*bmi2_rorx<mode>3_1"
10808 [(set (match_operand:SWI48 0 "register_operand" "=r")
10810 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10811 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
10813 "rorx\t{%2, %1, %0|%0, %1, %2}"
10814 [(set_attr "type" "rotatex")
10815 (set_attr "mode" "<MODE>")])
10817 (define_insn "*<rotate_insn><mode>3_1"
10818 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10820 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10821 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10822 (clobber (reg:CC FLAGS_REG))]
10823 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10825 switch (get_attr_type (insn))
10831 if (operands[2] == const1_rtx
10832 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10833 return "<rotate>{<imodesuffix>}\t%0";
10835 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10838 [(set_attr "isa" "*,bmi2")
10839 (set_attr "type" "rotate,rotatex")
10840 (set (attr "length_immediate")
10842 (and (eq_attr "type" "rotate")
10843 (and (match_operand 2 "const1_operand")
10844 (ior (match_test "TARGET_SHIFT1")
10845 (match_test "optimize_function_for_size_p (cfun)"))))
10847 (const_string "*")))
10848 (set_attr "mode" "<MODE>")])
10850 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10852 [(set (match_operand:SWI48 0 "register_operand")
10853 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10854 (match_operand:QI 2 "const_int_operand")))
10855 (clobber (reg:CC FLAGS_REG))]
10856 "TARGET_BMI2 && reload_completed"
10857 [(set (match_dup 0)
10858 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10860 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
10862 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
10866 [(set (match_operand:SWI48 0 "register_operand")
10867 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10868 (match_operand:QI 2 "const_int_operand")))
10869 (clobber (reg:CC FLAGS_REG))]
10870 "TARGET_BMI2 && reload_completed"
10871 [(set (match_dup 0)
10872 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10874 (define_insn "*bmi2_rorxsi3_1_zext"
10875 [(set (match_operand:DI 0 "register_operand" "=r")
10877 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10878 (match_operand:QI 2 "const_0_to_31_operand" "I"))))]
10879 "TARGET_64BIT && TARGET_BMI2"
10880 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10881 [(set_attr "type" "rotatex")
10882 (set_attr "mode" "SI")])
10884 (define_insn "*<rotate_insn>si3_1_zext"
10885 [(set (match_operand:DI 0 "register_operand" "=r,r")
10887 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10888 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10889 (clobber (reg:CC FLAGS_REG))]
10890 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10892 switch (get_attr_type (insn))
10898 if (operands[2] == const1_rtx
10899 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10900 return "<rotate>{l}\t%k0";
10902 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10905 [(set_attr "isa" "*,bmi2")
10906 (set_attr "type" "rotate,rotatex")
10907 (set (attr "length_immediate")
10909 (and (eq_attr "type" "rotate")
10910 (and (match_operand 2 "const1_operand")
10911 (ior (match_test "TARGET_SHIFT1")
10912 (match_test "optimize_function_for_size_p (cfun)"))))
10914 (const_string "*")))
10915 (set_attr "mode" "SI")])
10917 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10919 [(set (match_operand:DI 0 "register_operand")
10921 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10922 (match_operand:QI 2 "const_int_operand"))))
10923 (clobber (reg:CC FLAGS_REG))]
10924 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10925 [(set (match_dup 0)
10926 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10928 int bitsize = GET_MODE_BITSIZE (SImode);
10930 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
10934 [(set (match_operand:DI 0 "register_operand")
10936 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10937 (match_operand:QI 2 "const_int_operand"))))
10938 (clobber (reg:CC FLAGS_REG))]
10939 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10940 [(set (match_dup 0)
10941 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10943 (define_insn "*<rotate_insn><mode>3_1"
10944 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10945 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10946 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10947 (clobber (reg:CC FLAGS_REG))]
10948 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10950 if (operands[2] == const1_rtx
10951 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10952 return "<rotate>{<imodesuffix>}\t%0";
10954 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10956 [(set_attr "type" "rotate")
10957 (set (attr "length_immediate")
10959 (and (match_operand 2 "const1_operand")
10960 (ior (match_test "TARGET_SHIFT1")
10961 (match_test "optimize_function_for_size_p (cfun)")))
10963 (const_string "*")))
10964 (set_attr "mode" "<MODE>")])
10966 (define_insn "*<rotate_insn>qi3_1_slp"
10967 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10968 (any_rotate:QI (match_dup 0)
10969 (match_operand:QI 1 "nonmemory_operand" "cI")))
10970 (clobber (reg:CC FLAGS_REG))]
10971 "(optimize_function_for_size_p (cfun)
10972 || !TARGET_PARTIAL_REG_STALL
10973 || (operands[1] == const1_rtx
10974 && TARGET_SHIFT1))"
10976 if (operands[1] == const1_rtx
10977 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10978 return "<rotate>{b}\t%0";
10980 return "<rotate>{b}\t{%1, %0|%0, %1}";
10982 [(set_attr "type" "rotate1")
10983 (set (attr "length_immediate")
10985 (and (match_operand 1 "const1_operand")
10986 (ior (match_test "TARGET_SHIFT1")
10987 (match_test "optimize_function_for_size_p (cfun)")))
10989 (const_string "*")))
10990 (set_attr "mode" "QI")])
10993 [(set (match_operand:HI 0 "register_operand")
10994 (any_rotate:HI (match_dup 0) (const_int 8)))
10995 (clobber (reg:CC FLAGS_REG))]
10997 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10998 [(parallel [(set (strict_low_part (match_dup 0))
10999 (bswap:HI (match_dup 0)))
11000 (clobber (reg:CC FLAGS_REG))])])
11002 ;; Bit set / bit test instructions
11004 ;; %%% bts, btr, btc
11006 ;; These instructions are *slow* when applied to memory.
11008 (define_code_attr btsc [(ior "bts") (xor "btc")])
11010 (define_insn "*<btsc><mode>"
11011 [(set (match_operand:SWI48 0 "register_operand" "=r")
11013 (ashift:SWI48 (const_int 1)
11014 (match_operand:QI 2 "register_operand" "r"))
11015 (match_operand:SWI48 1 "register_operand" "0")))
11016 (clobber (reg:CC FLAGS_REG))]
11018 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11019 [(set_attr "type" "alu1")
11020 (set_attr "prefix_0f" "1")
11021 (set_attr "znver1_decode" "double")
11022 (set_attr "mode" "<MODE>")])
11024 ;; Avoid useless masking of count operand.
11025 (define_insn_and_split "*<btsc><mode>_mask"
11026 [(set (match_operand:SWI48 0 "register_operand")
11032 (match_operand:SI 1 "register_operand")
11033 (match_operand:SI 2 "const_int_operand")) 0))
11034 (match_operand:SWI48 3 "register_operand")))
11035 (clobber (reg:CC FLAGS_REG))]
11037 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11038 == GET_MODE_BITSIZE (<MODE>mode)-1
11039 && can_create_pseudo_p ()"
11043 [(set (match_dup 0)
11045 (ashift:SWI48 (const_int 1)
11048 (clobber (reg:CC FLAGS_REG))])]
11049 "operands[1] = gen_lowpart (QImode, operands[1]);")
11051 (define_insn "*btr<mode>"
11052 [(set (match_operand:SWI48 0 "register_operand" "=r")
11054 (rotate:SWI48 (const_int -2)
11055 (match_operand:QI 2 "register_operand" "r"))
11056 (match_operand:SWI48 1 "register_operand" "0")))
11057 (clobber (reg:CC FLAGS_REG))]
11059 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11060 [(set_attr "type" "alu1")
11061 (set_attr "prefix_0f" "1")
11062 (set_attr "znver1_decode" "double")
11063 (set_attr "mode" "<MODE>")])
11065 ;; Avoid useless masking of count operand.
11066 (define_insn_and_split "*btr<mode>_mask"
11067 [(set (match_operand:SWI48 0 "register_operand")
11073 (match_operand:SI 1 "register_operand")
11074 (match_operand:SI 2 "const_int_operand")) 0))
11075 (match_operand:SWI48 3 "register_operand")))
11076 (clobber (reg:CC FLAGS_REG))]
11078 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11079 == GET_MODE_BITSIZE (<MODE>mode)-1
11080 && can_create_pseudo_p ()"
11084 [(set (match_dup 0)
11086 (rotate:SWI48 (const_int -2)
11089 (clobber (reg:CC FLAGS_REG))])]
11090 "operands[1] = gen_lowpart (QImode, operands[1]);")
11092 ;; These instructions are never faster than the corresponding
11093 ;; and/ior/xor operations when using immediate operand, so with
11094 ;; 32-bit there's no point. But in 64-bit, we can't hold the
11095 ;; relevant immediates within the instruction itself, so operating
11096 ;; on bits in the high 32-bits of a register becomes easier.
11098 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
11099 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
11100 ;; negdf respectively, so they can never be disabled entirely.
11102 (define_insn "*btsq_imm"
11103 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11105 (match_operand 1 "const_0_to_63_operand" "J"))
11107 (clobber (reg:CC FLAGS_REG))]
11108 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11109 "bts{q}\t{%1, %0|%0, %1}"
11110 [(set_attr "type" "alu1")
11111 (set_attr "prefix_0f" "1")
11112 (set_attr "znver1_decode" "double")
11113 (set_attr "mode" "DI")])
11115 (define_insn "*btrq_imm"
11116 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11118 (match_operand 1 "const_0_to_63_operand" "J"))
11120 (clobber (reg:CC FLAGS_REG))]
11121 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11122 "btr{q}\t{%1, %0|%0, %1}"
11123 [(set_attr "type" "alu1")
11124 (set_attr "prefix_0f" "1")
11125 (set_attr "znver1_decode" "double")
11126 (set_attr "mode" "DI")])
11128 (define_insn "*btcq_imm"
11129 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11131 (match_operand 1 "const_0_to_63_operand" "J"))
11132 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
11133 (clobber (reg:CC FLAGS_REG))]
11134 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11135 "btc{q}\t{%1, %0|%0, %1}"
11136 [(set_attr "type" "alu1")
11137 (set_attr "prefix_0f" "1")
11138 (set_attr "znver1_decode" "double")
11139 (set_attr "mode" "DI")])
11141 ;; Allow Nocona to avoid these instructions if a register is available.
11144 [(match_scratch:DI 2 "r")
11145 (parallel [(set (zero_extract:DI
11146 (match_operand:DI 0 "nonimmediate_operand")
11148 (match_operand 1 "const_0_to_63_operand"))
11150 (clobber (reg:CC FLAGS_REG))])]
11151 "TARGET_64BIT && !TARGET_USE_BT"
11152 [(parallel [(set (match_dup 0)
11153 (ior:DI (match_dup 0) (match_dup 3)))
11154 (clobber (reg:CC FLAGS_REG))])]
11156 int i = INTVAL (operands[1]);
11158 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11160 if (!x86_64_immediate_operand (operands[3], DImode))
11162 emit_move_insn (operands[2], operands[3]);
11163 operands[3] = operands[2];
11168 [(match_scratch:DI 2 "r")
11169 (parallel [(set (zero_extract:DI
11170 (match_operand:DI 0 "nonimmediate_operand")
11172 (match_operand 1 "const_0_to_63_operand"))
11174 (clobber (reg:CC FLAGS_REG))])]
11175 "TARGET_64BIT && !TARGET_USE_BT"
11176 [(parallel [(set (match_dup 0)
11177 (and:DI (match_dup 0) (match_dup 3)))
11178 (clobber (reg:CC FLAGS_REG))])]
11180 int i = INTVAL (operands[1]);
11182 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
11184 if (!x86_64_immediate_operand (operands[3], DImode))
11186 emit_move_insn (operands[2], operands[3]);
11187 operands[3] = operands[2];
11192 [(match_scratch:DI 2 "r")
11193 (parallel [(set (zero_extract:DI
11194 (match_operand:DI 0 "nonimmediate_operand")
11196 (match_operand 1 "const_0_to_63_operand"))
11197 (not:DI (zero_extract:DI
11198 (match_dup 0) (const_int 1) (match_dup 1))))
11199 (clobber (reg:CC FLAGS_REG))])]
11200 "TARGET_64BIT && !TARGET_USE_BT"
11201 [(parallel [(set (match_dup 0)
11202 (xor:DI (match_dup 0) (match_dup 3)))
11203 (clobber (reg:CC FLAGS_REG))])]
11205 int i = INTVAL (operands[1]);
11207 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11209 if (!x86_64_immediate_operand (operands[3], DImode))
11211 emit_move_insn (operands[2], operands[3]);
11212 operands[3] = operands[2];
11218 (define_insn "*bt<mode>"
11219 [(set (reg:CCC FLAGS_REG)
11221 (zero_extract:SWI48
11222 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
11224 (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
11228 switch (get_attr_mode (insn))
11231 return "bt{l}\t{%1, %k0|%k0, %1}";
11234 return "bt{q}\t{%q1, %0|%0, %q1}";
11237 gcc_unreachable ();
11240 [(set_attr "type" "alu1")
11241 (set_attr "prefix_0f" "1")
11244 (and (match_test "CONST_INT_P (operands[1])")
11245 (match_test "INTVAL (operands[1]) < 32"))
11246 (const_string "SI")
11247 (const_string "<MODE>")))])
11249 (define_insn_and_split "*jcc_bt<mode>"
11251 (if_then_else (match_operator 0 "bt_comparison_operator"
11252 [(zero_extract:SWI48
11253 (match_operand:SWI48 1 "nonimmediate_operand")
11255 (match_operand:SI 2 "nonmemory_operand"))
11257 (label_ref (match_operand 3))
11259 (clobber (reg:CC FLAGS_REG))]
11260 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11261 && (CONST_INT_P (operands[2])
11262 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
11263 && INTVAL (operands[2])
11264 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
11265 : !memory_operand (operands[1], <MODE>mode))
11266 && can_create_pseudo_p ()"
11269 [(set (reg:CCC FLAGS_REG)
11271 (zero_extract:SWI48
11277 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11278 (label_ref (match_dup 3))
11281 operands[0] = shallow_copy_rtx (operands[0]);
11282 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11285 (define_insn_and_split "*jcc_bt<mode>_1"
11287 (if_then_else (match_operator 0 "bt_comparison_operator"
11288 [(zero_extract:SWI48
11289 (match_operand:SWI48 1 "register_operand")
11292 (match_operand:QI 2 "register_operand")))
11294 (label_ref (match_operand 3))
11296 (clobber (reg:CC FLAGS_REG))]
11297 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11298 && can_create_pseudo_p ()"
11301 [(set (reg:CCC FLAGS_REG)
11303 (zero_extract:SWI48
11309 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11310 (label_ref (match_dup 3))
11313 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
11314 operands[0] = shallow_copy_rtx (operands[0]);
11315 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11318 ;; Avoid useless masking of bit offset operand.
11319 (define_insn_and_split "*jcc_bt<mode>_mask"
11321 (if_then_else (match_operator 0 "bt_comparison_operator"
11322 [(zero_extract:SWI48
11323 (match_operand:SWI48 1 "register_operand")
11326 (match_operand:SI 2 "register_operand")
11327 (match_operand 3 "const_int_operand")))])
11328 (label_ref (match_operand 4))
11330 (clobber (reg:CC FLAGS_REG))]
11331 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11332 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11333 == GET_MODE_BITSIZE (<MODE>mode)-1
11334 && can_create_pseudo_p ()"
11337 [(set (reg:CCC FLAGS_REG)
11339 (zero_extract:SWI48
11345 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11346 (label_ref (match_dup 4))
11349 operands[0] = shallow_copy_rtx (operands[0]);
11350 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11353 ;; Store-flag instructions.
11355 ;; For all sCOND expanders, also expand the compare or test insn that
11356 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
11358 (define_insn_and_split "*setcc_di_1"
11359 [(set (match_operand:DI 0 "register_operand" "=q")
11360 (match_operator:DI 1 "ix86_comparison_operator"
11361 [(reg FLAGS_REG) (const_int 0)]))]
11362 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
11364 "&& reload_completed"
11365 [(set (match_dup 2) (match_dup 1))
11366 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
11368 operands[1] = shallow_copy_rtx (operands[1]);
11369 PUT_MODE (operands[1], QImode);
11370 operands[2] = gen_lowpart (QImode, operands[0]);
11373 (define_insn_and_split "*setcc_si_1_and"
11374 [(set (match_operand:SI 0 "register_operand" "=q")
11375 (match_operator:SI 1 "ix86_comparison_operator"
11376 [(reg FLAGS_REG) (const_int 0)]))
11377 (clobber (reg:CC FLAGS_REG))]
11378 "!TARGET_PARTIAL_REG_STALL
11379 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
11381 "&& reload_completed"
11382 [(set (match_dup 2) (match_dup 1))
11383 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
11384 (clobber (reg:CC FLAGS_REG))])]
11386 operands[1] = shallow_copy_rtx (operands[1]);
11387 PUT_MODE (operands[1], QImode);
11388 operands[2] = gen_lowpart (QImode, operands[0]);
11391 (define_insn_and_split "*setcc_si_1_movzbl"
11392 [(set (match_operand:SI 0 "register_operand" "=q")
11393 (match_operator:SI 1 "ix86_comparison_operator"
11394 [(reg FLAGS_REG) (const_int 0)]))]
11395 "!TARGET_PARTIAL_REG_STALL
11396 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
11398 "&& reload_completed"
11399 [(set (match_dup 2) (match_dup 1))
11400 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
11402 operands[1] = shallow_copy_rtx (operands[1]);
11403 PUT_MODE (operands[1], QImode);
11404 operands[2] = gen_lowpart (QImode, operands[0]);
11407 (define_insn "*setcc_qi"
11408 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11409 (match_operator:QI 1 "ix86_comparison_operator"
11410 [(reg FLAGS_REG) (const_int 0)]))]
11413 [(set_attr "type" "setcc")
11414 (set_attr "mode" "QI")])
11416 (define_insn "*setcc_qi_slp"
11417 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11418 (match_operator:QI 1 "ix86_comparison_operator"
11419 [(reg FLAGS_REG) (const_int 0)]))]
11422 [(set_attr "type" "setcc")
11423 (set_attr "mode" "QI")])
11425 ;; In general it is not safe to assume too much about CCmode registers,
11426 ;; so simplify-rtx stops when it sees a second one. Under certain
11427 ;; conditions this is safe on x86, so help combine not create
11434 [(set (match_operand:QI 0 "nonimmediate_operand")
11435 (ne:QI (match_operator 1 "ix86_comparison_operator"
11436 [(reg FLAGS_REG) (const_int 0)])
11439 [(set (match_dup 0) (match_dup 1))]
11441 operands[1] = shallow_copy_rtx (operands[1]);
11442 PUT_MODE (operands[1], QImode);
11446 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11447 (ne:QI (match_operator 1 "ix86_comparison_operator"
11448 [(reg FLAGS_REG) (const_int 0)])
11451 [(set (match_dup 0) (match_dup 1))]
11453 operands[1] = shallow_copy_rtx (operands[1]);
11454 PUT_MODE (operands[1], QImode);
11458 [(set (match_operand:QI 0 "nonimmediate_operand")
11459 (eq:QI (match_operator 1 "ix86_comparison_operator"
11460 [(reg FLAGS_REG) (const_int 0)])
11463 [(set (match_dup 0) (match_dup 1))]
11465 operands[1] = shallow_copy_rtx (operands[1]);
11466 PUT_MODE (operands[1], QImode);
11467 PUT_CODE (operands[1],
11468 ix86_reverse_condition (GET_CODE (operands[1]),
11469 GET_MODE (XEXP (operands[1], 0))));
11471 /* Make sure that (a) the CCmode we have for the flags is strong
11472 enough for the reversed compare or (b) we have a valid FP compare. */
11473 if (! ix86_comparison_operator (operands[1], VOIDmode))
11478 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11479 (eq:QI (match_operator 1 "ix86_comparison_operator"
11480 [(reg FLAGS_REG) (const_int 0)])
11483 [(set (match_dup 0) (match_dup 1))]
11485 operands[1] = shallow_copy_rtx (operands[1]);
11486 PUT_MODE (operands[1], QImode);
11487 PUT_CODE (operands[1],
11488 ix86_reverse_condition (GET_CODE (operands[1]),
11489 GET_MODE (XEXP (operands[1], 0))));
11491 /* Make sure that (a) the CCmode we have for the flags is strong
11492 enough for the reversed compare or (b) we have a valid FP compare. */
11493 if (! ix86_comparison_operator (operands[1], VOIDmode))
11497 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
11498 ;; subsequent logical operations are used to imitate conditional moves.
11499 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
11502 (define_insn "setcc_<mode>_sse"
11503 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
11504 (match_operator:MODEF 3 "sse_comparison_operator"
11505 [(match_operand:MODEF 1 "register_operand" "0,x")
11506 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
11507 "SSE_FLOAT_MODE_P (<MODE>mode)"
11509 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
11510 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
11511 [(set_attr "isa" "noavx,avx")
11512 (set_attr "type" "ssecmp")
11513 (set_attr "length_immediate" "1")
11514 (set_attr "prefix" "orig,vex")
11515 (set_attr "mode" "<MODE>")])
11517 ;; Basic conditional jump instructions.
11518 ;; We ignore the overflow flag for signed branch instructions.
11520 (define_insn "*jcc_1"
11522 (if_then_else (match_operator 1 "ix86_comparison_operator"
11523 [(reg FLAGS_REG) (const_int 0)])
11524 (label_ref (match_operand 0))
11528 [(set_attr "type" "ibr")
11529 (set_attr "modrm" "0")
11530 (set (attr "length")
11532 (and (ge (minus (match_dup 0) (pc))
11534 (lt (minus (match_dup 0) (pc))
11538 (set_attr "maybe_prefix_bnd" "1")])
11540 (define_insn "*jcc_2"
11542 (if_then_else (match_operator 1 "ix86_comparison_operator"
11543 [(reg FLAGS_REG) (const_int 0)])
11545 (label_ref (match_operand 0))))]
11548 [(set_attr "type" "ibr")
11549 (set_attr "modrm" "0")
11550 (set (attr "length")
11552 (and (ge (minus (match_dup 0) (pc))
11554 (lt (minus (match_dup 0) (pc))
11558 (set_attr "maybe_prefix_bnd" "1")])
11560 ;; In general it is not safe to assume too much about CCmode registers,
11561 ;; so simplify-rtx stops when it sees a second one. Under certain
11562 ;; conditions this is safe on x86, so help combine not create
11570 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11571 [(reg FLAGS_REG) (const_int 0)])
11573 (label_ref (match_operand 1))
11577 (if_then_else (match_dup 0)
11578 (label_ref (match_dup 1))
11581 operands[0] = shallow_copy_rtx (operands[0]);
11582 PUT_MODE (operands[0], VOIDmode);
11587 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11588 [(reg FLAGS_REG) (const_int 0)])
11590 (label_ref (match_operand 1))
11594 (if_then_else (match_dup 0)
11595 (label_ref (match_dup 1))
11598 operands[0] = shallow_copy_rtx (operands[0]);
11599 PUT_MODE (operands[0], VOIDmode);
11600 PUT_CODE (operands[0],
11601 ix86_reverse_condition (GET_CODE (operands[0]),
11602 GET_MODE (XEXP (operands[0], 0))));
11604 /* Make sure that (a) the CCmode we have for the flags is strong
11605 enough for the reversed compare or (b) we have a valid FP compare. */
11606 if (! ix86_comparison_operator (operands[0], VOIDmode))
11610 ;; Define combination compare-and-branch fp compare instructions to help
11613 (define_insn "*jcc<mode>_0_i387"
11615 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11616 [(match_operand:X87MODEF 1 "register_operand" "f")
11617 (match_operand:X87MODEF 2 "const0_operand")])
11618 (label_ref (match_operand 3))
11620 (clobber (reg:CCFP FPSR_REG))
11621 (clobber (reg:CCFP FLAGS_REG))
11622 (clobber (match_scratch:HI 4 "=a"))]
11623 "TARGET_80387 && !TARGET_CMOVE"
11626 (define_insn "*jcc<mode>_0_r_i387"
11628 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11629 [(match_operand:X87MODEF 1 "register_operand" "f")
11630 (match_operand:X87MODEF 2 "const0_operand")])
11632 (label_ref (match_operand 3))))
11633 (clobber (reg:CCFP FPSR_REG))
11634 (clobber (reg:CCFP FLAGS_REG))
11635 (clobber (match_scratch:HI 4 "=a"))]
11636 "TARGET_80387 && !TARGET_CMOVE"
11639 (define_insn "*jccxf_i387"
11641 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11642 [(match_operand:XF 1 "register_operand" "f")
11643 (match_operand:XF 2 "register_operand" "f")])
11644 (label_ref (match_operand 3))
11646 (clobber (reg:CCFP FPSR_REG))
11647 (clobber (reg:CCFP FLAGS_REG))
11648 (clobber (match_scratch:HI 4 "=a"))]
11649 "TARGET_80387 && !TARGET_CMOVE"
11652 (define_insn "*jccxf_r_i387"
11654 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11655 [(match_operand:XF 1 "register_operand" "f")
11656 (match_operand:XF 2 "register_operand" "f")])
11658 (label_ref (match_operand 3))))
11659 (clobber (reg:CCFP FPSR_REG))
11660 (clobber (reg:CCFP FLAGS_REG))
11661 (clobber (match_scratch:HI 4 "=a"))]
11662 "TARGET_80387 && !TARGET_CMOVE"
11665 (define_insn "*jcc<mode>_i387"
11667 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11668 [(match_operand:MODEF 1 "register_operand" "f")
11669 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11670 (label_ref (match_operand 3))
11672 (clobber (reg:CCFP FPSR_REG))
11673 (clobber (reg:CCFP FLAGS_REG))
11674 (clobber (match_scratch:HI 4 "=a"))]
11675 "TARGET_80387 && !TARGET_CMOVE"
11678 (define_insn "*jcc<mode>_r_i387"
11680 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11681 [(match_operand:MODEF 1 "register_operand" "f")
11682 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11684 (label_ref (match_operand 3))))
11685 (clobber (reg:CCFP FPSR_REG))
11686 (clobber (reg:CCFP FLAGS_REG))
11687 (clobber (match_scratch:HI 4 "=a"))]
11688 "TARGET_80387 && !TARGET_CMOVE"
11691 (define_insn "*jccu<mode>_i387"
11693 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11694 [(match_operand:X87MODEF 1 "register_operand" "f")
11695 (match_operand:X87MODEF 2 "register_operand" "f")])
11696 (label_ref (match_operand 3))
11698 (clobber (reg:CCFP FPSR_REG))
11699 (clobber (reg:CCFP FLAGS_REG))
11700 (clobber (match_scratch:HI 4 "=a"))]
11701 "TARGET_80387 && !TARGET_CMOVE"
11704 (define_insn "*jccu<mode>_r_i387"
11706 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11707 [(match_operand:X87MODEF 1 "register_operand" "f")
11708 (match_operand:X87MODEF 2 "register_operand" "f")])
11710 (label_ref (match_operand 3))))
11711 (clobber (reg:CCFP FPSR_REG))
11712 (clobber (reg:CCFP FLAGS_REG))
11713 (clobber (match_scratch:HI 4 "=a"))]
11714 "TARGET_80387 && !TARGET_CMOVE"
11719 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11720 [(match_operand:X87MODEF 1 "register_operand")
11721 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11723 (match_operand 4)))
11724 (clobber (reg:CCFP FPSR_REG))
11725 (clobber (reg:CCFP FLAGS_REG))]
11726 "TARGET_80387 && !TARGET_CMOVE
11727 && reload_completed"
11730 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11731 operands[3], operands[4], NULL_RTX);
11737 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11738 [(match_operand:X87MODEF 1 "register_operand")
11739 (match_operand:X87MODEF 2 "general_operand")])
11741 (match_operand 4)))
11742 (clobber (reg:CCFP FPSR_REG))
11743 (clobber (reg:CCFP FLAGS_REG))
11744 (clobber (match_scratch:HI 5))]
11745 "TARGET_80387 && !TARGET_CMOVE
11746 && reload_completed"
11749 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11750 operands[3], operands[4], operands[5]);
11754 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11755 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11756 ;; with a precedence over other operators and is always put in the first
11757 ;; place. Swap condition and operands to match ficom instruction.
11759 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11762 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11763 [(match_operator:X87MODEF 1 "float_operator"
11764 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11765 (match_operand:X87MODEF 3 "register_operand" "f")])
11766 (label_ref (match_operand 4))
11768 (clobber (reg:CCFP FPSR_REG))
11769 (clobber (reg:CCFP FLAGS_REG))
11770 (clobber (match_scratch:HI 5 "=a"))]
11771 "TARGET_80387 && !TARGET_CMOVE
11772 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11773 || optimize_function_for_size_p (cfun))"
11776 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11779 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11780 [(match_operator:X87MODEF 1 "float_operator"
11781 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11782 (match_operand:X87MODEF 3 "register_operand" "f")])
11784 (label_ref (match_operand 4))))
11785 (clobber (reg:CCFP FPSR_REG))
11786 (clobber (reg:CCFP FLAGS_REG))
11787 (clobber (match_scratch:HI 5 "=a"))]
11788 "TARGET_80387 && !TARGET_CMOVE
11789 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11790 || optimize_function_for_size_p (cfun))"
11796 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11797 [(match_operator:X87MODEF 1 "float_operator"
11798 [(match_operand:SWI24 2 "memory_operand")])
11799 (match_operand:X87MODEF 3 "register_operand")])
11801 (match_operand 5)))
11802 (clobber (reg:CCFP FPSR_REG))
11803 (clobber (reg:CCFP FLAGS_REG))
11804 (clobber (match_scratch:HI 6))]
11805 "TARGET_80387 && !TARGET_CMOVE
11806 && reload_completed"
11809 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11810 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11811 operands[4], operands[5], operands[6]);
11815 ;; Unconditional and other jump instructions
11817 (define_insn "jump"
11819 (label_ref (match_operand 0)))]
11822 [(set_attr "type" "ibr")
11823 (set_attr "modrm" "0")
11824 (set (attr "length")
11826 (and (ge (minus (match_dup 0) (pc))
11828 (lt (minus (match_dup 0) (pc))
11832 (set_attr "maybe_prefix_bnd" "1")])
11834 (define_expand "indirect_jump"
11835 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11839 operands[0] = convert_memory_address (word_mode, operands[0]);
11842 (define_insn "*indirect_jump"
11843 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11846 [(set_attr "type" "ibr")
11847 (set_attr "length_immediate" "0")
11848 (set_attr "maybe_prefix_bnd" "1")])
11850 (define_expand "tablejump"
11851 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11852 (use (label_ref (match_operand 1)))])]
11855 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11856 relative. Convert the relative address to an absolute address. */
11860 enum rtx_code code;
11862 /* We can't use @GOTOFF for text labels on VxWorks;
11863 see gotoff_operand. */
11864 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11868 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11870 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11874 op1 = pic_offset_table_rtx;
11879 op0 = pic_offset_table_rtx;
11883 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11888 operands[0] = convert_memory_address (word_mode, operands[0]);
11891 (define_insn "*tablejump_1"
11892 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11893 (use (label_ref (match_operand 1)))]
11896 [(set_attr "type" "ibr")
11897 (set_attr "length_immediate" "0")
11898 (set_attr "maybe_prefix_bnd" "1")])
11900 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11903 [(set (reg FLAGS_REG) (match_operand 0))
11904 (set (match_operand:QI 1 "register_operand")
11905 (match_operator:QI 2 "ix86_comparison_operator"
11906 [(reg FLAGS_REG) (const_int 0)]))
11907 (set (match_operand 3 "any_QIreg_operand")
11908 (zero_extend (match_dup 1)))]
11909 "(peep2_reg_dead_p (3, operands[1])
11910 || operands_match_p (operands[1], operands[3]))
11911 && ! reg_overlap_mentioned_p (operands[3], operands[0])
11912 && peep2_regno_dead_p (0, FLAGS_REG)"
11913 [(set (match_dup 4) (match_dup 0))
11914 (set (strict_low_part (match_dup 5))
11917 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11918 operands[5] = gen_lowpart (QImode, operands[3]);
11919 ix86_expand_clear (operands[3]);
11923 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11924 (match_operand 4)])
11925 (set (match_operand:QI 1 "register_operand")
11926 (match_operator:QI 2 "ix86_comparison_operator"
11927 [(reg FLAGS_REG) (const_int 0)]))
11928 (set (match_operand 3 "any_QIreg_operand")
11929 (zero_extend (match_dup 1)))]
11930 "(peep2_reg_dead_p (3, operands[1])
11931 || operands_match_p (operands[1], operands[3]))
11932 && ! reg_overlap_mentioned_p (operands[3], operands[0])
11933 && ! reg_set_p (operands[3], operands[4])
11934 && peep2_regno_dead_p (0, FLAGS_REG)"
11935 [(parallel [(set (match_dup 5) (match_dup 0))
11937 (set (strict_low_part (match_dup 6))
11940 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11941 operands[6] = gen_lowpart (QImode, operands[3]);
11942 ix86_expand_clear (operands[3]);
11945 ;; Similar, but match zero extend with andsi3.
11948 [(set (reg FLAGS_REG) (match_operand 0))
11949 (set (match_operand:QI 1 "register_operand")
11950 (match_operator:QI 2 "ix86_comparison_operator"
11951 [(reg FLAGS_REG) (const_int 0)]))
11952 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
11953 (and:SI (match_dup 3) (const_int 255)))
11954 (clobber (reg:CC FLAGS_REG))])]
11955 "REGNO (operands[1]) == REGNO (operands[3])
11956 && ! reg_overlap_mentioned_p (operands[3], operands[0])
11957 && peep2_regno_dead_p (0, FLAGS_REG)"
11958 [(set (match_dup 4) (match_dup 0))
11959 (set (strict_low_part (match_dup 5))
11962 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11963 operands[5] = gen_lowpart (QImode, operands[3]);
11964 ix86_expand_clear (operands[3]);
11968 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11969 (match_operand 4)])
11970 (set (match_operand:QI 1 "register_operand")
11971 (match_operator:QI 2 "ix86_comparison_operator"
11972 [(reg FLAGS_REG) (const_int 0)]))
11973 (parallel [(set (match_operand 3 "any_QIreg_operand")
11974 (zero_extend (match_dup 1)))
11975 (clobber (reg:CC FLAGS_REG))])]
11976 "(peep2_reg_dead_p (3, operands[1])
11977 || operands_match_p (operands[1], operands[3]))
11978 && ! reg_overlap_mentioned_p (operands[3], operands[0])
11979 && ! reg_set_p (operands[3], operands[4])
11980 && peep2_regno_dead_p (0, FLAGS_REG)"
11981 [(parallel [(set (match_dup 5) (match_dup 0))
11983 (set (strict_low_part (match_dup 6))
11986 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11987 operands[6] = gen_lowpart (QImode, operands[3]);
11988 ix86_expand_clear (operands[3]);
11991 ;; Call instructions.
11993 ;; The predicates normally associated with named expanders are not properly
11994 ;; checked for calls. This is a bug in the generic code, but it isn't that
11995 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11997 ;; P6 processors will jump to the address after the decrement when %esp
11998 ;; is used as a call operand, so they will execute return address as a code.
11999 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
12001 ;; Register constraint for call instruction.
12002 (define_mode_attr c [(SI "l") (DI "r")])
12004 ;; Call subroutine returning no value.
12006 (define_expand "call"
12007 [(call (match_operand:QI 0)
12009 (use (match_operand 2))]
12012 ix86_expand_call (NULL, operands[0], operands[1],
12013 operands[2], NULL, false);
12017 (define_expand "sibcall"
12018 [(call (match_operand:QI 0)
12020 (use (match_operand 2))]
12023 ix86_expand_call (NULL, operands[0], operands[1],
12024 operands[2], NULL, true);
12028 (define_insn "*call"
12029 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
12030 (match_operand 1))]
12031 "!SIBLING_CALL_P (insn)"
12032 "* return ix86_output_call_insn (insn, operands[0]);"
12033 [(set_attr "type" "call")])
12035 ;; This covers both call and sibcall since only GOT slot is allowed.
12036 (define_insn "*call_got_x32"
12037 [(call (mem:QI (zero_extend:DI
12038 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
12039 (match_operand 1))]
12042 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
12043 return ix86_output_call_insn (insn, fnaddr);
12045 [(set_attr "type" "call")])
12047 ;; Since sibcall never returns, we can only use call-clobbered register
12049 (define_insn "*sibcall_GOT_32"
12052 (match_operand:SI 0 "register_no_elim_operand" "U")
12053 (match_operand:SI 1 "GOT32_symbol_operand"))))
12054 (match_operand 2))]
12055 "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
12057 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
12058 fnaddr = gen_const_mem (SImode, fnaddr);
12059 return ix86_output_call_insn (insn, fnaddr);
12061 [(set_attr "type" "call")])
12063 (define_insn "*sibcall"
12064 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
12065 (match_operand 1))]
12066 "SIBLING_CALL_P (insn)"
12067 "* return ix86_output_call_insn (insn, operands[0]);"
12068 [(set_attr "type" "call")])
12070 (define_insn "*sibcall_memory"
12071 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
12073 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12075 "* return ix86_output_call_insn (insn, operands[0]);"
12076 [(set_attr "type" "call")])
12079 [(set (match_operand:W 0 "register_operand")
12080 (match_operand:W 1 "memory_operand"))
12081 (call (mem:QI (match_dup 0))
12082 (match_operand 3))]
12083 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
12084 && !reg_mentioned_p (operands[0],
12085 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12086 [(parallel [(call (mem:QI (match_dup 1))
12088 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12091 [(set (match_operand:W 0 "register_operand")
12092 (match_operand:W 1 "memory_operand"))
12093 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12094 (call (mem:QI (match_dup 0))
12095 (match_operand 3))]
12096 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
12097 && !reg_mentioned_p (operands[0],
12098 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12099 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12100 (parallel [(call (mem:QI (match_dup 1))
12102 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12104 (define_expand "call_pop"
12105 [(parallel [(call (match_operand:QI 0)
12106 (match_operand:SI 1))
12107 (set (reg:SI SP_REG)
12108 (plus:SI (reg:SI SP_REG)
12109 (match_operand:SI 3)))])]
12112 ix86_expand_call (NULL, operands[0], operands[1],
12113 operands[2], operands[3], false);
12117 (define_insn "*call_pop"
12118 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
12120 (set (reg:SI SP_REG)
12121 (plus:SI (reg:SI SP_REG)
12122 (match_operand:SI 2 "immediate_operand" "i")))]
12123 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12124 "* return ix86_output_call_insn (insn, operands[0]);"
12125 [(set_attr "type" "call")])
12127 (define_insn "*sibcall_pop"
12128 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
12130 (set (reg:SI SP_REG)
12131 (plus:SI (reg:SI SP_REG)
12132 (match_operand:SI 2 "immediate_operand" "i")))]
12133 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12134 "* return ix86_output_call_insn (insn, operands[0]);"
12135 [(set_attr "type" "call")])
12137 (define_insn "*sibcall_pop_memory"
12138 [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
12140 (set (reg:SI SP_REG)
12141 (plus:SI (reg:SI SP_REG)
12142 (match_operand:SI 2 "immediate_operand" "i")))
12143 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12145 "* return ix86_output_call_insn (insn, operands[0]);"
12146 [(set_attr "type" "call")])
12149 [(set (match_operand:SI 0 "register_operand")
12150 (match_operand:SI 1 "memory_operand"))
12151 (parallel [(call (mem:QI (match_dup 0))
12153 (set (reg:SI SP_REG)
12154 (plus:SI (reg:SI SP_REG)
12155 (match_operand:SI 4 "immediate_operand")))])]
12156 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12157 && !reg_mentioned_p (operands[0],
12158 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12159 [(parallel [(call (mem:QI (match_dup 1))
12161 (set (reg:SI SP_REG)
12162 (plus:SI (reg:SI SP_REG)
12164 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12167 [(set (match_operand:SI 0 "register_operand")
12168 (match_operand:SI 1 "memory_operand"))
12169 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12170 (parallel [(call (mem:QI (match_dup 0))
12172 (set (reg:SI SP_REG)
12173 (plus:SI (reg:SI SP_REG)
12174 (match_operand:SI 4 "immediate_operand")))])]
12175 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12176 && !reg_mentioned_p (operands[0],
12177 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12178 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12179 (parallel [(call (mem:QI (match_dup 1))
12181 (set (reg:SI SP_REG)
12182 (plus:SI (reg:SI SP_REG)
12184 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12186 ;; Combining simple memory jump instruction
12189 [(set (match_operand:W 0 "register_operand")
12190 (match_operand:W 1 "memory_operand"))
12191 (set (pc) (match_dup 0))]
12192 "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
12193 [(set (pc) (match_dup 1))])
12195 ;; Call subroutine, returning value in operand 0
12197 (define_expand "call_value"
12198 [(set (match_operand 0)
12199 (call (match_operand:QI 1)
12200 (match_operand 2)))
12201 (use (match_operand 3))]
12204 ix86_expand_call (operands[0], operands[1], operands[2],
12205 operands[3], NULL, false);
12209 (define_expand "sibcall_value"
12210 [(set (match_operand 0)
12211 (call (match_operand:QI 1)
12212 (match_operand 2)))
12213 (use (match_operand 3))]
12216 ix86_expand_call (operands[0], operands[1], operands[2],
12217 operands[3], NULL, true);
12221 (define_insn "*call_value"
12222 [(set (match_operand 0)
12223 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
12224 (match_operand 2)))]
12225 "!SIBLING_CALL_P (insn)"
12226 "* return ix86_output_call_insn (insn, operands[1]);"
12227 [(set_attr "type" "callv")])
12229 ;; This covers both call and sibcall since only GOT slot is allowed.
12230 (define_insn "*call_value_got_x32"
12231 [(set (match_operand 0)
12234 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
12235 (match_operand 2)))]
12238 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
12239 return ix86_output_call_insn (insn, fnaddr);
12241 [(set_attr "type" "callv")])
12243 ;; Since sibcall never returns, we can only use call-clobbered register
12245 (define_insn "*sibcall_value_GOT_32"
12246 [(set (match_operand 0)
12249 (match_operand:SI 1 "register_no_elim_operand" "U")
12250 (match_operand:SI 2 "GOT32_symbol_operand"))))
12251 (match_operand 3)))]
12252 "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
12254 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
12255 fnaddr = gen_const_mem (SImode, fnaddr);
12256 return ix86_output_call_insn (insn, fnaddr);
12258 [(set_attr "type" "callv")])
12260 (define_insn "*sibcall_value"
12261 [(set (match_operand 0)
12262 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
12263 (match_operand 2)))]
12264 "SIBLING_CALL_P (insn)"
12265 "* return ix86_output_call_insn (insn, operands[1]);"
12266 [(set_attr "type" "callv")])
12268 (define_insn "*sibcall_value_memory"
12269 [(set (match_operand 0)
12270 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
12271 (match_operand 2)))
12272 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12274 "* return ix86_output_call_insn (insn, operands[1]);"
12275 [(set_attr "type" "callv")])
12278 [(set (match_operand:W 0 "register_operand")
12279 (match_operand:W 1 "memory_operand"))
12280 (set (match_operand 2)
12281 (call (mem:QI (match_dup 0))
12282 (match_operand 3)))]
12283 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
12284 && !reg_mentioned_p (operands[0],
12285 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12286 [(parallel [(set (match_dup 2)
12287 (call (mem:QI (match_dup 1))
12289 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12292 [(set (match_operand:W 0 "register_operand")
12293 (match_operand:W 1 "memory_operand"))
12294 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12295 (set (match_operand 2)
12296 (call (mem:QI (match_dup 0))
12297 (match_operand 3)))]
12298 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
12299 && !reg_mentioned_p (operands[0],
12300 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12301 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12302 (parallel [(set (match_dup 2)
12303 (call (mem:QI (match_dup 1))
12305 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12307 (define_expand "call_value_pop"
12308 [(parallel [(set (match_operand 0)
12309 (call (match_operand:QI 1)
12310 (match_operand:SI 2)))
12311 (set (reg:SI SP_REG)
12312 (plus:SI (reg:SI SP_REG)
12313 (match_operand:SI 4)))])]
12316 ix86_expand_call (operands[0], operands[1], operands[2],
12317 operands[3], operands[4], false);
12321 (define_insn "*call_value_pop"
12322 [(set (match_operand 0)
12323 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
12324 (match_operand 2)))
12325 (set (reg:SI SP_REG)
12326 (plus:SI (reg:SI SP_REG)
12327 (match_operand:SI 3 "immediate_operand" "i")))]
12328 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12329 "* return ix86_output_call_insn (insn, operands[1]);"
12330 [(set_attr "type" "callv")])
12332 (define_insn "*sibcall_value_pop"
12333 [(set (match_operand 0)
12334 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
12335 (match_operand 2)))
12336 (set (reg:SI SP_REG)
12337 (plus:SI (reg:SI SP_REG)
12338 (match_operand:SI 3 "immediate_operand" "i")))]
12339 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12340 "* return ix86_output_call_insn (insn, operands[1]);"
12341 [(set_attr "type" "callv")])
12343 (define_insn "*sibcall_value_pop_memory"
12344 [(set (match_operand 0)
12345 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
12346 (match_operand 2)))
12347 (set (reg:SI SP_REG)
12348 (plus:SI (reg:SI SP_REG)
12349 (match_operand:SI 3 "immediate_operand" "i")))
12350 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12352 "* return ix86_output_call_insn (insn, operands[1]);"
12353 [(set_attr "type" "callv")])
12356 [(set (match_operand:SI 0 "register_operand")
12357 (match_operand:SI 1 "memory_operand"))
12358 (parallel [(set (match_operand 2)
12359 (call (mem:QI (match_dup 0))
12360 (match_operand 3)))
12361 (set (reg:SI SP_REG)
12362 (plus:SI (reg:SI SP_REG)
12363 (match_operand:SI 4 "immediate_operand")))])]
12364 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12365 && !reg_mentioned_p (operands[0],
12366 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12367 [(parallel [(set (match_dup 2)
12368 (call (mem:QI (match_dup 1))
12370 (set (reg:SI SP_REG)
12371 (plus:SI (reg:SI SP_REG)
12373 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12376 [(set (match_operand:SI 0 "register_operand")
12377 (match_operand:SI 1 "memory_operand"))
12378 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12379 (parallel [(set (match_operand 2)
12380 (call (mem:QI (match_dup 0))
12381 (match_operand 3)))
12382 (set (reg:SI SP_REG)
12383 (plus:SI (reg:SI SP_REG)
12384 (match_operand:SI 4 "immediate_operand")))])]
12385 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12386 && !reg_mentioned_p (operands[0],
12387 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12388 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12389 (parallel [(set (match_dup 2)
12390 (call (mem:QI (match_dup 1))
12392 (set (reg:SI SP_REG)
12393 (plus:SI (reg:SI SP_REG)
12395 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12397 ;; Call subroutine returning any type.
12399 (define_expand "untyped_call"
12400 [(parallel [(call (match_operand 0)
12403 (match_operand 2)])]
12408 /* In order to give reg-stack an easier job in validating two
12409 coprocessor registers as containing a possible return value,
12410 simply pretend the untyped call returns a complex long double
12413 We can't use SSE_REGPARM_MAX here since callee is unprototyped
12414 and should have the default ABI. */
12416 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12417 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12418 operands[0], const0_rtx,
12419 GEN_INT ((TARGET_64BIT
12420 ? (ix86_abi == SYSV_ABI
12421 ? X86_64_SSE_REGPARM_MAX
12422 : X86_64_MS_SSE_REGPARM_MAX)
12423 : X86_32_SSE_REGPARM_MAX)
12427 for (i = 0; i < XVECLEN (operands[2], 0); i++)
12429 rtx set = XVECEXP (operands[2], 0, i);
12430 emit_move_insn (SET_DEST (set), SET_SRC (set));
12433 /* The optimizer does not know that the call sets the function value
12434 registers we stored in the result block. We avoid problems by
12435 claiming that all hard registers are used and clobbered at this
12437 emit_insn (gen_blockage ());
12442 ;; Prologue and epilogue instructions
12444 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12445 ;; all of memory. This blocks insns from being moved across this point.
12447 (define_insn "blockage"
12448 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12451 [(set_attr "length" "0")])
12453 ;; Do not schedule instructions accessing memory across this point.
12455 (define_expand "memory_blockage"
12456 [(set (match_dup 0)
12457 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12460 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12461 MEM_VOLATILE_P (operands[0]) = 1;
12464 (define_insn "*memory_blockage"
12465 [(set (match_operand:BLK 0)
12466 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12469 [(set_attr "length" "0")])
12471 ;; As USE insns aren't meaningful after reload, this is used instead
12472 ;; to prevent deleting instructions setting registers for PIC code
12473 (define_insn "prologue_use"
12474 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12477 [(set_attr "length" "0")])
12479 ;; Insn emitted into the body of a function to return from a function.
12480 ;; This is only done if the function's epilogue is known to be simple.
12481 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12483 (define_expand "return"
12485 "ix86_can_use_return_insn_p ()"
12487 if (crtl->args.pops_args)
12489 rtx popc = GEN_INT (crtl->args.pops_args);
12490 emit_jump_insn (gen_simple_return_pop_internal (popc));
12495 ;; We need to disable this for TARGET_SEH, as otherwise
12496 ;; shrink-wrapped prologue gets enabled too. This might exceed
12497 ;; the maximum size of prologue in unwind information.
12498 ;; Also disallow shrink-wrapping if using stack slot to pass the
12499 ;; static chain pointer - the first instruction has to be pushl %esi
12500 ;; and it can't be moved around, as we use alternate entry points
12503 (define_expand "simple_return"
12505 "!TARGET_SEH && !ix86_static_chain_on_stack"
12507 if (crtl->args.pops_args)
12509 rtx popc = GEN_INT (crtl->args.pops_args);
12510 emit_jump_insn (gen_simple_return_pop_internal (popc));
12515 (define_insn "simple_return_internal"
12519 [(set_attr "length" "1")
12520 (set_attr "atom_unit" "jeu")
12521 (set_attr "length_immediate" "0")
12522 (set_attr "modrm" "0")
12523 (set_attr "maybe_prefix_bnd" "1")])
12525 (define_insn "interrupt_return"
12527 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
12530 return TARGET_64BIT ? "iretq" : "iret";
12533 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12534 ;; instruction Athlon and K8 have.
12536 (define_insn "simple_return_internal_long"
12538 (unspec [(const_int 0)] UNSPEC_REP)]
12541 if (ix86_bnd_prefixed_insn_p (insn))
12544 return "rep%; ret";
12546 [(set_attr "length" "2")
12547 (set_attr "atom_unit" "jeu")
12548 (set_attr "length_immediate" "0")
12549 (set_attr "prefix_rep" "1")
12550 (set_attr "modrm" "0")])
12552 (define_insn "simple_return_pop_internal"
12554 (use (match_operand:SI 0 "const_int_operand"))]
12557 [(set_attr "length" "3")
12558 (set_attr "atom_unit" "jeu")
12559 (set_attr "length_immediate" "2")
12560 (set_attr "modrm" "0")
12561 (set_attr "maybe_prefix_bnd" "1")])
12563 (define_insn "simple_return_indirect_internal"
12565 (use (match_operand:SI 0 "register_operand" "r"))]
12568 [(set_attr "type" "ibr")
12569 (set_attr "length_immediate" "0")
12570 (set_attr "maybe_prefix_bnd" "1")])
12576 [(set_attr "length" "1")
12577 (set_attr "length_immediate" "0")
12578 (set_attr "modrm" "0")])
12580 ;; Generate nops. Operand 0 is the number of nops, up to 8.
12581 (define_insn "nops"
12582 [(unspec_volatile [(match_operand 0 "const_int_operand")]
12586 int num = INTVAL (operands[0]);
12588 gcc_assert (IN_RANGE (num, 1, 8));
12591 fputs ("\tnop\n", asm_out_file);
12595 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12596 (set_attr "length_immediate" "0")
12597 (set_attr "modrm" "0")])
12599 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12600 ;; branch prediction penalty for the third jump in a 16-byte
12604 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12607 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12608 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12610 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12611 The align insn is used to avoid 3 jump instructions in the row to improve
12612 branch prediction and the benefits hardly outweigh the cost of extra 8
12613 nops on the average inserted by full alignment pseudo operation. */
12617 [(set_attr "length" "16")])
12619 (define_expand "prologue"
12622 "ix86_expand_prologue (); DONE;")
12624 (define_expand "set_got"
12626 [(set (match_operand:SI 0 "register_operand")
12627 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12628 (clobber (reg:CC FLAGS_REG))])]
12631 if (flag_pic && !TARGET_VXWORKS_RTP)
12632 ix86_pc_thunk_call_expanded = true;
12635 (define_insn "*set_got"
12636 [(set (match_operand:SI 0 "register_operand" "=r")
12637 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12638 (clobber (reg:CC FLAGS_REG))]
12640 "* return output_set_got (operands[0], NULL_RTX);"
12641 [(set_attr "type" "multi")
12642 (set_attr "length" "12")])
12644 (define_expand "set_got_labelled"
12646 [(set (match_operand:SI 0 "register_operand")
12647 (unspec:SI [(label_ref (match_operand 1))]
12649 (clobber (reg:CC FLAGS_REG))])]
12652 if (flag_pic && !TARGET_VXWORKS_RTP)
12653 ix86_pc_thunk_call_expanded = true;
12656 (define_insn "*set_got_labelled"
12657 [(set (match_operand:SI 0 "register_operand" "=r")
12658 (unspec:SI [(label_ref (match_operand 1))]
12660 (clobber (reg:CC FLAGS_REG))]
12662 "* return output_set_got (operands[0], operands[1]);"
12663 [(set_attr "type" "multi")
12664 (set_attr "length" "12")])
12666 (define_insn "set_got_rex64"
12667 [(set (match_operand:DI 0 "register_operand" "=r")
12668 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12670 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12671 [(set_attr "type" "lea")
12672 (set_attr "length_address" "4")
12673 (set_attr "modrm_class" "unknown")
12674 (set_attr "mode" "DI")])
12676 (define_insn "set_rip_rex64"
12677 [(set (match_operand:DI 0 "register_operand" "=r")
12678 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12680 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12681 [(set_attr "type" "lea")
12682 (set_attr "length_address" "4")
12683 (set_attr "mode" "DI")])
12685 (define_insn "set_got_offset_rex64"
12686 [(set (match_operand:DI 0 "register_operand" "=r")
12688 [(label_ref (match_operand 1))]
12689 UNSPEC_SET_GOT_OFFSET))]
12691 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12692 [(set_attr "type" "imov")
12693 (set_attr "length_immediate" "0")
12694 (set_attr "length_address" "8")
12695 (set_attr "mode" "DI")])
12697 (define_expand "epilogue"
12700 "ix86_expand_epilogue (1); DONE;")
12702 (define_expand "sibcall_epilogue"
12705 "ix86_expand_epilogue (0); DONE;")
12707 (define_expand "eh_return"
12708 [(use (match_operand 0 "register_operand"))]
12711 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12713 /* Tricky bit: we write the address of the handler to which we will
12714 be returning into someone else's stack frame, one word below the
12715 stack address we wish to restore. */
12716 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12717 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12718 tmp = gen_rtx_MEM (Pmode, tmp);
12719 emit_move_insn (tmp, ra);
12721 emit_jump_insn (gen_eh_return_internal ());
12726 (define_insn_and_split "eh_return_internal"
12730 "epilogue_completed"
12732 "ix86_expand_epilogue (2); DONE;")
12734 (define_insn "leave"
12735 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12736 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12737 (clobber (mem:BLK (scratch)))]
12740 [(set_attr "type" "leave")])
12742 (define_insn "leave_rex64"
12743 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12744 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12745 (clobber (mem:BLK (scratch)))]
12748 [(set_attr "type" "leave")])
12750 ;; Handle -fsplit-stack.
12752 (define_expand "split_stack_prologue"
12756 ix86_expand_split_stack_prologue ();
12760 ;; In order to support the call/return predictor, we use a return
12761 ;; instruction which the middle-end doesn't see.
12762 (define_insn "split_stack_return"
12763 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12764 UNSPECV_SPLIT_STACK_RETURN)]
12767 if (operands[0] == const0_rtx)
12772 [(set_attr "atom_unit" "jeu")
12773 (set_attr "modrm" "0")
12774 (set (attr "length")
12775 (if_then_else (match_operand:SI 0 "const0_operand")
12778 (set (attr "length_immediate")
12779 (if_then_else (match_operand:SI 0 "const0_operand")
12783 ;; If there are operand 0 bytes available on the stack, jump to
12786 (define_expand "split_stack_space_check"
12787 [(set (pc) (if_then_else
12788 (ltu (minus (reg SP_REG)
12789 (match_operand 0 "register_operand"))
12791 (label_ref (match_operand 1))
12795 rtx reg = gen_reg_rtx (Pmode);
12797 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
12799 operands[2] = ix86_split_stack_guard ();
12800 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
12805 ;; Bit manipulation instructions.
12807 (define_expand "ffs<mode>2"
12808 [(set (match_dup 2) (const_int -1))
12809 (parallel [(set (match_dup 3) (match_dup 4))
12810 (set (match_operand:SWI48 0 "register_operand")
12812 (match_operand:SWI48 1 "nonimmediate_operand")))])
12813 (set (match_dup 0) (if_then_else:SWI48
12814 (eq (match_dup 3) (const_int 0))
12817 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12818 (clobber (reg:CC FLAGS_REG))])]
12821 machine_mode flags_mode;
12823 if (<MODE>mode == SImode && !TARGET_CMOVE)
12825 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12829 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12831 operands[2] = gen_reg_rtx (<MODE>mode);
12832 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12833 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12836 (define_insn_and_split "ffssi2_no_cmove"
12837 [(set (match_operand:SI 0 "register_operand" "=r")
12838 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12839 (clobber (match_scratch:SI 2 "=&q"))
12840 (clobber (reg:CC FLAGS_REG))]
12843 "&& reload_completed"
12844 [(parallel [(set (match_dup 4) (match_dup 5))
12845 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12846 (set (strict_low_part (match_dup 3))
12847 (eq:QI (match_dup 4) (const_int 0)))
12848 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12849 (clobber (reg:CC FLAGS_REG))])
12850 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12851 (clobber (reg:CC FLAGS_REG))])
12852 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12853 (clobber (reg:CC FLAGS_REG))])]
12855 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12857 operands[3] = gen_lowpart (QImode, operands[2]);
12858 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12859 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12861 ix86_expand_clear (operands[2]);
12864 (define_insn_and_split "*tzcnt<mode>_1"
12865 [(set (reg:CCC FLAGS_REG)
12866 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12868 (set (match_operand:SWI48 0 "register_operand" "=r")
12869 (ctz:SWI48 (match_dup 1)))]
12871 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12872 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
12873 && optimize_function_for_speed_p (cfun)
12874 && !reg_mentioned_p (operands[0], operands[1])"
12876 [(set (reg:CCC FLAGS_REG)
12877 (compare:CCC (match_dup 1) (const_int 0)))
12879 (ctz:SWI48 (match_dup 1)))
12880 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
12881 "ix86_expand_clear (operands[0]);"
12882 [(set_attr "type" "alu1")
12883 (set_attr "prefix_0f" "1")
12884 (set_attr "prefix_rep" "1")
12885 (set_attr "btver2_decode" "double")
12886 (set_attr "mode" "<MODE>")])
12888 ; False dependency happens when destination is only updated by tzcnt,
12889 ; lzcnt or popcnt. There is no false dependency when destination is
12890 ; also used in source.
12891 (define_insn "*tzcnt<mode>_1_falsedep"
12892 [(set (reg:CCC FLAGS_REG)
12893 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12895 (set (match_operand:SWI48 0 "register_operand" "=r")
12896 (ctz:SWI48 (match_dup 1)))
12897 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12898 UNSPEC_INSN_FALSE_DEP)]
12900 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12901 [(set_attr "type" "alu1")
12902 (set_attr "prefix_0f" "1")
12903 (set_attr "prefix_rep" "1")
12904 (set_attr "btver2_decode" "double")
12905 (set_attr "mode" "<MODE>")])
12907 (define_insn "*bsf<mode>_1"
12908 [(set (reg:CCZ FLAGS_REG)
12909 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12911 (set (match_operand:SWI48 0 "register_operand" "=r")
12912 (ctz:SWI48 (match_dup 1)))]
12914 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12915 [(set_attr "type" "alu1")
12916 (set_attr "prefix_0f" "1")
12917 (set_attr "btver2_decode" "double")
12918 (set_attr "znver1_decode" "vector")
12919 (set_attr "mode" "<MODE>")])
12921 (define_insn_and_split "ctz<mode>2"
12922 [(set (match_operand:SWI48 0 "register_operand" "=r")
12924 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12925 (clobber (reg:CC FLAGS_REG))]
12929 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12930 else if (optimize_function_for_size_p (cfun))
12932 else if (TARGET_GENERIC)
12933 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12934 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12936 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12938 "(TARGET_BMI || TARGET_GENERIC)
12939 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
12940 && optimize_function_for_speed_p (cfun)
12941 && !reg_mentioned_p (operands[0], operands[1])"
12943 [(set (match_dup 0)
12944 (ctz:SWI48 (match_dup 1)))
12945 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12946 (clobber (reg:CC FLAGS_REG))])]
12947 "ix86_expand_clear (operands[0]);"
12948 [(set_attr "type" "alu1")
12949 (set_attr "prefix_0f" "1")
12950 (set (attr "prefix_rep")
12952 (ior (match_test "TARGET_BMI")
12953 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12954 (match_test "TARGET_GENERIC")))
12956 (const_string "0")))
12957 (set_attr "mode" "<MODE>")])
12959 ; False dependency happens when destination is only updated by tzcnt,
12960 ; lzcnt or popcnt. There is no false dependency when destination is
12961 ; also used in source.
12962 (define_insn "*ctz<mode>2_falsedep"
12963 [(set (match_operand:SWI48 0 "register_operand" "=r")
12965 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12966 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12967 UNSPEC_INSN_FALSE_DEP)
12968 (clobber (reg:CC FLAGS_REG))]
12972 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12973 else if (TARGET_GENERIC)
12974 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12975 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12977 gcc_unreachable ();
12979 [(set_attr "type" "alu1")
12980 (set_attr "prefix_0f" "1")
12981 (set_attr "prefix_rep" "1")
12982 (set_attr "mode" "<MODE>")])
12984 (define_insn "bsr_rex64"
12985 [(set (match_operand:DI 0 "register_operand" "=r")
12986 (minus:DI (const_int 63)
12987 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12988 (clobber (reg:CC FLAGS_REG))]
12990 "bsr{q}\t{%1, %0|%0, %1}"
12991 [(set_attr "type" "alu1")
12992 (set_attr "prefix_0f" "1")
12993 (set_attr "znver1_decode" "vector")
12994 (set_attr "mode" "DI")])
12997 [(set (match_operand:SI 0 "register_operand" "=r")
12998 (minus:SI (const_int 31)
12999 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13000 (clobber (reg:CC FLAGS_REG))]
13002 "bsr{l}\t{%1, %0|%0, %1}"
13003 [(set_attr "type" "alu1")
13004 (set_attr "prefix_0f" "1")
13005 (set_attr "znver1_decode" "vector")
13006 (set_attr "mode" "SI")])
13008 (define_insn "*bsrhi"
13009 [(set (match_operand:HI 0 "register_operand" "=r")
13010 (minus:HI (const_int 15)
13011 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13012 (clobber (reg:CC FLAGS_REG))]
13014 "bsr{w}\t{%1, %0|%0, %1}"
13015 [(set_attr "type" "alu1")
13016 (set_attr "prefix_0f" "1")
13017 (set_attr "znver1_decode" "vector")
13018 (set_attr "mode" "HI")])
13020 (define_expand "clz<mode>2"
13022 [(set (match_operand:SWI48 0 "register_operand")
13025 (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
13026 (clobber (reg:CC FLAGS_REG))])
13028 [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
13029 (clobber (reg:CC FLAGS_REG))])]
13034 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
13037 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
13040 (define_insn_and_split "clz<mode>2_lzcnt"
13041 [(set (match_operand:SWI48 0 "register_operand" "=r")
13043 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13044 (clobber (reg:CC FLAGS_REG))]
13046 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13047 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13048 && optimize_function_for_speed_p (cfun)
13049 && !reg_mentioned_p (operands[0], operands[1])"
13051 [(set (match_dup 0)
13052 (clz:SWI48 (match_dup 1)))
13053 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13054 (clobber (reg:CC FLAGS_REG))])]
13055 "ix86_expand_clear (operands[0]);"
13056 [(set_attr "prefix_rep" "1")
13057 (set_attr "type" "bitmanip")
13058 (set_attr "mode" "<MODE>")])
13060 ; False dependency happens when destination is only updated by tzcnt,
13061 ; lzcnt or popcnt. There is no false dependency when destination is
13062 ; also used in source.
13063 (define_insn "*clz<mode>2_lzcnt_falsedep"
13064 [(set (match_operand:SWI48 0 "register_operand" "=r")
13066 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13067 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13068 UNSPEC_INSN_FALSE_DEP)
13069 (clobber (reg:CC FLAGS_REG))]
13071 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13072 [(set_attr "prefix_rep" "1")
13073 (set_attr "type" "bitmanip")
13074 (set_attr "mode" "<MODE>")])
13076 (define_int_iterator LT_ZCNT
13077 [(UNSPEC_TZCNT "TARGET_BMI")
13078 (UNSPEC_LZCNT "TARGET_LZCNT")])
13080 (define_int_attr lt_zcnt
13081 [(UNSPEC_TZCNT "tzcnt")
13082 (UNSPEC_LZCNT "lzcnt")])
13084 (define_int_attr lt_zcnt_type
13085 [(UNSPEC_TZCNT "alu1")
13086 (UNSPEC_LZCNT "bitmanip")])
13088 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
13089 ;; provides operand size as output when source operand is zero.
13091 (define_insn_and_split "<lt_zcnt>_<mode>"
13092 [(set (match_operand:SWI48 0 "register_operand" "=r")
13094 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13095 (clobber (reg:CC FLAGS_REG))]
13097 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13098 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13099 && optimize_function_for_speed_p (cfun)
13100 && !reg_mentioned_p (operands[0], operands[1])"
13102 [(set (match_dup 0)
13103 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
13104 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13105 (clobber (reg:CC FLAGS_REG))])]
13106 "ix86_expand_clear (operands[0]);"
13107 [(set_attr "type" "<lt_zcnt_type>")
13108 (set_attr "prefix_0f" "1")
13109 (set_attr "prefix_rep" "1")
13110 (set_attr "mode" "<MODE>")])
13112 ; False dependency happens when destination is only updated by tzcnt,
13113 ; lzcnt or popcnt. There is no false dependency when destination is
13114 ; also used in source.
13115 (define_insn "*<lt_zcnt>_<mode>_falsedep"
13116 [(set (match_operand:SWI48 0 "register_operand" "=r")
13118 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13119 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13120 UNSPEC_INSN_FALSE_DEP)
13121 (clobber (reg:CC FLAGS_REG))]
13123 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13124 [(set_attr "type" "<lt_zcnt_type>")
13125 (set_attr "prefix_0f" "1")
13126 (set_attr "prefix_rep" "1")
13127 (set_attr "mode" "<MODE>")])
13129 (define_insn "<lt_zcnt>_hi"
13130 [(set (match_operand:HI 0 "register_operand" "=r")
13132 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13133 (clobber (reg:CC FLAGS_REG))]
13135 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
13136 [(set_attr "type" "<lt_zcnt_type>")
13137 (set_attr "prefix_0f" "1")
13138 (set_attr "prefix_rep" "1")
13139 (set_attr "mode" "HI")])
13141 ;; BMI instructions.
13143 (define_insn "bmi_bextr_<mode>"
13144 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
13145 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13146 (match_operand:SWI48 2 "register_operand" "r,r")]
13148 (clobber (reg:CC FLAGS_REG))]
13150 "bextr\t{%2, %1, %0|%0, %1, %2}"
13151 [(set_attr "type" "bitmanip")
13152 (set_attr "btver2_decode" "direct, double")
13153 (set_attr "mode" "<MODE>")])
13155 (define_insn "*bmi_bextr_<mode>_ccz"
13156 [(set (reg:CCZ FLAGS_REG)
13158 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13159 (match_operand:SWI48 2 "register_operand" "r,r")]
13162 (clobber (match_scratch:SWI48 0 "=r,r"))]
13164 "bextr\t{%2, %1, %0|%0, %1, %2}"
13165 [(set_attr "type" "bitmanip")
13166 (set_attr "btver2_decode" "direct, double")
13167 (set_attr "mode" "<MODE>")])
13169 (define_insn "*bmi_blsi_<mode>"
13170 [(set (match_operand:SWI48 0 "register_operand" "=r")
13173 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
13175 (clobber (reg:CC FLAGS_REG))]
13177 "blsi\t{%1, %0|%0, %1}"
13178 [(set_attr "type" "bitmanip")
13179 (set_attr "btver2_decode" "double")
13180 (set_attr "mode" "<MODE>")])
13182 (define_insn "*bmi_blsmsk_<mode>"
13183 [(set (match_operand:SWI48 0 "register_operand" "=r")
13186 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13189 (clobber (reg:CC FLAGS_REG))]
13191 "blsmsk\t{%1, %0|%0, %1}"
13192 [(set_attr "type" "bitmanip")
13193 (set_attr "btver2_decode" "double")
13194 (set_attr "mode" "<MODE>")])
13196 (define_insn "*bmi_blsr_<mode>"
13197 [(set (match_operand:SWI48 0 "register_operand" "=r")
13200 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13203 (clobber (reg:CC FLAGS_REG))]
13205 "blsr\t{%1, %0|%0, %1}"
13206 [(set_attr "type" "bitmanip")
13207 (set_attr "btver2_decode" "double")
13208 (set_attr "mode" "<MODE>")])
13210 ;; BMI2 instructions.
13211 (define_expand "bmi2_bzhi_<mode>3"
13213 [(set (match_operand:SWI48 0 "register_operand")
13214 (zero_extract:SWI48
13215 (match_operand:SWI48 1 "nonimmediate_operand")
13217 (and:SWI48 (match_operand:SWI48 2 "register_operand")
13221 (clobber (reg:CC FLAGS_REG))])]
13223 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
13225 (define_insn "*bmi2_bzhi_<mode>3"
13226 [(set (match_operand:SWI48 0 "register_operand" "=r")
13227 (zero_extract:SWI48
13228 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13230 (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
13232 (match_operand:SWI48 3 "const_int_operand" "n"))
13234 (clobber (reg:CC FLAGS_REG))]
13235 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13236 "bzhi\t{%2, %1, %0|%0, %1, %2}"
13237 [(set_attr "type" "bitmanip")
13238 (set_attr "prefix" "vex")
13239 (set_attr "mode" "<MODE>")])
13241 (define_insn "*bmi2_bzhi_<mode>3_1"
13242 [(set (match_operand:SWI48 0 "register_operand" "=r")
13243 (zero_extract:SWI48
13244 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13246 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13247 (match_operand:SWI48 3 "const_int_operand" "n"))
13249 (clobber (reg:CC FLAGS_REG))]
13250 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13251 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13252 [(set_attr "type" "bitmanip")
13253 (set_attr "prefix" "vex")
13254 (set_attr "mode" "<MODE>")])
13256 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
13257 [(set (reg:CCZ FLAGS_REG)
13259 (zero_extract:SWI48
13260 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13262 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13263 (match_operand:SWI48 3 "const_int_operand" "n"))
13266 (clobber (match_scratch:SWI48 0 "=r"))]
13267 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13268 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13269 [(set_attr "type" "bitmanip")
13270 (set_attr "prefix" "vex")
13271 (set_attr "mode" "<MODE>")])
13273 (define_insn "bmi2_pdep_<mode>3"
13274 [(set (match_operand:SWI48 0 "register_operand" "=r")
13275 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13276 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13279 "pdep\t{%2, %1, %0|%0, %1, %2}"
13280 [(set_attr "type" "bitmanip")
13281 (set_attr "prefix" "vex")
13282 (set_attr "mode" "<MODE>")])
13284 (define_insn "bmi2_pext_<mode>3"
13285 [(set (match_operand:SWI48 0 "register_operand" "=r")
13286 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13287 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13290 "pext\t{%2, %1, %0|%0, %1, %2}"
13291 [(set_attr "type" "bitmanip")
13292 (set_attr "prefix" "vex")
13293 (set_attr "mode" "<MODE>")])
13295 ;; TBM instructions.
13296 (define_insn "tbm_bextri_<mode>"
13297 [(set (match_operand:SWI48 0 "register_operand" "=r")
13298 (zero_extract:SWI48
13299 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13300 (match_operand 2 "const_0_to_255_operand" "N")
13301 (match_operand 3 "const_0_to_255_operand" "N")))
13302 (clobber (reg:CC FLAGS_REG))]
13305 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
13306 return "bextr\t{%2, %1, %0|%0, %1, %2}";
13308 [(set_attr "type" "bitmanip")
13309 (set_attr "mode" "<MODE>")])
13311 (define_insn "*tbm_blcfill_<mode>"
13312 [(set (match_operand:SWI48 0 "register_operand" "=r")
13315 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13318 (clobber (reg:CC FLAGS_REG))]
13320 "blcfill\t{%1, %0|%0, %1}"
13321 [(set_attr "type" "bitmanip")
13322 (set_attr "mode" "<MODE>")])
13324 (define_insn "*tbm_blci_<mode>"
13325 [(set (match_operand:SWI48 0 "register_operand" "=r")
13329 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13332 (clobber (reg:CC FLAGS_REG))]
13334 "blci\t{%1, %0|%0, %1}"
13335 [(set_attr "type" "bitmanip")
13336 (set_attr "mode" "<MODE>")])
13338 (define_insn "*tbm_blcic_<mode>"
13339 [(set (match_operand:SWI48 0 "register_operand" "=r")
13342 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13346 (clobber (reg:CC FLAGS_REG))]
13348 "blcic\t{%1, %0|%0, %1}"
13349 [(set_attr "type" "bitmanip")
13350 (set_attr "mode" "<MODE>")])
13352 (define_insn "*tbm_blcmsk_<mode>"
13353 [(set (match_operand:SWI48 0 "register_operand" "=r")
13356 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13359 (clobber (reg:CC FLAGS_REG))]
13361 "blcmsk\t{%1, %0|%0, %1}"
13362 [(set_attr "type" "bitmanip")
13363 (set_attr "mode" "<MODE>")])
13365 (define_insn "*tbm_blcs_<mode>"
13366 [(set (match_operand:SWI48 0 "register_operand" "=r")
13369 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13372 (clobber (reg:CC FLAGS_REG))]
13374 "blcs\t{%1, %0|%0, %1}"
13375 [(set_attr "type" "bitmanip")
13376 (set_attr "mode" "<MODE>")])
13378 (define_insn "*tbm_blsfill_<mode>"
13379 [(set (match_operand:SWI48 0 "register_operand" "=r")
13382 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13385 (clobber (reg:CC FLAGS_REG))]
13387 "blsfill\t{%1, %0|%0, %1}"
13388 [(set_attr "type" "bitmanip")
13389 (set_attr "mode" "<MODE>")])
13391 (define_insn "*tbm_blsic_<mode>"
13392 [(set (match_operand:SWI48 0 "register_operand" "=r")
13395 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13399 (clobber (reg:CC FLAGS_REG))]
13401 "blsic\t{%1, %0|%0, %1}"
13402 [(set_attr "type" "bitmanip")
13403 (set_attr "mode" "<MODE>")])
13405 (define_insn "*tbm_t1mskc_<mode>"
13406 [(set (match_operand:SWI48 0 "register_operand" "=r")
13409 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13413 (clobber (reg:CC FLAGS_REG))]
13415 "t1mskc\t{%1, %0|%0, %1}"
13416 [(set_attr "type" "bitmanip")
13417 (set_attr "mode" "<MODE>")])
13419 (define_insn "*tbm_tzmsk_<mode>"
13420 [(set (match_operand:SWI48 0 "register_operand" "=r")
13423 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13427 (clobber (reg:CC FLAGS_REG))]
13429 "tzmsk\t{%1, %0|%0, %1}"
13430 [(set_attr "type" "bitmanip")
13431 (set_attr "mode" "<MODE>")])
13433 (define_insn_and_split "popcount<mode>2"
13434 [(set (match_operand:SWI48 0 "register_operand" "=r")
13436 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13437 (clobber (reg:CC FLAGS_REG))]
13441 return "popcnt\t{%1, %0|%0, %1}";
13443 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13446 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13447 && optimize_function_for_speed_p (cfun)
13448 && !reg_mentioned_p (operands[0], operands[1])"
13450 [(set (match_dup 0)
13451 (popcount:SWI48 (match_dup 1)))
13452 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13453 (clobber (reg:CC FLAGS_REG))])]
13454 "ix86_expand_clear (operands[0]);"
13455 [(set_attr "prefix_rep" "1")
13456 (set_attr "type" "bitmanip")
13457 (set_attr "mode" "<MODE>")])
13459 ; False dependency happens when destination is only updated by tzcnt,
13460 ; lzcnt or popcnt. There is no false dependency when destination is
13461 ; also used in source.
13462 (define_insn "*popcount<mode>2_falsedep"
13463 [(set (match_operand:SWI48 0 "register_operand" "=r")
13465 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13466 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13467 UNSPEC_INSN_FALSE_DEP)
13468 (clobber (reg:CC FLAGS_REG))]
13472 return "popcnt\t{%1, %0|%0, %1}";
13474 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13477 [(set_attr "prefix_rep" "1")
13478 (set_attr "type" "bitmanip")
13479 (set_attr "mode" "<MODE>")])
13481 (define_insn_and_split "*popcounthi2_1"
13482 [(set (match_operand:SI 0 "register_operand")
13484 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
13485 (clobber (reg:CC FLAGS_REG))]
13487 && can_create_pseudo_p ()"
13492 rtx tmp = gen_reg_rtx (HImode);
13494 emit_insn (gen_popcounthi2 (tmp, operands[1]));
13495 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
13499 (define_insn "popcounthi2"
13500 [(set (match_operand:HI 0 "register_operand" "=r")
13502 (match_operand:HI 1 "nonimmediate_operand" "rm")))
13503 (clobber (reg:CC FLAGS_REG))]
13507 return "popcnt\t{%1, %0|%0, %1}";
13509 return "popcnt{w}\t{%1, %0|%0, %1}";
13512 [(set_attr "prefix_rep" "1")
13513 (set_attr "type" "bitmanip")
13514 (set_attr "mode" "HI")])
13516 (define_expand "bswapdi2"
13517 [(set (match_operand:DI 0 "register_operand")
13518 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
13522 operands[1] = force_reg (DImode, operands[1]);
13525 (define_expand "bswapsi2"
13526 [(set (match_operand:SI 0 "register_operand")
13527 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
13532 else if (TARGET_BSWAP)
13533 operands[1] = force_reg (SImode, operands[1]);
13536 rtx x = operands[0];
13538 emit_move_insn (x, operands[1]);
13539 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13540 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
13541 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13546 (define_insn "*bswap<mode>2_movbe"
13547 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
13548 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
13550 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13553 movbe\t{%1, %0|%0, %1}
13554 movbe\t{%1, %0|%0, %1}"
13555 [(set_attr "type" "bitmanip,imov,imov")
13556 (set_attr "modrm" "0,1,1")
13557 (set_attr "prefix_0f" "*,1,1")
13558 (set_attr "prefix_extra" "*,1,1")
13559 (set_attr "mode" "<MODE>")])
13561 (define_insn "*bswap<mode>2"
13562 [(set (match_operand:SWI48 0 "register_operand" "=r")
13563 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
13566 [(set_attr "type" "bitmanip")
13567 (set_attr "modrm" "0")
13568 (set_attr "mode" "<MODE>")])
13570 (define_insn "*bswaphi_lowpart_1"
13571 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
13572 (bswap:HI (match_dup 0)))
13573 (clobber (reg:CC FLAGS_REG))]
13574 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
13576 xchg{b}\t{%h0, %b0|%b0, %h0}
13577 rol{w}\t{$8, %0|%0, 8}"
13578 [(set_attr "length" "2,4")
13579 (set_attr "mode" "QI,HI")])
13581 (define_insn "bswaphi_lowpart"
13582 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
13583 (bswap:HI (match_dup 0)))
13584 (clobber (reg:CC FLAGS_REG))]
13586 "rol{w}\t{$8, %0|%0, 8}"
13587 [(set_attr "length" "4")
13588 (set_attr "mode" "HI")])
13590 (define_expand "paritydi2"
13591 [(set (match_operand:DI 0 "register_operand")
13592 (parity:DI (match_operand:DI 1 "register_operand")))]
13595 rtx scratch = gen_reg_rtx (QImode);
13597 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
13598 NULL_RTX, operands[1]));
13600 ix86_expand_setcc (scratch, ORDERED,
13601 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
13604 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
13607 rtx tmp = gen_reg_rtx (SImode);
13609 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
13610 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
13615 (define_expand "paritysi2"
13616 [(set (match_operand:SI 0 "register_operand")
13617 (parity:SI (match_operand:SI 1 "register_operand")))]
13620 rtx scratch = gen_reg_rtx (QImode);
13622 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
13624 ix86_expand_setcc (scratch, ORDERED,
13625 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
13627 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
13631 (define_insn_and_split "paritydi2_cmp"
13632 [(set (reg:CC FLAGS_REG)
13633 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
13635 (clobber (match_scratch:DI 0 "=r"))
13636 (clobber (match_scratch:SI 1 "=&r"))
13637 (clobber (match_scratch:HI 2 "=Q"))]
13640 "&& reload_completed"
13642 [(set (match_dup 1)
13643 (xor:SI (match_dup 1) (match_dup 4)))
13644 (clobber (reg:CC FLAGS_REG))])
13646 [(set (reg:CC FLAGS_REG)
13647 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13648 (clobber (match_dup 1))
13649 (clobber (match_dup 2))])]
13651 operands[4] = gen_lowpart (SImode, operands[3]);
13655 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
13656 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
13659 operands[1] = gen_highpart (SImode, operands[3]);
13662 (define_insn_and_split "paritysi2_cmp"
13663 [(set (reg:CC FLAGS_REG)
13664 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
13666 (clobber (match_scratch:SI 0 "=r"))
13667 (clobber (match_scratch:HI 1 "=&Q"))]
13670 "&& reload_completed"
13672 [(set (match_dup 1)
13673 (xor:HI (match_dup 1) (match_dup 3)))
13674 (clobber (reg:CC FLAGS_REG))])
13676 [(set (reg:CC FLAGS_REG)
13677 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13678 (clobber (match_dup 1))])]
13680 operands[3] = gen_lowpart (HImode, operands[2]);
13682 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
13683 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
13686 (define_insn "*parityhi2_cmp"
13687 [(set (reg:CC FLAGS_REG)
13688 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
13690 (clobber (match_scratch:HI 0 "=Q"))]
13692 "xor{b}\t{%h0, %b0|%b0, %h0}"
13693 [(set_attr "length" "2")
13694 (set_attr "mode" "HI")])
13697 ;; Thread-local storage patterns for ELF.
13699 ;; Note that these code sequences must appear exactly as shown
13700 ;; in order to allow linker relaxation.
13702 (define_insn "*tls_global_dynamic_32_gnu"
13703 [(set (match_operand:SI 0 "register_operand" "=a")
13705 [(match_operand:SI 1 "register_operand" "Yb")
13706 (match_operand 2 "tls_symbolic_operand")
13707 (match_operand 3 "constant_call_address_operand" "Bz")
13710 (clobber (match_scratch:SI 4 "=d"))
13711 (clobber (match_scratch:SI 5 "=c"))
13712 (clobber (reg:CC FLAGS_REG))]
13713 "!TARGET_64BIT && TARGET_GNU_TLS"
13715 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13717 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
13720 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
13721 if (TARGET_SUN_TLS)
13722 #ifdef HAVE_AS_IX86_TLSGDPLT
13723 return "call\t%a2@tlsgdplt";
13725 return "call\t%p3@plt";
13727 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13728 return "call\t%P3";
13729 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
13731 [(set_attr "type" "multi")
13732 (set_attr "length" "12")])
13734 (define_expand "tls_global_dynamic_32"
13736 [(set (match_operand:SI 0 "register_operand")
13737 (unspec:SI [(match_operand:SI 2 "register_operand")
13738 (match_operand 1 "tls_symbolic_operand")
13739 (match_operand 3 "constant_call_address_operand")
13742 (clobber (match_scratch:SI 4))
13743 (clobber (match_scratch:SI 5))
13744 (clobber (reg:CC FLAGS_REG))])]
13746 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13748 (define_insn "*tls_global_dynamic_64_<mode>"
13749 [(set (match_operand:P 0 "register_operand" "=a")
13751 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
13752 (match_operand 3)))
13753 (unspec:P [(match_operand 1 "tls_symbolic_operand")
13759 fputs (ASM_BYTE "0x66\n", asm_out_file);
13761 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13762 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13763 fputs (ASM_SHORT "0x6666\n", asm_out_file);
13765 fputs (ASM_BYTE "0x66\n", asm_out_file);
13766 fputs ("\trex64\n", asm_out_file);
13767 if (TARGET_SUN_TLS)
13768 return "call\t%p2@plt";
13769 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13770 return "call\t%P2";
13771 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
13773 [(set_attr "type" "multi")
13774 (set (attr "length")
13775 (symbol_ref "TARGET_X32 ? 15 : 16"))])
13777 (define_insn "*tls_global_dynamic_64_largepic"
13778 [(set (match_operand:DI 0 "register_operand" "=a")
13780 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
13781 (match_operand:DI 3 "immediate_operand" "i")))
13782 (match_operand 4)))
13783 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13786 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13787 && GET_CODE (operands[3]) == CONST
13788 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13789 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13792 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13793 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13794 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13795 return "call\t{*%%rax|rax}";
13797 [(set_attr "type" "multi")
13798 (set_attr "length" "22")])
13800 (define_expand "tls_global_dynamic_64_<mode>"
13802 [(set (match_operand:P 0 "register_operand")
13804 (mem:QI (match_operand 2))
13806 (unspec:P [(match_operand 1 "tls_symbolic_operand")
13810 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13812 (define_insn "*tls_local_dynamic_base_32_gnu"
13813 [(set (match_operand:SI 0 "register_operand" "=a")
13815 [(match_operand:SI 1 "register_operand" "Yb")
13816 (match_operand 2 "constant_call_address_operand" "Bz")
13818 UNSPEC_TLS_LD_BASE))
13819 (clobber (match_scratch:SI 3 "=d"))
13820 (clobber (match_scratch:SI 4 "=c"))
13821 (clobber (reg:CC FLAGS_REG))]
13822 "!TARGET_64BIT && TARGET_GNU_TLS"
13825 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13826 if (TARGET_SUN_TLS)
13828 if (HAVE_AS_IX86_TLSLDMPLT)
13829 return "call\t%&@tlsldmplt";
13831 return "call\t%p2@plt";
13833 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13834 return "call\t%P2";
13835 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
13837 [(set_attr "type" "multi")
13838 (set_attr "length" "11")])
13840 (define_expand "tls_local_dynamic_base_32"
13842 [(set (match_operand:SI 0 "register_operand")
13844 [(match_operand:SI 1 "register_operand")
13845 (match_operand 2 "constant_call_address_operand")
13847 UNSPEC_TLS_LD_BASE))
13848 (clobber (match_scratch:SI 3))
13849 (clobber (match_scratch:SI 4))
13850 (clobber (reg:CC FLAGS_REG))])]
13852 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13854 (define_insn "*tls_local_dynamic_base_64_<mode>"
13855 [(set (match_operand:P 0 "register_operand" "=a")
13857 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13858 (match_operand 2)))
13859 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
13863 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13864 if (TARGET_SUN_TLS)
13865 return "call\t%p1@plt";
13866 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13867 return "call\t%P1";
13868 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
13870 [(set_attr "type" "multi")
13871 (set_attr "length" "12")])
13873 (define_insn "*tls_local_dynamic_base_64_largepic"
13874 [(set (match_operand:DI 0 "register_operand" "=a")
13876 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13877 (match_operand:DI 2 "immediate_operand" "i")))
13878 (match_operand 3)))
13879 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
13880 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13881 && GET_CODE (operands[2]) == CONST
13882 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13883 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13886 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13887 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13888 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13889 return "call\t{*%%rax|rax}";
13891 [(set_attr "type" "multi")
13892 (set_attr "length" "22")])
13894 (define_expand "tls_local_dynamic_base_64_<mode>"
13896 [(set (match_operand:P 0 "register_operand")
13898 (mem:QI (match_operand 1))
13900 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
13902 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13904 ;; Local dynamic of a single variable is a lose. Show combine how
13905 ;; to convert that back to global dynamic.
13907 (define_insn_and_split "*tls_local_dynamic_32_once"
13908 [(set (match_operand:SI 0 "register_operand" "=a")
13910 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13911 (match_operand 2 "constant_call_address_operand" "Bz")
13913 UNSPEC_TLS_LD_BASE)
13914 (const:SI (unspec:SI
13915 [(match_operand 3 "tls_symbolic_operand")]
13917 (clobber (match_scratch:SI 4 "=d"))
13918 (clobber (match_scratch:SI 5 "=c"))
13919 (clobber (reg:CC FLAGS_REG))]
13924 [(set (match_dup 0)
13925 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13928 (clobber (match_dup 4))
13929 (clobber (match_dup 5))
13930 (clobber (reg:CC FLAGS_REG))])])
13932 ;; Load and add the thread base pointer from %<tp_seg>:0.
13933 (define_insn_and_split "*load_tp_<mode>"
13934 [(set (match_operand:PTR 0 "register_operand" "=r")
13935 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
13939 [(set (match_dup 0)
13942 addr_space_t as = DEFAULT_TLS_SEG_REG;
13944 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
13945 set_mem_addr_space (operands[1], as);
13948 (define_insn_and_split "*load_tp_x32_zext"
13949 [(set (match_operand:DI 0 "register_operand" "=r")
13951 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13955 [(set (match_dup 0)
13956 (zero_extend:DI (match_dup 1)))]
13958 addr_space_t as = DEFAULT_TLS_SEG_REG;
13960 operands[1] = gen_const_mem (SImode, const0_rtx);
13961 set_mem_addr_space (operands[1], as);
13964 (define_insn_and_split "*add_tp_<mode>"
13965 [(set (match_operand:PTR 0 "register_operand" "=r")
13967 (unspec:PTR [(const_int 0)] UNSPEC_TP)
13968 (match_operand:PTR 1 "register_operand" "0")))
13969 (clobber (reg:CC FLAGS_REG))]
13974 [(set (match_dup 0)
13975 (plus:PTR (match_dup 1) (match_dup 2)))
13976 (clobber (reg:CC FLAGS_REG))])]
13978 addr_space_t as = DEFAULT_TLS_SEG_REG;
13980 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
13981 set_mem_addr_space (operands[2], as);
13984 (define_insn_and_split "*add_tp_x32_zext"
13985 [(set (match_operand:DI 0 "register_operand" "=r")
13987 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13988 (match_operand:SI 1 "register_operand" "0"))))
13989 (clobber (reg:CC FLAGS_REG))]
13994 [(set (match_dup 0)
13996 (plus:SI (match_dup 1) (match_dup 2))))
13997 (clobber (reg:CC FLAGS_REG))])]
13999 addr_space_t as = DEFAULT_TLS_SEG_REG;
14001 operands[2] = gen_const_mem (SImode, const0_rtx);
14002 set_mem_addr_space (operands[2], as);
14005 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
14006 ;; %rax as destination of the initial executable code sequence.
14007 (define_insn "tls_initial_exec_64_sun"
14008 [(set (match_operand:DI 0 "register_operand" "=a")
14010 [(match_operand 1 "tls_symbolic_operand")]
14011 UNSPEC_TLS_IE_SUN))
14012 (clobber (reg:CC FLAGS_REG))]
14013 "TARGET_64BIT && TARGET_SUN_TLS"
14016 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
14017 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
14019 [(set_attr "type" "multi")])
14021 ;; GNU2 TLS patterns can be split.
14023 (define_expand "tls_dynamic_gnu2_32"
14024 [(set (match_dup 3)
14025 (plus:SI (match_operand:SI 2 "register_operand")
14027 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
14030 [(set (match_operand:SI 0 "register_operand")
14031 (unspec:SI [(match_dup 1) (match_dup 3)
14032 (match_dup 2) (reg:SI SP_REG)]
14034 (clobber (reg:CC FLAGS_REG))])]
14035 "!TARGET_64BIT && TARGET_GNU2_TLS"
14037 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14038 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14041 (define_insn "*tls_dynamic_gnu2_lea_32"
14042 [(set (match_operand:SI 0 "register_operand" "=r")
14043 (plus:SI (match_operand:SI 1 "register_operand" "b")
14045 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
14046 UNSPEC_TLSDESC))))]
14047 "!TARGET_64BIT && TARGET_GNU2_TLS"
14048 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
14049 [(set_attr "type" "lea")
14050 (set_attr "mode" "SI")
14051 (set_attr "length" "6")
14052 (set_attr "length_address" "4")])
14054 (define_insn "*tls_dynamic_gnu2_call_32"
14055 [(set (match_operand:SI 0 "register_operand" "=a")
14056 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
14057 (match_operand:SI 2 "register_operand" "0")
14058 ;; we have to make sure %ebx still points to the GOT
14059 (match_operand:SI 3 "register_operand" "b")
14062 (clobber (reg:CC FLAGS_REG))]
14063 "!TARGET_64BIT && TARGET_GNU2_TLS"
14064 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14065 [(set_attr "type" "call")
14066 (set_attr "length" "2")
14067 (set_attr "length_address" "0")])
14069 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14070 [(set (match_operand:SI 0 "register_operand" "=&a")
14072 (unspec:SI [(match_operand 3 "tls_modbase_operand")
14073 (match_operand:SI 4)
14074 (match_operand:SI 2 "register_operand" "b")
14077 (const:SI (unspec:SI
14078 [(match_operand 1 "tls_symbolic_operand")]
14080 (clobber (reg:CC FLAGS_REG))]
14081 "!TARGET_64BIT && TARGET_GNU2_TLS"
14084 [(set (match_dup 0) (match_dup 5))]
14086 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14087 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14090 (define_expand "tls_dynamic_gnu2_64"
14091 [(set (match_dup 2)
14092 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14095 [(set (match_operand:DI 0 "register_operand")
14096 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14098 (clobber (reg:CC FLAGS_REG))])]
14099 "TARGET_64BIT && TARGET_GNU2_TLS"
14101 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14102 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14105 (define_insn "*tls_dynamic_gnu2_lea_64"
14106 [(set (match_operand:DI 0 "register_operand" "=r")
14107 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14109 "TARGET_64BIT && TARGET_GNU2_TLS"
14110 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
14111 [(set_attr "type" "lea")
14112 (set_attr "mode" "DI")
14113 (set_attr "length" "7")
14114 (set_attr "length_address" "4")])
14116 (define_insn "*tls_dynamic_gnu2_call_64"
14117 [(set (match_operand:DI 0 "register_operand" "=a")
14118 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14119 (match_operand:DI 2 "register_operand" "0")
14122 (clobber (reg:CC FLAGS_REG))]
14123 "TARGET_64BIT && TARGET_GNU2_TLS"
14124 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14125 [(set_attr "type" "call")
14126 (set_attr "length" "2")
14127 (set_attr "length_address" "0")])
14129 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14130 [(set (match_operand:DI 0 "register_operand" "=&a")
14132 (unspec:DI [(match_operand 2 "tls_modbase_operand")
14133 (match_operand:DI 3)
14136 (const:DI (unspec:DI
14137 [(match_operand 1 "tls_symbolic_operand")]
14139 (clobber (reg:CC FLAGS_REG))]
14140 "TARGET_64BIT && TARGET_GNU2_TLS"
14143 [(set (match_dup 0) (match_dup 4))]
14145 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14146 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14150 [(match_operand 0 "tls_address_pattern")]
14151 "TARGET_TLS_DIRECT_SEG_REFS"
14153 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
14156 ;; These patterns match the binary 387 instructions for addM3, subM3,
14157 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14158 ;; SFmode. The first is the normal insn, the second the same insn but
14159 ;; with one operand a conversion, and the third the same insn but with
14160 ;; the other operand a conversion. The conversion may be SFmode or
14161 ;; SImode if the target mode DFmode, but only SImode if the target mode
14164 ;; Gcc is slightly more smart about handling normal two address instructions
14165 ;; so use special patterns for add and mull.
14167 (define_insn "*fop_<mode>_comm"
14168 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
14169 (match_operator:MODEF 3 "binary_fp_operator"
14170 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
14171 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
14172 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14173 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14174 && COMMUTATIVE_ARITH_P (operands[3])
14175 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14176 "* return output_387_binary_op (insn, operands);"
14177 [(set (attr "type")
14178 (if_then_else (eq_attr "alternative" "1,2")
14179 (if_then_else (match_operand:MODEF 3 "mult_operator")
14180 (const_string "ssemul")
14181 (const_string "sseadd"))
14182 (if_then_else (match_operand:MODEF 3 "mult_operator")
14183 (const_string "fmul")
14184 (const_string "fop"))))
14185 (set_attr "isa" "*,noavx,avx")
14186 (set_attr "prefix" "orig,orig,vex")
14187 (set_attr "mode" "<MODE>")
14188 (set (attr "enabled")
14190 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14192 (eq_attr "alternative" "0")
14193 (symbol_ref "TARGET_MIX_SSE_I387
14194 && X87_ENABLE_ARITH (<MODE>mode)")
14195 (const_string "*"))
14197 (eq_attr "alternative" "0")
14198 (symbol_ref "true")
14199 (symbol_ref "false"))))])
14201 (define_insn "*rcpsf2_sse"
14202 [(set (match_operand:SF 0 "register_operand" "=x")
14203 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14205 "TARGET_SSE && TARGET_SSE_MATH"
14206 "%vrcpss\t{%1, %d0|%d0, %1}"
14207 [(set_attr "type" "sse")
14208 (set_attr "atom_sse_attr" "rcp")
14209 (set_attr "btver2_sse_attr" "rcp")
14210 (set_attr "prefix" "maybe_vex")
14211 (set_attr "mode" "SF")])
14213 (define_insn "*fop_<mode>_1"
14214 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
14215 (match_operator:MODEF 3 "binary_fp_operator"
14216 [(match_operand:MODEF 1
14217 "x87nonimm_ssenomem_operand" "0,fm,0,v")
14218 (match_operand:MODEF 2
14219 "nonimmediate_operand" "fm,0,xm,vm")]))]
14220 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14221 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14222 && !COMMUTATIVE_ARITH_P (operands[3])
14223 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14224 "* return output_387_binary_op (insn, operands);"
14225 [(set (attr "type")
14226 (if_then_else (eq_attr "alternative" "2,3")
14227 (if_then_else (match_operand:MODEF 3 "div_operator")
14228 (const_string "ssediv")
14229 (const_string "sseadd"))
14230 (if_then_else (match_operand:MODEF 3 "div_operator")
14231 (const_string "fdiv")
14232 (const_string "fop"))))
14233 (set_attr "isa" "*,*,noavx,avx")
14234 (set_attr "prefix" "orig,orig,orig,vex")
14235 (set_attr "mode" "<MODE>")
14236 (set (attr "enabled")
14238 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14240 (eq_attr "alternative" "0,1")
14241 (symbol_ref "TARGET_MIX_SSE_I387
14242 && X87_ENABLE_ARITH (<MODE>mode)")
14243 (const_string "*"))
14245 (eq_attr "alternative" "0,1")
14246 (symbol_ref "true")
14247 (symbol_ref "false"))))])
14249 ;; ??? Add SSE splitters for these!
14250 (define_insn "*fop_<MODEF:mode>_2_i387"
14251 [(set (match_operand:MODEF 0 "register_operand" "=f")
14252 (match_operator:MODEF 3 "binary_fp_operator"
14254 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14255 (match_operand:MODEF 2 "register_operand" "0")]))]
14256 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14257 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14258 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14259 || optimize_function_for_size_p (cfun))"
14260 "* return output_387_binary_op (insn, operands);"
14261 [(set (attr "type")
14262 (cond [(match_operand:MODEF 3 "mult_operator")
14263 (const_string "fmul")
14264 (match_operand:MODEF 3 "div_operator")
14265 (const_string "fdiv")
14267 (const_string "fop")))
14268 (set_attr "fp_int_src" "true")
14269 (set_attr "mode" "<SWI24:MODE>")])
14271 (define_insn "*fop_<MODEF:mode>_3_i387"
14272 [(set (match_operand:MODEF 0 "register_operand" "=f")
14273 (match_operator:MODEF 3 "binary_fp_operator"
14274 [(match_operand:MODEF 1 "register_operand" "0")
14276 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14277 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14278 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14279 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14280 || optimize_function_for_size_p (cfun))"
14281 "* return output_387_binary_op (insn, operands);"
14282 [(set (attr "type")
14283 (cond [(match_operand:MODEF 3 "mult_operator")
14284 (const_string "fmul")
14285 (match_operand:MODEF 3 "div_operator")
14286 (const_string "fdiv")
14288 (const_string "fop")))
14289 (set_attr "fp_int_src" "true")
14290 (set_attr "mode" "<MODE>")])
14292 (define_insn "*fop_df_4_i387"
14293 [(set (match_operand:DF 0 "register_operand" "=f,f")
14294 (match_operator:DF 3 "binary_fp_operator"
14296 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14297 (match_operand:DF 2 "register_operand" "0,f")]))]
14298 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14299 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14300 "* return output_387_binary_op (insn, operands);"
14301 [(set (attr "type")
14302 (cond [(match_operand:DF 3 "mult_operator")
14303 (const_string "fmul")
14304 (match_operand:DF 3 "div_operator")
14305 (const_string "fdiv")
14307 (const_string "fop")))
14308 (set_attr "mode" "SF")])
14310 (define_insn "*fop_df_5_i387"
14311 [(set (match_operand:DF 0 "register_operand" "=f,f")
14312 (match_operator:DF 3 "binary_fp_operator"
14313 [(match_operand:DF 1 "register_operand" "0,f")
14315 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14316 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14317 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14318 "* return output_387_binary_op (insn, operands);"
14319 [(set (attr "type")
14320 (cond [(match_operand:DF 3 "mult_operator")
14321 (const_string "fmul")
14322 (match_operand:DF 3 "div_operator")
14323 (const_string "fdiv")
14325 (const_string "fop")))
14326 (set_attr "mode" "SF")])
14328 (define_insn "*fop_df_6_i387"
14329 [(set (match_operand:DF 0 "register_operand" "=f,f")
14330 (match_operator:DF 3 "binary_fp_operator"
14332 (match_operand:SF 1 "register_operand" "0,f"))
14334 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14335 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14336 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14337 "* return output_387_binary_op (insn, operands);"
14338 [(set (attr "type")
14339 (cond [(match_operand:DF 3 "mult_operator")
14340 (const_string "fmul")
14341 (match_operand:DF 3 "div_operator")
14342 (const_string "fdiv")
14344 (const_string "fop")))
14345 (set_attr "mode" "SF")])
14347 (define_insn "*fop_xf_comm_i387"
14348 [(set (match_operand:XF 0 "register_operand" "=f")
14349 (match_operator:XF 3 "binary_fp_operator"
14350 [(match_operand:XF 1 "register_operand" "%0")
14351 (match_operand:XF 2 "register_operand" "f")]))]
14353 && COMMUTATIVE_ARITH_P (operands[3])"
14354 "* return output_387_binary_op (insn, operands);"
14355 [(set (attr "type")
14356 (if_then_else (match_operand:XF 3 "mult_operator")
14357 (const_string "fmul")
14358 (const_string "fop")))
14359 (set_attr "mode" "XF")])
14361 (define_insn "*fop_xf_1_i387"
14362 [(set (match_operand:XF 0 "register_operand" "=f,f")
14363 (match_operator:XF 3 "binary_fp_operator"
14364 [(match_operand:XF 1 "register_operand" "0,f")
14365 (match_operand:XF 2 "register_operand" "f,0")]))]
14367 && !COMMUTATIVE_ARITH_P (operands[3])"
14368 "* return output_387_binary_op (insn, operands);"
14369 [(set (attr "type")
14370 (if_then_else (match_operand:XF 3 "div_operator")
14371 (const_string "fdiv")
14372 (const_string "fop")))
14373 (set_attr "mode" "XF")])
14375 (define_insn "*fop_xf_2_i387"
14376 [(set (match_operand:XF 0 "register_operand" "=f")
14377 (match_operator:XF 3 "binary_fp_operator"
14379 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14380 (match_operand:XF 2 "register_operand" "0")]))]
14382 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14383 "* return output_387_binary_op (insn, operands);"
14384 [(set (attr "type")
14385 (cond [(match_operand:XF 3 "mult_operator")
14386 (const_string "fmul")
14387 (match_operand:XF 3 "div_operator")
14388 (const_string "fdiv")
14390 (const_string "fop")))
14391 (set_attr "fp_int_src" "true")
14392 (set_attr "mode" "<MODE>")])
14394 (define_insn "*fop_xf_3_i387"
14395 [(set (match_operand:XF 0 "register_operand" "=f")
14396 (match_operator:XF 3 "binary_fp_operator"
14397 [(match_operand:XF 1 "register_operand" "0")
14399 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14401 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14402 "* return output_387_binary_op (insn, operands);"
14403 [(set (attr "type")
14404 (cond [(match_operand:XF 3 "mult_operator")
14405 (const_string "fmul")
14406 (match_operand:XF 3 "div_operator")
14407 (const_string "fdiv")
14409 (const_string "fop")))
14410 (set_attr "fp_int_src" "true")
14411 (set_attr "mode" "<MODE>")])
14413 (define_insn "*fop_xf_4_i387"
14414 [(set (match_operand:XF 0 "register_operand" "=f,f")
14415 (match_operator:XF 3 "binary_fp_operator"
14417 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
14418 (match_operand:XF 2 "register_operand" "0,f")]))]
14420 "* return output_387_binary_op (insn, operands);"
14421 [(set (attr "type")
14422 (cond [(match_operand:XF 3 "mult_operator")
14423 (const_string "fmul")
14424 (match_operand:XF 3 "div_operator")
14425 (const_string "fdiv")
14427 (const_string "fop")))
14428 (set_attr "mode" "<MODE>")])
14430 (define_insn "*fop_xf_5_i387"
14431 [(set (match_operand:XF 0 "register_operand" "=f,f")
14432 (match_operator:XF 3 "binary_fp_operator"
14433 [(match_operand:XF 1 "register_operand" "0,f")
14435 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14437 "* return output_387_binary_op (insn, operands);"
14438 [(set (attr "type")
14439 (cond [(match_operand:XF 3 "mult_operator")
14440 (const_string "fmul")
14441 (match_operand:XF 3 "div_operator")
14442 (const_string "fdiv")
14444 (const_string "fop")))
14445 (set_attr "mode" "<MODE>")])
14447 (define_insn "*fop_xf_6_i387"
14448 [(set (match_operand:XF 0 "register_operand" "=f,f")
14449 (match_operator:XF 3 "binary_fp_operator"
14451 (match_operand:MODEF 1 "register_operand" "0,f"))
14453 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14455 "* return output_387_binary_op (insn, operands);"
14456 [(set (attr "type")
14457 (cond [(match_operand:XF 3 "mult_operator")
14458 (const_string "fmul")
14459 (match_operand:XF 3 "div_operator")
14460 (const_string "fdiv")
14462 (const_string "fop")))
14463 (set_attr "mode" "<MODE>")])
14465 ;; FPU special functions.
14467 ;; This pattern implements a no-op XFmode truncation for
14468 ;; all fancy i386 XFmode math functions.
14470 (define_insn "truncxf<mode>2_i387_noop_unspec"
14471 [(set (match_operand:MODEF 0 "register_operand" "=f")
14472 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
14473 UNSPEC_TRUNC_NOOP))]
14474 "TARGET_USE_FANCY_MATH_387"
14475 "* return output_387_reg_move (insn, operands);"
14476 [(set_attr "type" "fmov")
14477 (set_attr "mode" "<MODE>")])
14479 (define_insn "sqrtxf2"
14480 [(set (match_operand:XF 0 "register_operand" "=f")
14481 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14482 "TARGET_USE_FANCY_MATH_387"
14484 [(set_attr "type" "fpspc")
14485 (set_attr "mode" "XF")
14486 (set_attr "athlon_decode" "direct")
14487 (set_attr "amdfam10_decode" "direct")
14488 (set_attr "bdver1_decode" "direct")])
14490 (define_insn "sqrt_extend<mode>xf2_i387"
14491 [(set (match_operand:XF 0 "register_operand" "=f")
14494 (match_operand:MODEF 1 "register_operand" "0"))))]
14495 "TARGET_USE_FANCY_MATH_387"
14497 [(set_attr "type" "fpspc")
14498 (set_attr "mode" "XF")
14499 (set_attr "athlon_decode" "direct")
14500 (set_attr "amdfam10_decode" "direct")
14501 (set_attr "bdver1_decode" "direct")])
14503 (define_insn "*rsqrtsf2_sse"
14504 [(set (match_operand:SF 0 "register_operand" "=x")
14505 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14507 "TARGET_SSE && TARGET_SSE_MATH"
14508 "%vrsqrtss\t{%1, %d0|%d0, %1}"
14509 [(set_attr "type" "sse")
14510 (set_attr "atom_sse_attr" "rcp")
14511 (set_attr "btver2_sse_attr" "rcp")
14512 (set_attr "prefix" "maybe_vex")
14513 (set_attr "mode" "SF")])
14515 (define_expand "rsqrtsf2"
14516 [(set (match_operand:SF 0 "register_operand")
14517 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
14519 "TARGET_SSE && TARGET_SSE_MATH"
14521 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
14525 (define_insn "*sqrt<mode>2_sse"
14526 [(set (match_operand:MODEF 0 "register_operand" "=v")
14528 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
14529 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14530 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
14531 [(set_attr "type" "sse")
14532 (set_attr "atom_sse_attr" "sqrt")
14533 (set_attr "btver2_sse_attr" "sqrt")
14534 (set_attr "prefix" "maybe_vex")
14535 (set_attr "mode" "<MODE>")
14536 (set_attr "athlon_decode" "*")
14537 (set_attr "amdfam10_decode" "*")
14538 (set_attr "bdver1_decode" "*")])
14540 (define_expand "sqrt<mode>2"
14541 [(set (match_operand:MODEF 0 "register_operand")
14543 (match_operand:MODEF 1 "nonimmediate_operand")))]
14544 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
14545 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14547 if (<MODE>mode == SFmode
14548 && TARGET_SSE && TARGET_SSE_MATH
14549 && TARGET_RECIP_SQRT
14550 && !optimize_function_for_size_p (cfun)
14551 && flag_finite_math_only && !flag_trapping_math
14552 && flag_unsafe_math_optimizations)
14554 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
14558 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
14560 rtx op0 = gen_reg_rtx (XFmode);
14561 rtx op1 = force_reg (<MODE>mode, operands[1]);
14563 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
14564 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
14569 (define_insn "fpremxf4_i387"
14570 [(set (match_operand:XF 0 "register_operand" "=f")
14571 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14572 (match_operand:XF 3 "register_operand" "1")]
14574 (set (match_operand:XF 1 "register_operand" "=u")
14575 (unspec:XF [(match_dup 2) (match_dup 3)]
14577 (set (reg:CCFP FPSR_REG)
14578 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14580 "TARGET_USE_FANCY_MATH_387
14581 && flag_finite_math_only"
14583 [(set_attr "type" "fpspc")
14584 (set_attr "znver1_decode" "vector")
14585 (set_attr "mode" "XF")])
14587 (define_expand "fmodxf3"
14588 [(use (match_operand:XF 0 "register_operand"))
14589 (use (match_operand:XF 1 "general_operand"))
14590 (use (match_operand:XF 2 "general_operand"))]
14591 "TARGET_USE_FANCY_MATH_387
14592 && flag_finite_math_only"
14594 rtx_code_label *label = gen_label_rtx ();
14596 rtx op1 = gen_reg_rtx (XFmode);
14597 rtx op2 = gen_reg_rtx (XFmode);
14599 emit_move_insn (op2, operands[2]);
14600 emit_move_insn (op1, operands[1]);
14602 emit_label (label);
14603 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14604 ix86_emit_fp_unordered_jump (label);
14605 LABEL_NUSES (label) = 1;
14607 emit_move_insn (operands[0], op1);
14611 (define_expand "fmod<mode>3"
14612 [(use (match_operand:MODEF 0 "register_operand"))
14613 (use (match_operand:MODEF 1 "general_operand"))
14614 (use (match_operand:MODEF 2 "general_operand"))]
14615 "TARGET_USE_FANCY_MATH_387
14616 && flag_finite_math_only"
14618 rtx (*gen_truncxf) (rtx, rtx);
14620 rtx_code_label *label = gen_label_rtx ();
14622 rtx op1 = gen_reg_rtx (XFmode);
14623 rtx op2 = gen_reg_rtx (XFmode);
14625 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14626 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14628 emit_label (label);
14629 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14630 ix86_emit_fp_unordered_jump (label);
14631 LABEL_NUSES (label) = 1;
14633 /* Truncate the result properly for strict SSE math. */
14634 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14635 && !TARGET_MIX_SSE_I387)
14636 gen_truncxf = gen_truncxf<mode>2;
14638 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14640 emit_insn (gen_truncxf (operands[0], op1));
14644 (define_insn "fprem1xf4_i387"
14645 [(set (match_operand:XF 0 "register_operand" "=f")
14646 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14647 (match_operand:XF 3 "register_operand" "1")]
14649 (set (match_operand:XF 1 "register_operand" "=u")
14650 (unspec:XF [(match_dup 2) (match_dup 3)]
14652 (set (reg:CCFP FPSR_REG)
14653 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14655 "TARGET_USE_FANCY_MATH_387
14656 && flag_finite_math_only"
14658 [(set_attr "type" "fpspc")
14659 (set_attr "znver1_decode" "vector")
14660 (set_attr "mode" "XF")])
14662 (define_expand "remainderxf3"
14663 [(use (match_operand:XF 0 "register_operand"))
14664 (use (match_operand:XF 1 "general_operand"))
14665 (use (match_operand:XF 2 "general_operand"))]
14666 "TARGET_USE_FANCY_MATH_387
14667 && flag_finite_math_only"
14669 rtx_code_label *label = gen_label_rtx ();
14671 rtx op1 = gen_reg_rtx (XFmode);
14672 rtx op2 = gen_reg_rtx (XFmode);
14674 emit_move_insn (op2, operands[2]);
14675 emit_move_insn (op1, operands[1]);
14677 emit_label (label);
14678 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14679 ix86_emit_fp_unordered_jump (label);
14680 LABEL_NUSES (label) = 1;
14682 emit_move_insn (operands[0], op1);
14686 (define_expand "remainder<mode>3"
14687 [(use (match_operand:MODEF 0 "register_operand"))
14688 (use (match_operand:MODEF 1 "general_operand"))
14689 (use (match_operand:MODEF 2 "general_operand"))]
14690 "TARGET_USE_FANCY_MATH_387
14691 && flag_finite_math_only"
14693 rtx (*gen_truncxf) (rtx, rtx);
14695 rtx_code_label *label = gen_label_rtx ();
14697 rtx op1 = gen_reg_rtx (XFmode);
14698 rtx op2 = gen_reg_rtx (XFmode);
14700 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14701 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14703 emit_label (label);
14705 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14706 ix86_emit_fp_unordered_jump (label);
14707 LABEL_NUSES (label) = 1;
14709 /* Truncate the result properly for strict SSE math. */
14710 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14711 && !TARGET_MIX_SSE_I387)
14712 gen_truncxf = gen_truncxf<mode>2;
14714 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14716 emit_insn (gen_truncxf (operands[0], op1));
14720 (define_int_iterator SINCOS
14724 (define_int_attr sincos
14725 [(UNSPEC_SIN "sin")
14726 (UNSPEC_COS "cos")])
14728 (define_insn "*<sincos>xf2_i387"
14729 [(set (match_operand:XF 0 "register_operand" "=f")
14730 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14732 "TARGET_USE_FANCY_MATH_387
14733 && flag_unsafe_math_optimizations"
14735 [(set_attr "type" "fpspc")
14736 (set_attr "znver1_decode" "vector")
14737 (set_attr "mode" "XF")])
14739 (define_insn "*<sincos>_extend<mode>xf2_i387"
14740 [(set (match_operand:XF 0 "register_operand" "=f")
14741 (unspec:XF [(float_extend:XF
14742 (match_operand:MODEF 1 "register_operand" "0"))]
14744 "TARGET_USE_FANCY_MATH_387
14745 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14746 || TARGET_MIX_SSE_I387)
14747 && flag_unsafe_math_optimizations"
14749 [(set_attr "type" "fpspc")
14750 (set_attr "znver1_decode" "vector")
14751 (set_attr "mode" "XF")])
14753 ;; When sincos pattern is defined, sin and cos builtin functions will be
14754 ;; expanded to sincos pattern with one of its outputs left unused.
14755 ;; CSE pass will figure out if two sincos patterns can be combined,
14756 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14757 ;; depending on the unused output.
14759 (define_insn "sincosxf3"
14760 [(set (match_operand:XF 0 "register_operand" "=f")
14761 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14762 UNSPEC_SINCOS_COS))
14763 (set (match_operand:XF 1 "register_operand" "=u")
14764 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14765 "TARGET_USE_FANCY_MATH_387
14766 && flag_unsafe_math_optimizations"
14768 [(set_attr "type" "fpspc")
14769 (set_attr "znver1_decode" "vector")
14770 (set_attr "mode" "XF")])
14773 [(set (match_operand:XF 0 "register_operand")
14774 (unspec:XF [(match_operand:XF 2 "register_operand")]
14775 UNSPEC_SINCOS_COS))
14776 (set (match_operand:XF 1 "register_operand")
14777 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14778 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14779 && can_create_pseudo_p ()"
14780 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14783 [(set (match_operand:XF 0 "register_operand")
14784 (unspec:XF [(match_operand:XF 2 "register_operand")]
14785 UNSPEC_SINCOS_COS))
14786 (set (match_operand:XF 1 "register_operand")
14787 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14788 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14789 && can_create_pseudo_p ()"
14790 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14792 (define_insn "sincos_extend<mode>xf3_i387"
14793 [(set (match_operand:XF 0 "register_operand" "=f")
14794 (unspec:XF [(float_extend:XF
14795 (match_operand:MODEF 2 "register_operand" "0"))]
14796 UNSPEC_SINCOS_COS))
14797 (set (match_operand:XF 1 "register_operand" "=u")
14798 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14799 "TARGET_USE_FANCY_MATH_387
14800 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14801 || TARGET_MIX_SSE_I387)
14802 && flag_unsafe_math_optimizations"
14804 [(set_attr "type" "fpspc")
14805 (set_attr "znver1_decode" "vector")
14806 (set_attr "mode" "XF")])
14809 [(set (match_operand:XF 0 "register_operand")
14810 (unspec:XF [(float_extend:XF
14811 (match_operand:MODEF 2 "register_operand"))]
14812 UNSPEC_SINCOS_COS))
14813 (set (match_operand:XF 1 "register_operand")
14814 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14815 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14816 && can_create_pseudo_p ()"
14817 [(set (match_dup 1)
14818 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14821 [(set (match_operand:XF 0 "register_operand")
14822 (unspec:XF [(float_extend:XF
14823 (match_operand:MODEF 2 "register_operand"))]
14824 UNSPEC_SINCOS_COS))
14825 (set (match_operand:XF 1 "register_operand")
14826 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14827 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14828 && can_create_pseudo_p ()"
14829 [(set (match_dup 0)
14830 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14832 (define_expand "sincos<mode>3"
14833 [(use (match_operand:MODEF 0 "register_operand"))
14834 (use (match_operand:MODEF 1 "register_operand"))
14835 (use (match_operand:MODEF 2 "register_operand"))]
14836 "TARGET_USE_FANCY_MATH_387
14837 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14838 || TARGET_MIX_SSE_I387)
14839 && flag_unsafe_math_optimizations"
14841 rtx op0 = gen_reg_rtx (XFmode);
14842 rtx op1 = gen_reg_rtx (XFmode);
14844 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14845 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14846 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14850 (define_insn "fptanxf4_i387"
14851 [(set (match_operand:XF 0 "register_operand" "=f")
14852 (match_operand:XF 3 "const_double_operand" "F"))
14853 (set (match_operand:XF 1 "register_operand" "=u")
14854 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14856 "TARGET_USE_FANCY_MATH_387
14857 && flag_unsafe_math_optimizations
14858 && standard_80387_constant_p (operands[3]) == 2"
14860 [(set_attr "type" "fpspc")
14861 (set_attr "znver1_decode" "vector")
14862 (set_attr "mode" "XF")])
14864 (define_insn "fptan_extend<mode>xf4_i387"
14865 [(set (match_operand:MODEF 0 "register_operand" "=f")
14866 (match_operand:MODEF 3 "const_double_operand" "F"))
14867 (set (match_operand:XF 1 "register_operand" "=u")
14868 (unspec:XF [(float_extend:XF
14869 (match_operand:MODEF 2 "register_operand" "0"))]
14871 "TARGET_USE_FANCY_MATH_387
14872 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14873 || TARGET_MIX_SSE_I387)
14874 && flag_unsafe_math_optimizations
14875 && standard_80387_constant_p (operands[3]) == 2"
14877 [(set_attr "type" "fpspc")
14878 (set_attr "znver1_decode" "vector")
14879 (set_attr "mode" "XF")])
14881 (define_expand "tanxf2"
14882 [(use (match_operand:XF 0 "register_operand"))
14883 (use (match_operand:XF 1 "register_operand"))]
14884 "TARGET_USE_FANCY_MATH_387
14885 && flag_unsafe_math_optimizations"
14887 rtx one = gen_reg_rtx (XFmode);
14888 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14890 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14894 (define_expand "tan<mode>2"
14895 [(use (match_operand:MODEF 0 "register_operand"))
14896 (use (match_operand:MODEF 1 "register_operand"))]
14897 "TARGET_USE_FANCY_MATH_387
14898 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14899 || TARGET_MIX_SSE_I387)
14900 && flag_unsafe_math_optimizations"
14902 rtx op0 = gen_reg_rtx (XFmode);
14904 rtx one = gen_reg_rtx (<MODE>mode);
14905 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14907 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14908 operands[1], op2));
14909 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14913 (define_insn "*fpatanxf3_i387"
14914 [(set (match_operand:XF 0 "register_operand" "=f")
14915 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14916 (match_operand:XF 2 "register_operand" "u")]
14918 (clobber (match_scratch:XF 3 "=2"))]
14919 "TARGET_USE_FANCY_MATH_387
14920 && flag_unsafe_math_optimizations"
14922 [(set_attr "type" "fpspc")
14923 (set_attr "znver1_decode" "vector")
14924 (set_attr "mode" "XF")])
14926 (define_insn "fpatan_extend<mode>xf3_i387"
14927 [(set (match_operand:XF 0 "register_operand" "=f")
14928 (unspec:XF [(float_extend:XF
14929 (match_operand:MODEF 1 "register_operand" "0"))
14931 (match_operand:MODEF 2 "register_operand" "u"))]
14933 (clobber (match_scratch:XF 3 "=2"))]
14934 "TARGET_USE_FANCY_MATH_387
14935 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14936 || TARGET_MIX_SSE_I387)
14937 && flag_unsafe_math_optimizations"
14939 [(set_attr "type" "fpspc")
14940 (set_attr "znver1_decode" "vector")
14941 (set_attr "mode" "XF")])
14943 (define_expand "atan2xf3"
14944 [(parallel [(set (match_operand:XF 0 "register_operand")
14945 (unspec:XF [(match_operand:XF 2 "register_operand")
14946 (match_operand:XF 1 "register_operand")]
14948 (clobber (match_scratch:XF 3))])]
14949 "TARGET_USE_FANCY_MATH_387
14950 && flag_unsafe_math_optimizations")
14952 (define_expand "atan2<mode>3"
14953 [(use (match_operand:MODEF 0 "register_operand"))
14954 (use (match_operand:MODEF 1 "register_operand"))
14955 (use (match_operand:MODEF 2 "register_operand"))]
14956 "TARGET_USE_FANCY_MATH_387
14957 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14958 || TARGET_MIX_SSE_I387)
14959 && flag_unsafe_math_optimizations"
14961 rtx op0 = gen_reg_rtx (XFmode);
14963 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14964 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14968 (define_expand "atanxf2"
14969 [(parallel [(set (match_operand:XF 0 "register_operand")
14970 (unspec:XF [(match_dup 2)
14971 (match_operand:XF 1 "register_operand")]
14973 (clobber (match_scratch:XF 3))])]
14974 "TARGET_USE_FANCY_MATH_387
14975 && flag_unsafe_math_optimizations"
14977 operands[2] = gen_reg_rtx (XFmode);
14978 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14981 (define_expand "atan<mode>2"
14982 [(use (match_operand:MODEF 0 "register_operand"))
14983 (use (match_operand:MODEF 1 "register_operand"))]
14984 "TARGET_USE_FANCY_MATH_387
14985 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14986 || TARGET_MIX_SSE_I387)
14987 && flag_unsafe_math_optimizations"
14989 rtx op0 = gen_reg_rtx (XFmode);
14991 rtx op2 = gen_reg_rtx (<MODE>mode);
14992 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14994 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14995 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14999 (define_expand "asinxf2"
15000 [(set (match_dup 2)
15001 (mult:XF (match_operand:XF 1 "register_operand")
15003 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15004 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15005 (parallel [(set (match_operand:XF 0 "register_operand")
15006 (unspec:XF [(match_dup 5) (match_dup 1)]
15008 (clobber (match_scratch:XF 6))])]
15009 "TARGET_USE_FANCY_MATH_387
15010 && flag_unsafe_math_optimizations"
15014 for (i = 2; i < 6; i++)
15015 operands[i] = gen_reg_rtx (XFmode);
15017 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15020 (define_expand "asin<mode>2"
15021 [(use (match_operand:MODEF 0 "register_operand"))
15022 (use (match_operand:MODEF 1 "general_operand"))]
15023 "TARGET_USE_FANCY_MATH_387
15024 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15025 || TARGET_MIX_SSE_I387)
15026 && flag_unsafe_math_optimizations"
15028 rtx op0 = gen_reg_rtx (XFmode);
15029 rtx op1 = gen_reg_rtx (XFmode);
15031 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15032 emit_insn (gen_asinxf2 (op0, op1));
15033 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15037 (define_expand "acosxf2"
15038 [(set (match_dup 2)
15039 (mult:XF (match_operand:XF 1 "register_operand")
15041 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15042 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15043 (parallel [(set (match_operand:XF 0 "register_operand")
15044 (unspec:XF [(match_dup 1) (match_dup 5)]
15046 (clobber (match_scratch:XF 6))])]
15047 "TARGET_USE_FANCY_MATH_387
15048 && flag_unsafe_math_optimizations"
15052 for (i = 2; i < 6; i++)
15053 operands[i] = gen_reg_rtx (XFmode);
15055 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15058 (define_expand "acos<mode>2"
15059 [(use (match_operand:MODEF 0 "register_operand"))
15060 (use (match_operand:MODEF 1 "general_operand"))]
15061 "TARGET_USE_FANCY_MATH_387
15062 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15063 || TARGET_MIX_SSE_I387)
15064 && flag_unsafe_math_optimizations"
15066 rtx op0 = gen_reg_rtx (XFmode);
15067 rtx op1 = gen_reg_rtx (XFmode);
15069 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15070 emit_insn (gen_acosxf2 (op0, op1));
15071 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15075 (define_insn "fyl2xxf3_i387"
15076 [(set (match_operand:XF 0 "register_operand" "=f")
15077 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15078 (match_operand:XF 2 "register_operand" "u")]
15080 (clobber (match_scratch:XF 3 "=2"))]
15081 "TARGET_USE_FANCY_MATH_387
15082 && flag_unsafe_math_optimizations"
15084 [(set_attr "type" "fpspc")
15085 (set_attr "znver1_decode" "vector")
15086 (set_attr "mode" "XF")])
15088 (define_insn "fyl2x_extend<mode>xf3_i387"
15089 [(set (match_operand:XF 0 "register_operand" "=f")
15090 (unspec:XF [(float_extend:XF
15091 (match_operand:MODEF 1 "register_operand" "0"))
15092 (match_operand:XF 2 "register_operand" "u")]
15094 (clobber (match_scratch:XF 3 "=2"))]
15095 "TARGET_USE_FANCY_MATH_387
15096 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15097 || TARGET_MIX_SSE_I387)
15098 && flag_unsafe_math_optimizations"
15100 [(set_attr "type" "fpspc")
15101 (set_attr "znver1_decode" "vector")
15102 (set_attr "mode" "XF")])
15104 (define_expand "logxf2"
15105 [(parallel [(set (match_operand:XF 0 "register_operand")
15106 (unspec:XF [(match_operand:XF 1 "register_operand")
15107 (match_dup 2)] UNSPEC_FYL2X))
15108 (clobber (match_scratch:XF 3))])]
15109 "TARGET_USE_FANCY_MATH_387
15110 && flag_unsafe_math_optimizations"
15112 operands[2] = gen_reg_rtx (XFmode);
15113 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
15116 (define_expand "log<mode>2"
15117 [(use (match_operand:MODEF 0 "register_operand"))
15118 (use (match_operand:MODEF 1 "register_operand"))]
15119 "TARGET_USE_FANCY_MATH_387
15120 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15121 || TARGET_MIX_SSE_I387)
15122 && flag_unsafe_math_optimizations"
15124 rtx op0 = gen_reg_rtx (XFmode);
15126 rtx op2 = gen_reg_rtx (XFmode);
15127 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
15129 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15130 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15134 (define_expand "log10xf2"
15135 [(parallel [(set (match_operand:XF 0 "register_operand")
15136 (unspec:XF [(match_operand:XF 1 "register_operand")
15137 (match_dup 2)] UNSPEC_FYL2X))
15138 (clobber (match_scratch:XF 3))])]
15139 "TARGET_USE_FANCY_MATH_387
15140 && flag_unsafe_math_optimizations"
15142 operands[2] = gen_reg_rtx (XFmode);
15143 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
15146 (define_expand "log10<mode>2"
15147 [(use (match_operand:MODEF 0 "register_operand"))
15148 (use (match_operand:MODEF 1 "register_operand"))]
15149 "TARGET_USE_FANCY_MATH_387
15150 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15151 || TARGET_MIX_SSE_I387)
15152 && flag_unsafe_math_optimizations"
15154 rtx op0 = gen_reg_rtx (XFmode);
15156 rtx op2 = gen_reg_rtx (XFmode);
15157 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
15159 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15160 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15164 (define_expand "log2xf2"
15165 [(parallel [(set (match_operand:XF 0 "register_operand")
15166 (unspec:XF [(match_operand:XF 1 "register_operand")
15167 (match_dup 2)] UNSPEC_FYL2X))
15168 (clobber (match_scratch:XF 3))])]
15169 "TARGET_USE_FANCY_MATH_387
15170 && flag_unsafe_math_optimizations"
15172 operands[2] = gen_reg_rtx (XFmode);
15173 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15176 (define_expand "log2<mode>2"
15177 [(use (match_operand:MODEF 0 "register_operand"))
15178 (use (match_operand:MODEF 1 "register_operand"))]
15179 "TARGET_USE_FANCY_MATH_387
15180 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15181 || TARGET_MIX_SSE_I387)
15182 && flag_unsafe_math_optimizations"
15184 rtx op0 = gen_reg_rtx (XFmode);
15186 rtx op2 = gen_reg_rtx (XFmode);
15187 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15189 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15190 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15194 (define_insn "fyl2xp1xf3_i387"
15195 [(set (match_operand:XF 0 "register_operand" "=f")
15196 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15197 (match_operand:XF 2 "register_operand" "u")]
15199 (clobber (match_scratch:XF 3 "=2"))]
15200 "TARGET_USE_FANCY_MATH_387
15201 && flag_unsafe_math_optimizations"
15203 [(set_attr "type" "fpspc")
15204 (set_attr "znver1_decode" "vector")
15205 (set_attr "mode" "XF")])
15207 (define_insn "fyl2xp1_extend<mode>xf3_i387"
15208 [(set (match_operand:XF 0 "register_operand" "=f")
15209 (unspec:XF [(float_extend:XF
15210 (match_operand:MODEF 1 "register_operand" "0"))
15211 (match_operand:XF 2 "register_operand" "u")]
15213 (clobber (match_scratch:XF 3 "=2"))]
15214 "TARGET_USE_FANCY_MATH_387
15215 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15216 || TARGET_MIX_SSE_I387)
15217 && flag_unsafe_math_optimizations"
15219 [(set_attr "type" "fpspc")
15220 (set_attr "znver1_decode" "vector")
15221 (set_attr "mode" "XF")])
15223 (define_expand "log1pxf2"
15224 [(use (match_operand:XF 0 "register_operand"))
15225 (use (match_operand:XF 1 "register_operand"))]
15226 "TARGET_USE_FANCY_MATH_387
15227 && flag_unsafe_math_optimizations"
15229 ix86_emit_i387_log1p (operands[0], operands[1]);
15233 (define_expand "log1p<mode>2"
15234 [(use (match_operand:MODEF 0 "register_operand"))
15235 (use (match_operand:MODEF 1 "register_operand"))]
15236 "TARGET_USE_FANCY_MATH_387
15237 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15238 || TARGET_MIX_SSE_I387)
15239 && flag_unsafe_math_optimizations"
15243 op0 = gen_reg_rtx (XFmode);
15245 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
15247 ix86_emit_i387_log1p (op0, operands[1]);
15248 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15252 (define_insn "fxtractxf3_i387"
15253 [(set (match_operand:XF 0 "register_operand" "=f")
15254 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15255 UNSPEC_XTRACT_FRACT))
15256 (set (match_operand:XF 1 "register_operand" "=u")
15257 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15258 "TARGET_USE_FANCY_MATH_387
15259 && flag_unsafe_math_optimizations"
15261 [(set_attr "type" "fpspc")
15262 (set_attr "znver1_decode" "vector")
15263 (set_attr "mode" "XF")])
15265 (define_insn "fxtract_extend<mode>xf3_i387"
15266 [(set (match_operand:XF 0 "register_operand" "=f")
15267 (unspec:XF [(float_extend:XF
15268 (match_operand:MODEF 2 "register_operand" "0"))]
15269 UNSPEC_XTRACT_FRACT))
15270 (set (match_operand:XF 1 "register_operand" "=u")
15271 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
15272 "TARGET_USE_FANCY_MATH_387
15273 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15274 || TARGET_MIX_SSE_I387)
15275 && flag_unsafe_math_optimizations"
15277 [(set_attr "type" "fpspc")
15278 (set_attr "znver1_decode" "vector")
15279 (set_attr "mode" "XF")])
15281 (define_expand "logbxf2"
15282 [(parallel [(set (match_dup 2)
15283 (unspec:XF [(match_operand:XF 1 "register_operand")]
15284 UNSPEC_XTRACT_FRACT))
15285 (set (match_operand:XF 0 "register_operand")
15286 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15287 "TARGET_USE_FANCY_MATH_387
15288 && flag_unsafe_math_optimizations"
15289 "operands[2] = gen_reg_rtx (XFmode);")
15291 (define_expand "logb<mode>2"
15292 [(use (match_operand:MODEF 0 "register_operand"))
15293 (use (match_operand:MODEF 1 "register_operand"))]
15294 "TARGET_USE_FANCY_MATH_387
15295 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15296 || TARGET_MIX_SSE_I387)
15297 && flag_unsafe_math_optimizations"
15299 rtx op0 = gen_reg_rtx (XFmode);
15300 rtx op1 = gen_reg_rtx (XFmode);
15302 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15303 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
15307 (define_expand "ilogbxf2"
15308 [(use (match_operand:SI 0 "register_operand"))
15309 (use (match_operand:XF 1 "register_operand"))]
15310 "TARGET_USE_FANCY_MATH_387
15311 && flag_unsafe_math_optimizations"
15315 if (optimize_insn_for_size_p ())
15318 op0 = gen_reg_rtx (XFmode);
15319 op1 = gen_reg_rtx (XFmode);
15321 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
15322 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15326 (define_expand "ilogb<mode>2"
15327 [(use (match_operand:SI 0 "register_operand"))
15328 (use (match_operand:MODEF 1 "register_operand"))]
15329 "TARGET_USE_FANCY_MATH_387
15330 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15331 || TARGET_MIX_SSE_I387)
15332 && flag_unsafe_math_optimizations"
15336 if (optimize_insn_for_size_p ())
15339 op0 = gen_reg_rtx (XFmode);
15340 op1 = gen_reg_rtx (XFmode);
15342 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15343 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15347 (define_insn "*f2xm1xf2_i387"
15348 [(set (match_operand:XF 0 "register_operand" "=f")
15349 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15351 "TARGET_USE_FANCY_MATH_387
15352 && flag_unsafe_math_optimizations"
15354 [(set_attr "type" "fpspc")
15355 (set_attr "znver1_decode" "vector")
15356 (set_attr "mode" "XF")])
15358 (define_insn "fscalexf4_i387"
15359 [(set (match_operand:XF 0 "register_operand" "=f")
15360 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15361 (match_operand:XF 3 "register_operand" "1")]
15362 UNSPEC_FSCALE_FRACT))
15363 (set (match_operand:XF 1 "register_operand" "=u")
15364 (unspec:XF [(match_dup 2) (match_dup 3)]
15365 UNSPEC_FSCALE_EXP))]
15366 "TARGET_USE_FANCY_MATH_387
15367 && flag_unsafe_math_optimizations"
15369 [(set_attr "type" "fpspc")
15370 (set_attr "znver1_decode" "vector")
15371 (set_attr "mode" "XF")])
15373 (define_expand "expNcorexf3"
15374 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15375 (match_operand:XF 2 "register_operand")))
15376 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15377 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15378 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15379 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15380 (parallel [(set (match_operand:XF 0 "register_operand")
15381 (unspec:XF [(match_dup 8) (match_dup 4)]
15382 UNSPEC_FSCALE_FRACT))
15384 (unspec:XF [(match_dup 8) (match_dup 4)]
15385 UNSPEC_FSCALE_EXP))])]
15386 "TARGET_USE_FANCY_MATH_387
15387 && flag_unsafe_math_optimizations"
15391 for (i = 3; i < 10; i++)
15392 operands[i] = gen_reg_rtx (XFmode);
15394 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15397 (define_expand "expxf2"
15398 [(use (match_operand:XF 0 "register_operand"))
15399 (use (match_operand:XF 1 "register_operand"))]
15400 "TARGET_USE_FANCY_MATH_387
15401 && flag_unsafe_math_optimizations"
15405 op2 = gen_reg_rtx (XFmode);
15406 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
15408 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15412 (define_expand "exp<mode>2"
15413 [(use (match_operand:MODEF 0 "register_operand"))
15414 (use (match_operand:MODEF 1 "general_operand"))]
15415 "TARGET_USE_FANCY_MATH_387
15416 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15417 || TARGET_MIX_SSE_I387)
15418 && flag_unsafe_math_optimizations"
15422 op0 = gen_reg_rtx (XFmode);
15423 op1 = gen_reg_rtx (XFmode);
15425 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15426 emit_insn (gen_expxf2 (op0, op1));
15427 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15431 (define_expand "exp10xf2"
15432 [(use (match_operand:XF 0 "register_operand"))
15433 (use (match_operand:XF 1 "register_operand"))]
15434 "TARGET_USE_FANCY_MATH_387
15435 && flag_unsafe_math_optimizations"
15439 op2 = gen_reg_rtx (XFmode);
15440 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
15442 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15446 (define_expand "exp10<mode>2"
15447 [(use (match_operand:MODEF 0 "register_operand"))
15448 (use (match_operand:MODEF 1 "general_operand"))]
15449 "TARGET_USE_FANCY_MATH_387
15450 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15451 || TARGET_MIX_SSE_I387)
15452 && flag_unsafe_math_optimizations"
15456 op0 = gen_reg_rtx (XFmode);
15457 op1 = gen_reg_rtx (XFmode);
15459 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15460 emit_insn (gen_exp10xf2 (op0, op1));
15461 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15465 (define_expand "exp2xf2"
15466 [(use (match_operand:XF 0 "register_operand"))
15467 (use (match_operand:XF 1 "register_operand"))]
15468 "TARGET_USE_FANCY_MATH_387
15469 && flag_unsafe_math_optimizations"
15473 op2 = gen_reg_rtx (XFmode);
15474 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15476 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15480 (define_expand "exp2<mode>2"
15481 [(use (match_operand:MODEF 0 "register_operand"))
15482 (use (match_operand:MODEF 1 "general_operand"))]
15483 "TARGET_USE_FANCY_MATH_387
15484 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15485 || TARGET_MIX_SSE_I387)
15486 && flag_unsafe_math_optimizations"
15490 op0 = gen_reg_rtx (XFmode);
15491 op1 = gen_reg_rtx (XFmode);
15493 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15494 emit_insn (gen_exp2xf2 (op0, op1));
15495 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15499 (define_expand "expm1xf2"
15500 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15502 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15503 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15504 (set (match_dup 9) (float_extend:XF (match_dup 13)))
15505 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15506 (parallel [(set (match_dup 7)
15507 (unspec:XF [(match_dup 6) (match_dup 4)]
15508 UNSPEC_FSCALE_FRACT))
15510 (unspec:XF [(match_dup 6) (match_dup 4)]
15511 UNSPEC_FSCALE_EXP))])
15512 (parallel [(set (match_dup 10)
15513 (unspec:XF [(match_dup 9) (match_dup 8)]
15514 UNSPEC_FSCALE_FRACT))
15515 (set (match_dup 11)
15516 (unspec:XF [(match_dup 9) (match_dup 8)]
15517 UNSPEC_FSCALE_EXP))])
15518 (set (match_dup 12) (minus:XF (match_dup 10)
15519 (float_extend:XF (match_dup 13))))
15520 (set (match_operand:XF 0 "register_operand")
15521 (plus:XF (match_dup 12) (match_dup 7)))]
15522 "TARGET_USE_FANCY_MATH_387
15523 && flag_unsafe_math_optimizations"
15527 for (i = 2; i < 13; i++)
15528 operands[i] = gen_reg_rtx (XFmode);
15531 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
15533 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
15536 (define_expand "expm1<mode>2"
15537 [(use (match_operand:MODEF 0 "register_operand"))
15538 (use (match_operand:MODEF 1 "general_operand"))]
15539 "TARGET_USE_FANCY_MATH_387
15540 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15541 || TARGET_MIX_SSE_I387)
15542 && flag_unsafe_math_optimizations"
15546 op0 = gen_reg_rtx (XFmode);
15547 op1 = gen_reg_rtx (XFmode);
15549 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15550 emit_insn (gen_expm1xf2 (op0, op1));
15551 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15555 (define_expand "ldexpxf3"
15556 [(match_operand:XF 0 "register_operand")
15557 (match_operand:XF 1 "register_operand")
15558 (match_operand:SI 2 "register_operand")]
15559 "TARGET_USE_FANCY_MATH_387
15560 && flag_unsafe_math_optimizations"
15564 tmp1 = gen_reg_rtx (XFmode);
15565 tmp2 = gen_reg_rtx (XFmode);
15567 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
15568 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
15569 operands[1], tmp1));
15573 (define_expand "ldexp<mode>3"
15574 [(use (match_operand:MODEF 0 "register_operand"))
15575 (use (match_operand:MODEF 1 "general_operand"))
15576 (use (match_operand:SI 2 "register_operand"))]
15577 "TARGET_USE_FANCY_MATH_387
15578 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15579 || TARGET_MIX_SSE_I387)
15580 && flag_unsafe_math_optimizations"
15584 op0 = gen_reg_rtx (XFmode);
15585 op1 = gen_reg_rtx (XFmode);
15587 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15588 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15589 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15593 (define_expand "scalbxf3"
15594 [(parallel [(set (match_operand:XF 0 " register_operand")
15595 (unspec:XF [(match_operand:XF 1 "register_operand")
15596 (match_operand:XF 2 "register_operand")]
15597 UNSPEC_FSCALE_FRACT))
15599 (unspec:XF [(match_dup 1) (match_dup 2)]
15600 UNSPEC_FSCALE_EXP))])]
15601 "TARGET_USE_FANCY_MATH_387
15602 && flag_unsafe_math_optimizations"
15604 operands[3] = gen_reg_rtx (XFmode);
15607 (define_expand "scalb<mode>3"
15608 [(use (match_operand:MODEF 0 "register_operand"))
15609 (use (match_operand:MODEF 1 "general_operand"))
15610 (use (match_operand:MODEF 2 "general_operand"))]
15611 "TARGET_USE_FANCY_MATH_387
15612 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15613 || TARGET_MIX_SSE_I387)
15614 && flag_unsafe_math_optimizations"
15618 op0 = gen_reg_rtx (XFmode);
15619 op1 = gen_reg_rtx (XFmode);
15620 op2 = gen_reg_rtx (XFmode);
15622 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15623 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15624 emit_insn (gen_scalbxf3 (op0, op1, op2));
15625 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15629 (define_expand "significandxf2"
15630 [(parallel [(set (match_operand:XF 0 "register_operand")
15631 (unspec:XF [(match_operand:XF 1 "register_operand")]
15632 UNSPEC_XTRACT_FRACT))
15634 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15635 "TARGET_USE_FANCY_MATH_387
15636 && flag_unsafe_math_optimizations"
15637 "operands[2] = gen_reg_rtx (XFmode);")
15639 (define_expand "significand<mode>2"
15640 [(use (match_operand:MODEF 0 "register_operand"))
15641 (use (match_operand:MODEF 1 "register_operand"))]
15642 "TARGET_USE_FANCY_MATH_387
15643 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15644 || TARGET_MIX_SSE_I387)
15645 && flag_unsafe_math_optimizations"
15647 rtx op0 = gen_reg_rtx (XFmode);
15648 rtx op1 = gen_reg_rtx (XFmode);
15650 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15651 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15656 (define_insn "sse4_1_round<mode>2"
15657 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
15658 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x,v")
15659 (match_operand:SI 2 "const_0_to_15_operand" "n,n")]
15663 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
15664 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15665 [(set_attr "type" "ssecvt")
15666 (set_attr "prefix_extra" "1,*")
15667 (set_attr "length_immediate" "*,1")
15668 (set_attr "prefix" "maybe_vex,evex")
15669 (set_attr "isa" "noavx512f,avx512f")
15670 (set_attr "mode" "<MODE>")])
15672 (define_insn "rintxf2"
15673 [(set (match_operand:XF 0 "register_operand" "=f")
15674 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15676 "TARGET_USE_FANCY_MATH_387"
15678 [(set_attr "type" "fpspc")
15679 (set_attr "znver1_decode" "vector")
15680 (set_attr "mode" "XF")])
15682 (define_insn "rint<mode>2_frndint"
15683 [(set (match_operand:MODEF 0 "register_operand" "=f")
15684 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "0")]
15686 "TARGET_USE_FANCY_MATH_387"
15688 [(set_attr "type" "fpspc")
15689 (set_attr "znver1_decode" "vector")
15690 (set_attr "mode" "<MODE>")])
15692 (define_expand "rint<mode>2"
15693 [(use (match_operand:MODEF 0 "register_operand"))
15694 (use (match_operand:MODEF 1 "register_operand"))]
15695 "(TARGET_USE_FANCY_MATH_387
15696 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15697 || TARGET_MIX_SSE_I387))
15698 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15700 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15703 emit_insn (gen_sse4_1_round<mode>2
15704 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
15706 ix86_expand_rint (operands[0], operands[1]);
15709 emit_insn (gen_rint<mode>2_frndint (operands[0], operands[1]));
15713 (define_expand "round<mode>2"
15714 [(match_operand:X87MODEF 0 "register_operand")
15715 (match_operand:X87MODEF 1 "nonimmediate_operand")]
15716 "(TARGET_USE_FANCY_MATH_387
15717 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15718 || TARGET_MIX_SSE_I387)
15719 && flag_unsafe_math_optimizations)
15720 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15721 && !flag_trapping_math && !flag_rounding_math)"
15723 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15724 && !flag_trapping_math && !flag_rounding_math)
15728 operands[1] = force_reg (<MODE>mode, operands[1]);
15729 ix86_expand_round_sse4 (operands[0], operands[1]);
15731 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15732 ix86_expand_round (operands[0], operands[1]);
15734 ix86_expand_rounddf_32 (operands[0], operands[1]);
15738 operands[1] = force_reg (<MODE>mode, operands[1]);
15739 ix86_emit_i387_round (operands[0], operands[1]);
15744 (define_insn_and_split "*fistdi2_1"
15745 [(set (match_operand:DI 0 "nonimmediate_operand")
15746 (unspec:DI [(match_operand:XF 1 "register_operand")]
15748 "TARGET_USE_FANCY_MATH_387
15749 && can_create_pseudo_p ()"
15754 if (memory_operand (operands[0], VOIDmode))
15755 emit_insn (gen_fistdi2 (operands[0], operands[1]));
15758 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15759 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15764 [(set_attr "type" "fpspc")
15765 (set_attr "mode" "DI")])
15767 (define_insn "fistdi2"
15768 [(set (match_operand:DI 0 "memory_operand" "=m")
15769 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15771 (clobber (match_scratch:XF 2 "=&1f"))]
15772 "TARGET_USE_FANCY_MATH_387"
15773 "* return output_fix_trunc (insn, operands, false);"
15774 [(set_attr "type" "fpspc")
15775 (set_attr "mode" "DI")])
15777 (define_insn "fistdi2_with_temp"
15778 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15779 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15781 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15782 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15783 "TARGET_USE_FANCY_MATH_387"
15785 [(set_attr "type" "fpspc")
15786 (set_attr "mode" "DI")])
15789 [(set (match_operand:DI 0 "register_operand")
15790 (unspec:DI [(match_operand:XF 1 "register_operand")]
15792 (clobber (match_operand:DI 2 "memory_operand"))
15793 (clobber (match_scratch 3))]
15795 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15796 (clobber (match_dup 3))])
15797 (set (match_dup 0) (match_dup 2))])
15800 [(set (match_operand:DI 0 "memory_operand")
15801 (unspec:DI [(match_operand:XF 1 "register_operand")]
15803 (clobber (match_operand:DI 2 "memory_operand"))
15804 (clobber (match_scratch 3))]
15806 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15807 (clobber (match_dup 3))])])
15809 (define_insn_and_split "*fist<mode>2_1"
15810 [(set (match_operand:SWI24 0 "register_operand")
15811 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15813 "TARGET_USE_FANCY_MATH_387
15814 && can_create_pseudo_p ()"
15819 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15820 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15824 [(set_attr "type" "fpspc")
15825 (set_attr "mode" "<MODE>")])
15827 (define_insn "fist<mode>2"
15828 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15829 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15831 "TARGET_USE_FANCY_MATH_387"
15832 "* return output_fix_trunc (insn, operands, false);"
15833 [(set_attr "type" "fpspc")
15834 (set_attr "mode" "<MODE>")])
15836 (define_insn "fist<mode>2_with_temp"
15837 [(set (match_operand:SWI24 0 "register_operand" "=r")
15838 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15840 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15841 "TARGET_USE_FANCY_MATH_387"
15843 [(set_attr "type" "fpspc")
15844 (set_attr "mode" "<MODE>")])
15847 [(set (match_operand:SWI24 0 "register_operand")
15848 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15850 (clobber (match_operand:SWI24 2 "memory_operand"))]
15852 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15853 (set (match_dup 0) (match_dup 2))])
15856 [(set (match_operand:SWI24 0 "memory_operand")
15857 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15859 (clobber (match_operand:SWI24 2 "memory_operand"))]
15861 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15863 (define_expand "lrintxf<mode>2"
15864 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15865 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15867 "TARGET_USE_FANCY_MATH_387")
15869 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15870 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15871 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15872 UNSPEC_FIX_NOTRUNC))]
15873 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15875 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15876 [(match_operand:SWI248x 0 "nonimmediate_operand")
15877 (match_operand:X87MODEF 1 "register_operand")]
15878 "(TARGET_USE_FANCY_MATH_387
15879 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15880 || TARGET_MIX_SSE_I387)
15881 && flag_unsafe_math_optimizations)
15882 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15883 && <SWI248x:MODE>mode != HImode
15884 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15885 && !flag_trapping_math && !flag_rounding_math)"
15887 if (optimize_insn_for_size_p ())
15890 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15891 && <SWI248x:MODE>mode != HImode
15892 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15893 && !flag_trapping_math && !flag_rounding_math)
15894 ix86_expand_lround (operands[0], operands[1]);
15896 ix86_emit_i387_round (operands[0], operands[1]);
15900 (define_int_iterator FRNDINT_ROUNDING
15901 [UNSPEC_FRNDINT_FLOOR
15902 UNSPEC_FRNDINT_CEIL
15903 UNSPEC_FRNDINT_TRUNC])
15905 (define_int_iterator FIST_ROUNDING
15909 ;; Base name for define_insn
15910 (define_int_attr rounding_insn
15911 [(UNSPEC_FRNDINT_FLOOR "floor")
15912 (UNSPEC_FRNDINT_CEIL "ceil")
15913 (UNSPEC_FRNDINT_TRUNC "btrunc")
15914 (UNSPEC_FIST_FLOOR "floor")
15915 (UNSPEC_FIST_CEIL "ceil")])
15917 (define_int_attr rounding
15918 [(UNSPEC_FRNDINT_FLOOR "floor")
15919 (UNSPEC_FRNDINT_CEIL "ceil")
15920 (UNSPEC_FRNDINT_TRUNC "trunc")
15921 (UNSPEC_FIST_FLOOR "floor")
15922 (UNSPEC_FIST_CEIL "ceil")])
15924 (define_int_attr ROUNDING
15925 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15926 (UNSPEC_FRNDINT_CEIL "CEIL")
15927 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15928 (UNSPEC_FIST_FLOOR "FLOOR")
15929 (UNSPEC_FIST_CEIL "CEIL")])
15931 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15932 (define_insn_and_split "frndint<mode>2_<rounding>"
15933 [(set (match_operand:X87MODEF 0 "register_operand")
15934 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand")]
15936 (clobber (reg:CC FLAGS_REG))]
15937 "TARGET_USE_FANCY_MATH_387
15938 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
15939 && can_create_pseudo_p ()"
15944 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15946 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15947 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15949 emit_insn (gen_frndint<mode>2_<rounding>_i387 (operands[0], operands[1],
15950 operands[2], operands[3]));
15953 [(set_attr "type" "frndint")
15954 (set_attr "i387_cw" "<rounding>")
15955 (set_attr "mode" "<MODE>")])
15957 (define_insn "frndint<mode>2_<rounding>_i387"
15958 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
15959 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand" "0")]
15961 (use (match_operand:HI 2 "memory_operand" "m"))
15962 (use (match_operand:HI 3 "memory_operand" "m"))]
15963 "TARGET_USE_FANCY_MATH_387
15964 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
15965 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15966 [(set_attr "type" "frndint")
15967 (set_attr "i387_cw" "<rounding>")
15968 (set_attr "mode" "<MODE>")])
15970 (define_expand "<rounding_insn>xf2"
15971 [(parallel [(set (match_operand:XF 0 "register_operand")
15972 (unspec:XF [(match_operand:XF 1 "register_operand")]
15974 (clobber (reg:CC FLAGS_REG))])]
15975 "TARGET_USE_FANCY_MATH_387
15976 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
15978 (define_expand "<rounding_insn><mode>2"
15979 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15980 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15982 (clobber (reg:CC FLAGS_REG))])]
15983 "(TARGET_USE_FANCY_MATH_387
15984 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15985 || TARGET_MIX_SSE_I387)
15986 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
15987 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15988 && (TARGET_SSE4_1 || !flag_trapping_math
15989 || flag_fp_int_builtin_inexact))"
15991 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15992 && (TARGET_SSE4_1 || !flag_trapping_math || flag_fp_int_builtin_inexact))
15995 emit_insn (gen_sse4_1_round<mode>2
15996 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>
15998 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16000 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16001 ix86_expand_floorceil (operands[0], operands[1], true);
16002 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16003 ix86_expand_floorceil (operands[0], operands[1], false);
16004 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16005 ix86_expand_trunc (operands[0], operands[1]);
16007 gcc_unreachable ();
16011 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16012 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
16013 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16014 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
16015 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16016 ix86_expand_truncdf_32 (operands[0], operands[1]);
16018 gcc_unreachable ();
16022 emit_insn (gen_frndint<mode>2_<rounding> (operands[0], operands[1]));
16026 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16027 (define_insn_and_split "frndintxf2_mask_pm"
16028 [(set (match_operand:XF 0 "register_operand")
16029 (unspec:XF [(match_operand:XF 1 "register_operand")]
16030 UNSPEC_FRNDINT_MASK_PM))
16031 (clobber (reg:CC FLAGS_REG))]
16032 "TARGET_USE_FANCY_MATH_387
16033 && flag_unsafe_math_optimizations
16034 && can_create_pseudo_p ()"
16039 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
16041 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16042 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
16044 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
16045 operands[2], operands[3]));
16048 [(set_attr "type" "frndint")
16049 (set_attr "i387_cw" "mask_pm")
16050 (set_attr "mode" "XF")])
16052 (define_insn "frndintxf2_mask_pm_i387"
16053 [(set (match_operand:XF 0 "register_operand" "=f")
16054 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16055 UNSPEC_FRNDINT_MASK_PM))
16056 (use (match_operand:HI 2 "memory_operand" "m"))
16057 (use (match_operand:HI 3 "memory_operand" "m"))]
16058 "TARGET_USE_FANCY_MATH_387
16059 && flag_unsafe_math_optimizations"
16060 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16061 [(set_attr "type" "frndint")
16062 (set_attr "i387_cw" "mask_pm")
16063 (set_attr "mode" "XF")])
16065 (define_expand "nearbyintxf2"
16066 [(parallel [(set (match_operand:XF 0 "register_operand")
16067 (unspec:XF [(match_operand:XF 1 "register_operand")]
16068 UNSPEC_FRNDINT_MASK_PM))
16069 (clobber (reg:CC FLAGS_REG))])]
16070 "TARGET_USE_FANCY_MATH_387
16071 && flag_unsafe_math_optimizations")
16073 (define_expand "nearbyint<mode>2"
16074 [(use (match_operand:MODEF 0 "register_operand"))
16075 (use (match_operand:MODEF 1 "register_operand"))]
16076 "TARGET_USE_FANCY_MATH_387
16077 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16078 || TARGET_MIX_SSE_I387)
16079 && flag_unsafe_math_optimizations"
16081 rtx op0 = gen_reg_rtx (XFmode);
16082 rtx op1 = gen_reg_rtx (XFmode);
16084 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16085 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16087 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16091 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16092 (define_insn_and_split "*fist<mode>2_<rounding>_1"
16093 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16094 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16096 (clobber (reg:CC FLAGS_REG))]
16097 "TARGET_USE_FANCY_MATH_387
16098 && flag_unsafe_math_optimizations
16099 && can_create_pseudo_p ()"
16104 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16106 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16107 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16108 if (memory_operand (operands[0], VOIDmode))
16109 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
16110 operands[2], operands[3]));
16113 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16114 emit_insn (gen_fist<mode>2_<rounding>_with_temp
16115 (operands[0], operands[1], operands[2],
16116 operands[3], operands[4]));
16120 [(set_attr "type" "fistp")
16121 (set_attr "i387_cw" "<rounding>")
16122 (set_attr "mode" "<MODE>")])
16124 (define_insn "fistdi2_<rounding>"
16125 [(set (match_operand:DI 0 "memory_operand" "=m")
16126 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16128 (use (match_operand:HI 2 "memory_operand" "m"))
16129 (use (match_operand:HI 3 "memory_operand" "m"))
16130 (clobber (match_scratch:XF 4 "=&1f"))]
16131 "TARGET_USE_FANCY_MATH_387
16132 && flag_unsafe_math_optimizations"
16133 "* return output_fix_trunc (insn, operands, false);"
16134 [(set_attr "type" "fistp")
16135 (set_attr "i387_cw" "<rounding>")
16136 (set_attr "mode" "DI")])
16138 (define_insn "fistdi2_<rounding>_with_temp"
16139 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16140 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16142 (use (match_operand:HI 2 "memory_operand" "m,m"))
16143 (use (match_operand:HI 3 "memory_operand" "m,m"))
16144 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
16145 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16146 "TARGET_USE_FANCY_MATH_387
16147 && flag_unsafe_math_optimizations"
16149 [(set_attr "type" "fistp")
16150 (set_attr "i387_cw" "<rounding>")
16151 (set_attr "mode" "DI")])
16154 [(set (match_operand:DI 0 "register_operand")
16155 (unspec:DI [(match_operand:XF 1 "register_operand")]
16157 (use (match_operand:HI 2 "memory_operand"))
16158 (use (match_operand:HI 3 "memory_operand"))
16159 (clobber (match_operand:DI 4 "memory_operand"))
16160 (clobber (match_scratch 5))]
16162 [(parallel [(set (match_dup 4)
16163 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16164 (use (match_dup 2))
16165 (use (match_dup 3))
16166 (clobber (match_dup 5))])
16167 (set (match_dup 0) (match_dup 4))])
16170 [(set (match_operand:DI 0 "memory_operand")
16171 (unspec:DI [(match_operand:XF 1 "register_operand")]
16173 (use (match_operand:HI 2 "memory_operand"))
16174 (use (match_operand:HI 3 "memory_operand"))
16175 (clobber (match_operand:DI 4 "memory_operand"))
16176 (clobber (match_scratch 5))]
16178 [(parallel [(set (match_dup 0)
16179 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16180 (use (match_dup 2))
16181 (use (match_dup 3))
16182 (clobber (match_dup 5))])])
16184 (define_insn "fist<mode>2_<rounding>"
16185 [(set (match_operand:SWI24 0 "memory_operand" "=m")
16186 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16188 (use (match_operand:HI 2 "memory_operand" "m"))
16189 (use (match_operand:HI 3 "memory_operand" "m"))]
16190 "TARGET_USE_FANCY_MATH_387
16191 && flag_unsafe_math_optimizations"
16192 "* return output_fix_trunc (insn, operands, false);"
16193 [(set_attr "type" "fistp")
16194 (set_attr "i387_cw" "<rounding>")
16195 (set_attr "mode" "<MODE>")])
16197 (define_insn "fist<mode>2_<rounding>_with_temp"
16198 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
16199 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
16201 (use (match_operand:HI 2 "memory_operand" "m,m"))
16202 (use (match_operand:HI 3 "memory_operand" "m,m"))
16203 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
16204 "TARGET_USE_FANCY_MATH_387
16205 && flag_unsafe_math_optimizations"
16207 [(set_attr "type" "fistp")
16208 (set_attr "i387_cw" "<rounding>")
16209 (set_attr "mode" "<MODE>")])
16212 [(set (match_operand:SWI24 0 "register_operand")
16213 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16215 (use (match_operand:HI 2 "memory_operand"))
16216 (use (match_operand:HI 3 "memory_operand"))
16217 (clobber (match_operand:SWI24 4 "memory_operand"))]
16219 [(parallel [(set (match_dup 4)
16220 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16221 (use (match_dup 2))
16222 (use (match_dup 3))])
16223 (set (match_dup 0) (match_dup 4))])
16226 [(set (match_operand:SWI24 0 "memory_operand")
16227 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16229 (use (match_operand:HI 2 "memory_operand"))
16230 (use (match_operand:HI 3 "memory_operand"))
16231 (clobber (match_operand:SWI24 4 "memory_operand"))]
16233 [(parallel [(set (match_dup 0)
16234 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16235 (use (match_dup 2))
16236 (use (match_dup 3))])])
16238 (define_expand "l<rounding_insn>xf<mode>2"
16239 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16240 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16242 (clobber (reg:CC FLAGS_REG))])]
16243 "TARGET_USE_FANCY_MATH_387
16244 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16245 && flag_unsafe_math_optimizations")
16247 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
16248 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
16249 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16251 (clobber (reg:CC FLAGS_REG))])]
16252 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16253 && !flag_trapping_math"
16255 if (TARGET_64BIT && optimize_insn_for_size_p ())
16258 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16259 ix86_expand_lfloorceil (operands[0], operands[1], true);
16260 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16261 ix86_expand_lfloorceil (operands[0], operands[1], false);
16263 gcc_unreachable ();
16268 (define_insn "fxam<mode>2_i387"
16269 [(set (match_operand:HI 0 "register_operand" "=a")
16271 [(match_operand:X87MODEF 1 "register_operand" "f")]
16273 "TARGET_USE_FANCY_MATH_387"
16274 "fxam\n\tfnstsw\t%0"
16275 [(set_attr "type" "multi")
16276 (set_attr "length" "4")
16277 (set_attr "unit" "i387")
16278 (set_attr "mode" "<MODE>")])
16280 (define_insn_and_split "fxam<mode>2_i387_with_temp"
16281 [(set (match_operand:HI 0 "register_operand")
16283 [(match_operand:MODEF 1 "memory_operand")]
16285 "TARGET_USE_FANCY_MATH_387
16286 && can_create_pseudo_p ()"
16289 [(set (match_dup 2)(match_dup 1))
16291 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
16293 operands[2] = gen_reg_rtx (<MODE>mode);
16295 MEM_VOLATILE_P (operands[1]) = 1;
16297 [(set_attr "type" "multi")
16298 (set_attr "unit" "i387")
16299 (set_attr "mode" "<MODE>")])
16301 (define_expand "isinfxf2"
16302 [(use (match_operand:SI 0 "register_operand"))
16303 (use (match_operand:XF 1 "register_operand"))]
16304 "TARGET_USE_FANCY_MATH_387
16305 && ix86_libc_has_function (function_c99_misc)"
16307 rtx mask = GEN_INT (0x45);
16308 rtx val = GEN_INT (0x05);
16310 rtx scratch = gen_reg_rtx (HImode);
16311 rtx res = gen_reg_rtx (QImode);
16313 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16315 emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
16316 emit_insn (gen_cmpqi_ext_3 (scratch, val));
16317 ix86_expand_setcc (res, EQ,
16318 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
16319 emit_insn (gen_zero_extendqisi2 (operands[0], res));
16323 (define_expand "isinf<mode>2"
16324 [(use (match_operand:SI 0 "register_operand"))
16325 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
16326 "TARGET_USE_FANCY_MATH_387
16327 && ix86_libc_has_function (function_c99_misc)
16328 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16330 rtx mask = GEN_INT (0x45);
16331 rtx val = GEN_INT (0x05);
16333 rtx scratch = gen_reg_rtx (HImode);
16334 rtx res = gen_reg_rtx (QImode);
16336 /* Remove excess precision by forcing value through memory. */
16337 if (memory_operand (operands[1], VOIDmode))
16338 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
16341 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16343 emit_move_insn (temp, operands[1]);
16344 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
16347 emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
16348 emit_insn (gen_cmpqi_ext_3 (scratch, val));
16349 ix86_expand_setcc (res, EQ,
16350 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
16351 emit_insn (gen_zero_extendqisi2 (operands[0], res));
16355 (define_expand "signbittf2"
16356 [(use (match_operand:SI 0 "register_operand"))
16357 (use (match_operand:TF 1 "register_operand"))]
16362 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
16363 rtx scratch = gen_reg_rtx (QImode);
16365 emit_insn (gen_ptesttf2 (operands[1], mask));
16366 ix86_expand_setcc (scratch, NE,
16367 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
16369 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
16373 emit_insn (gen_sse_movmskps (operands[0],
16374 gen_lowpart (V4SFmode, operands[1])));
16375 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
16380 (define_expand "signbitxf2"
16381 [(use (match_operand:SI 0 "register_operand"))
16382 (use (match_operand:XF 1 "register_operand"))]
16383 "TARGET_USE_FANCY_MATH_387"
16385 rtx scratch = gen_reg_rtx (HImode);
16387 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16388 emit_insn (gen_andsi3 (operands[0],
16389 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16393 (define_insn "movmsk_df"
16394 [(set (match_operand:SI 0 "register_operand" "=r")
16396 [(match_operand:DF 1 "register_operand" "x")]
16398 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
16399 "%vmovmskpd\t{%1, %0|%0, %1}"
16400 [(set_attr "type" "ssemov")
16401 (set_attr "prefix" "maybe_vex")
16402 (set_attr "mode" "DF")])
16404 ;; Use movmskpd in SSE mode to avoid store forwarding stall
16405 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
16406 (define_expand "signbitdf2"
16407 [(use (match_operand:SI 0 "register_operand"))
16408 (use (match_operand:DF 1 "register_operand"))]
16409 "TARGET_USE_FANCY_MATH_387
16410 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
16412 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
16414 emit_insn (gen_movmsk_df (operands[0], operands[1]));
16415 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
16419 rtx scratch = gen_reg_rtx (HImode);
16421 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
16422 emit_insn (gen_andsi3 (operands[0],
16423 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16428 (define_expand "signbitsf2"
16429 [(use (match_operand:SI 0 "register_operand"))
16430 (use (match_operand:SF 1 "register_operand"))]
16431 "TARGET_USE_FANCY_MATH_387
16432 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
16434 rtx scratch = gen_reg_rtx (HImode);
16436 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
16437 emit_insn (gen_andsi3 (operands[0],
16438 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16442 ;; Block operation instructions
16445 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16448 [(set_attr "length" "1")
16449 (set_attr "length_immediate" "0")
16450 (set_attr "modrm" "0")])
16452 (define_expand "movmem<mode>"
16453 [(use (match_operand:BLK 0 "memory_operand"))
16454 (use (match_operand:BLK 1 "memory_operand"))
16455 (use (match_operand:SWI48 2 "nonmemory_operand"))
16456 (use (match_operand:SWI48 3 "const_int_operand"))
16457 (use (match_operand:SI 4 "const_int_operand"))
16458 (use (match_operand:SI 5 "const_int_operand"))
16459 (use (match_operand:SI 6 ""))
16460 (use (match_operand:SI 7 ""))
16461 (use (match_operand:SI 8 ""))]
16464 if (ix86_expand_set_or_movmem (operands[0], operands[1],
16465 operands[2], NULL, operands[3],
16466 operands[4], operands[5],
16467 operands[6], operands[7],
16468 operands[8], false))
16474 ;; Most CPUs don't like single string operations
16475 ;; Handle this case here to simplify previous expander.
16477 (define_expand "strmov"
16478 [(set (match_dup 4) (match_operand 3 "memory_operand"))
16479 (set (match_operand 1 "memory_operand") (match_dup 4))
16480 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
16481 (clobber (reg:CC FLAGS_REG))])
16482 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
16483 (clobber (reg:CC FLAGS_REG))])]
16486 /* Can't use this for non-default address spaces. */
16487 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
16490 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16492 /* If .md ever supports :P for Pmode, these can be directly
16493 in the pattern above. */
16494 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16495 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16497 /* Can't use this if the user has appropriated esi or edi. */
16498 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16499 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16501 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16502 operands[2], operands[3],
16503 operands[5], operands[6]));
16507 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16510 (define_expand "strmov_singleop"
16511 [(parallel [(set (match_operand 1 "memory_operand")
16512 (match_operand 3 "memory_operand"))
16513 (set (match_operand 0 "register_operand")
16515 (set (match_operand 2 "register_operand")
16516 (match_operand 5))])]
16520 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16523 (define_insn "*strmovdi_rex_1"
16524 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16525 (mem:DI (match_operand:P 3 "register_operand" "1")))
16526 (set (match_operand:P 0 "register_operand" "=D")
16527 (plus:P (match_dup 2)
16529 (set (match_operand:P 1 "register_operand" "=S")
16530 (plus:P (match_dup 3)
16533 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16534 && ix86_check_no_addr_space (insn)"
16536 [(set_attr "type" "str")
16537 (set_attr "memory" "both")
16538 (set_attr "mode" "DI")])
16540 (define_insn "*strmovsi_1"
16541 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16542 (mem:SI (match_operand:P 3 "register_operand" "1")))
16543 (set (match_operand:P 0 "register_operand" "=D")
16544 (plus:P (match_dup 2)
16546 (set (match_operand:P 1 "register_operand" "=S")
16547 (plus:P (match_dup 3)
16549 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16550 && ix86_check_no_addr_space (insn)"
16552 [(set_attr "type" "str")
16553 (set_attr "memory" "both")
16554 (set_attr "mode" "SI")])
16556 (define_insn "*strmovhi_1"
16557 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16558 (mem:HI (match_operand:P 3 "register_operand" "1")))
16559 (set (match_operand:P 0 "register_operand" "=D")
16560 (plus:P (match_dup 2)
16562 (set (match_operand:P 1 "register_operand" "=S")
16563 (plus:P (match_dup 3)
16565 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16566 && ix86_check_no_addr_space (insn)"
16568 [(set_attr "type" "str")
16569 (set_attr "memory" "both")
16570 (set_attr "mode" "HI")])
16572 (define_insn "*strmovqi_1"
16573 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16574 (mem:QI (match_operand:P 3 "register_operand" "1")))
16575 (set (match_operand:P 0 "register_operand" "=D")
16576 (plus:P (match_dup 2)
16578 (set (match_operand:P 1 "register_operand" "=S")
16579 (plus:P (match_dup 3)
16581 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16582 && ix86_check_no_addr_space (insn)"
16584 [(set_attr "type" "str")
16585 (set_attr "memory" "both")
16586 (set (attr "prefix_rex")
16588 (match_test "<P:MODE>mode == DImode")
16590 (const_string "*")))
16591 (set_attr "mode" "QI")])
16593 (define_expand "rep_mov"
16594 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16595 (set (match_operand 0 "register_operand")
16597 (set (match_operand 2 "register_operand")
16599 (set (match_operand 1 "memory_operand")
16600 (match_operand 3 "memory_operand"))
16601 (use (match_dup 4))])]
16605 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16608 (define_insn "*rep_movdi_rex64"
16609 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16610 (set (match_operand:P 0 "register_operand" "=D")
16611 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16613 (match_operand:P 3 "register_operand" "0")))
16614 (set (match_operand:P 1 "register_operand" "=S")
16615 (plus:P (ashift:P (match_dup 5) (const_int 3))
16616 (match_operand:P 4 "register_operand" "1")))
16617 (set (mem:BLK (match_dup 3))
16618 (mem:BLK (match_dup 4)))
16619 (use (match_dup 5))]
16621 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16622 && ix86_check_no_addr_space (insn)"
16624 [(set_attr "type" "str")
16625 (set_attr "prefix_rep" "1")
16626 (set_attr "memory" "both")
16627 (set_attr "mode" "DI")])
16629 (define_insn "*rep_movsi"
16630 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16631 (set (match_operand:P 0 "register_operand" "=D")
16632 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16634 (match_operand:P 3 "register_operand" "0")))
16635 (set (match_operand:P 1 "register_operand" "=S")
16636 (plus:P (ashift:P (match_dup 5) (const_int 2))
16637 (match_operand:P 4 "register_operand" "1")))
16638 (set (mem:BLK (match_dup 3))
16639 (mem:BLK (match_dup 4)))
16640 (use (match_dup 5))]
16641 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16642 && ix86_check_no_addr_space (insn)"
16643 "%^rep{%;} movs{l|d}"
16644 [(set_attr "type" "str")
16645 (set_attr "prefix_rep" "1")
16646 (set_attr "memory" "both")
16647 (set_attr "mode" "SI")])
16649 (define_insn "*rep_movqi"
16650 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16651 (set (match_operand:P 0 "register_operand" "=D")
16652 (plus:P (match_operand:P 3 "register_operand" "0")
16653 (match_operand:P 5 "register_operand" "2")))
16654 (set (match_operand:P 1 "register_operand" "=S")
16655 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16656 (set (mem:BLK (match_dup 3))
16657 (mem:BLK (match_dup 4)))
16658 (use (match_dup 5))]
16659 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16660 && ix86_check_no_addr_space (insn)"
16662 [(set_attr "type" "str")
16663 (set_attr "prefix_rep" "1")
16664 (set_attr "memory" "both")
16665 (set_attr "mode" "QI")])
16667 (define_expand "setmem<mode>"
16668 [(use (match_operand:BLK 0 "memory_operand"))
16669 (use (match_operand:SWI48 1 "nonmemory_operand"))
16670 (use (match_operand:QI 2 "nonmemory_operand"))
16671 (use (match_operand 3 "const_int_operand"))
16672 (use (match_operand:SI 4 "const_int_operand"))
16673 (use (match_operand:SI 5 "const_int_operand"))
16674 (use (match_operand:SI 6 ""))
16675 (use (match_operand:SI 7 ""))
16676 (use (match_operand:SI 8 ""))]
16679 if (ix86_expand_set_or_movmem (operands[0], NULL,
16680 operands[1], operands[2],
16681 operands[3], operands[4],
16682 operands[5], operands[6],
16683 operands[7], operands[8], true))
16689 ;; Most CPUs don't like single string operations
16690 ;; Handle this case here to simplify previous expander.
16692 (define_expand "strset"
16693 [(set (match_operand 1 "memory_operand")
16694 (match_operand 2 "register_operand"))
16695 (parallel [(set (match_operand 0 "register_operand")
16697 (clobber (reg:CC FLAGS_REG))])]
16700 /* Can't use this for non-default address spaces. */
16701 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
16704 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16705 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16707 /* If .md ever supports :P for Pmode, this can be directly
16708 in the pattern above. */
16709 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16710 GEN_INT (GET_MODE_SIZE (GET_MODE
16712 /* Can't use this if the user has appropriated eax or edi. */
16713 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16714 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16716 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16722 (define_expand "strset_singleop"
16723 [(parallel [(set (match_operand 1 "memory_operand")
16724 (match_operand 2 "register_operand"))
16725 (set (match_operand 0 "register_operand")
16727 (unspec [(const_int 0)] UNSPEC_STOS)])]
16731 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16734 (define_insn "*strsetdi_rex_1"
16735 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16736 (match_operand:DI 2 "register_operand" "a"))
16737 (set (match_operand:P 0 "register_operand" "=D")
16738 (plus:P (match_dup 1)
16740 (unspec [(const_int 0)] UNSPEC_STOS)]
16742 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16743 && ix86_check_no_addr_space (insn)"
16745 [(set_attr "type" "str")
16746 (set_attr "memory" "store")
16747 (set_attr "mode" "DI")])
16749 (define_insn "*strsetsi_1"
16750 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16751 (match_operand:SI 2 "register_operand" "a"))
16752 (set (match_operand:P 0 "register_operand" "=D")
16753 (plus:P (match_dup 1)
16755 (unspec [(const_int 0)] UNSPEC_STOS)]
16756 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16757 && ix86_check_no_addr_space (insn)"
16759 [(set_attr "type" "str")
16760 (set_attr "memory" "store")
16761 (set_attr "mode" "SI")])
16763 (define_insn "*strsethi_1"
16764 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16765 (match_operand:HI 2 "register_operand" "a"))
16766 (set (match_operand:P 0 "register_operand" "=D")
16767 (plus:P (match_dup 1)
16769 (unspec [(const_int 0)] UNSPEC_STOS)]
16770 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16771 && ix86_check_no_addr_space (insn)"
16773 [(set_attr "type" "str")
16774 (set_attr "memory" "store")
16775 (set_attr "mode" "HI")])
16777 (define_insn "*strsetqi_1"
16778 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16779 (match_operand:QI 2 "register_operand" "a"))
16780 (set (match_operand:P 0 "register_operand" "=D")
16781 (plus:P (match_dup 1)
16783 (unspec [(const_int 0)] UNSPEC_STOS)]
16784 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16785 && ix86_check_no_addr_space (insn)"
16787 [(set_attr "type" "str")
16788 (set_attr "memory" "store")
16789 (set (attr "prefix_rex")
16791 (match_test "<P:MODE>mode == DImode")
16793 (const_string "*")))
16794 (set_attr "mode" "QI")])
16796 (define_expand "rep_stos"
16797 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16798 (set (match_operand 0 "register_operand")
16800 (set (match_operand 2 "memory_operand") (const_int 0))
16801 (use (match_operand 3 "register_operand"))
16802 (use (match_dup 1))])]
16806 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16809 (define_insn "*rep_stosdi_rex64"
16810 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16811 (set (match_operand:P 0 "register_operand" "=D")
16812 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16814 (match_operand:P 3 "register_operand" "0")))
16815 (set (mem:BLK (match_dup 3))
16817 (use (match_operand:DI 2 "register_operand" "a"))
16818 (use (match_dup 4))]
16820 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16821 && ix86_check_no_addr_space (insn)"
16823 [(set_attr "type" "str")
16824 (set_attr "prefix_rep" "1")
16825 (set_attr "memory" "store")
16826 (set_attr "mode" "DI")])
16828 (define_insn "*rep_stossi"
16829 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16830 (set (match_operand:P 0 "register_operand" "=D")
16831 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16833 (match_operand:P 3 "register_operand" "0")))
16834 (set (mem:BLK (match_dup 3))
16836 (use (match_operand:SI 2 "register_operand" "a"))
16837 (use (match_dup 4))]
16838 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16839 && ix86_check_no_addr_space (insn)"
16840 "%^rep{%;} stos{l|d}"
16841 [(set_attr "type" "str")
16842 (set_attr "prefix_rep" "1")
16843 (set_attr "memory" "store")
16844 (set_attr "mode" "SI")])
16846 (define_insn "*rep_stosqi"
16847 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16848 (set (match_operand:P 0 "register_operand" "=D")
16849 (plus:P (match_operand:P 3 "register_operand" "0")
16850 (match_operand:P 4 "register_operand" "1")))
16851 (set (mem:BLK (match_dup 3))
16853 (use (match_operand:QI 2 "register_operand" "a"))
16854 (use (match_dup 4))]
16855 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16856 && ix86_check_no_addr_space (insn)"
16858 [(set_attr "type" "str")
16859 (set_attr "prefix_rep" "1")
16860 (set_attr "memory" "store")
16861 (set (attr "prefix_rex")
16863 (match_test "<P:MODE>mode == DImode")
16865 (const_string "*")))
16866 (set_attr "mode" "QI")])
16868 (define_expand "cmpstrnsi"
16869 [(set (match_operand:SI 0 "register_operand")
16870 (compare:SI (match_operand:BLK 1 "general_operand")
16871 (match_operand:BLK 2 "general_operand")))
16872 (use (match_operand 3 "general_operand"))
16873 (use (match_operand 4 "immediate_operand"))]
16876 rtx addr1, addr2, out, outlow, count, countreg, align;
16878 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16881 /* Can't use this if the user has appropriated ecx, esi or edi. */
16882 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16885 /* One of the strings must be a constant. If so, expand_builtin_strncmp()
16886 will have rewritten the length arg to be the minimum of the const string
16887 length and the actual length arg. If both strings are the same and
16888 shorter than the length arg, repz cmpsb will not stop at the 0 byte and
16889 will incorrectly base the results on chars past the 0 byte. */
16890 tree t1 = MEM_EXPR (operands[1]);
16891 tree t2 = MEM_EXPR (operands[2]);
16892 if (!((t1 && TREE_CODE (t1) == MEM_REF
16893 && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR
16894 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST)
16895 || (t2 && TREE_CODE (t2) == MEM_REF
16896 && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR
16897 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST)))
16902 out = gen_reg_rtx (SImode);
16904 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16905 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16906 if (addr1 != XEXP (operands[1], 0))
16907 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16908 if (addr2 != XEXP (operands[2], 0))
16909 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16911 count = operands[3];
16912 countreg = ix86_zero_extend_to_Pmode (count);
16914 /* %%% Iff we are testing strict equality, we can use known alignment
16915 to good advantage. This may be possible with combine, particularly
16916 once cc0 is dead. */
16917 align = operands[4];
16919 if (CONST_INT_P (count))
16921 if (INTVAL (count) == 0)
16923 emit_move_insn (operands[0], const0_rtx);
16926 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16927 operands[1], operands[2]));
16931 rtx (*gen_cmp) (rtx, rtx);
16933 gen_cmp = (TARGET_64BIT
16934 ? gen_cmpdi_1 : gen_cmpsi_1);
16936 emit_insn (gen_cmp (countreg, countreg));
16937 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16938 operands[1], operands[2]));
16941 outlow = gen_lowpart (QImode, out);
16942 emit_insn (gen_cmpintqi (outlow));
16943 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16945 if (operands[0] != out)
16946 emit_move_insn (operands[0], out);
16951 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16953 (define_expand "cmpintqi"
16954 [(set (match_dup 1)
16955 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16957 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16958 (parallel [(set (match_operand:QI 0 "register_operand")
16959 (minus:QI (match_dup 1)
16961 (clobber (reg:CC FLAGS_REG))])]
16964 operands[1] = gen_reg_rtx (QImode);
16965 operands[2] = gen_reg_rtx (QImode);
16968 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16969 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16971 (define_expand "cmpstrnqi_nz_1"
16972 [(parallel [(set (reg:CC FLAGS_REG)
16973 (compare:CC (match_operand 4 "memory_operand")
16974 (match_operand 5 "memory_operand")))
16975 (use (match_operand 2 "register_operand"))
16976 (use (match_operand:SI 3 "immediate_operand"))
16977 (clobber (match_operand 0 "register_operand"))
16978 (clobber (match_operand 1 "register_operand"))
16979 (clobber (match_dup 2))])]
16983 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16986 (define_insn "*cmpstrnqi_nz_1"
16987 [(set (reg:CC FLAGS_REG)
16988 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16989 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16990 (use (match_operand:P 6 "register_operand" "2"))
16991 (use (match_operand:SI 3 "immediate_operand" "i"))
16992 (clobber (match_operand:P 0 "register_operand" "=S"))
16993 (clobber (match_operand:P 1 "register_operand" "=D"))
16994 (clobber (match_operand:P 2 "register_operand" "=c"))]
16995 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16996 && ix86_check_no_addr_space (insn)"
16998 [(set_attr "type" "str")
16999 (set_attr "mode" "QI")
17000 (set (attr "prefix_rex")
17002 (match_test "<P:MODE>mode == DImode")
17004 (const_string "*")))
17005 (set_attr "prefix_rep" "1")])
17007 ;; The same, but the count is not known to not be zero.
17009 (define_expand "cmpstrnqi_1"
17010 [(parallel [(set (reg:CC FLAGS_REG)
17011 (if_then_else:CC (ne (match_operand 2 "register_operand")
17013 (compare:CC (match_operand 4 "memory_operand")
17014 (match_operand 5 "memory_operand"))
17016 (use (match_operand:SI 3 "immediate_operand"))
17017 (use (reg:CC FLAGS_REG))
17018 (clobber (match_operand 0 "register_operand"))
17019 (clobber (match_operand 1 "register_operand"))
17020 (clobber (match_dup 2))])]
17024 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17027 (define_insn "*cmpstrnqi_1"
17028 [(set (reg:CC FLAGS_REG)
17029 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
17031 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17032 (mem:BLK (match_operand:P 5 "register_operand" "1")))
17034 (use (match_operand:SI 3 "immediate_operand" "i"))
17035 (use (reg:CC FLAGS_REG))
17036 (clobber (match_operand:P 0 "register_operand" "=S"))
17037 (clobber (match_operand:P 1 "register_operand" "=D"))
17038 (clobber (match_operand:P 2 "register_operand" "=c"))]
17039 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17040 && ix86_check_no_addr_space (insn)"
17042 [(set_attr "type" "str")
17043 (set_attr "mode" "QI")
17044 (set (attr "prefix_rex")
17046 (match_test "<P:MODE>mode == DImode")
17048 (const_string "*")))
17049 (set_attr "prefix_rep" "1")])
17051 (define_expand "strlen<mode>"
17052 [(set (match_operand:P 0 "register_operand")
17053 (unspec:P [(match_operand:BLK 1 "general_operand")
17054 (match_operand:QI 2 "immediate_operand")
17055 (match_operand 3 "immediate_operand")]
17059 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17065 (define_expand "strlenqi_1"
17066 [(parallel [(set (match_operand 0 "register_operand")
17068 (clobber (match_operand 1 "register_operand"))
17069 (clobber (reg:CC FLAGS_REG))])]
17073 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17076 (define_insn "*strlenqi_1"
17077 [(set (match_operand:P 0 "register_operand" "=&c")
17078 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
17079 (match_operand:QI 2 "register_operand" "a")
17080 (match_operand:P 3 "immediate_operand" "i")
17081 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
17082 (clobber (match_operand:P 1 "register_operand" "=D"))
17083 (clobber (reg:CC FLAGS_REG))]
17084 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17085 && ix86_check_no_addr_space (insn)"
17086 "%^repnz{%;} scasb"
17087 [(set_attr "type" "str")
17088 (set_attr "mode" "QI")
17089 (set (attr "prefix_rex")
17091 (match_test "<P:MODE>mode == DImode")
17093 (const_string "*")))
17094 (set_attr "prefix_rep" "1")])
17096 ;; Peephole optimizations to clean up after cmpstrn*. This should be
17097 ;; handled in combine, but it is not currently up to the task.
17098 ;; When used for their truth value, the cmpstrn* expanders generate
17107 ;; The intermediate three instructions are unnecessary.
17109 ;; This one handles cmpstrn*_nz_1...
17112 (set (reg:CC FLAGS_REG)
17113 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17114 (mem:BLK (match_operand 5 "register_operand"))))
17115 (use (match_operand 6 "register_operand"))
17116 (use (match_operand:SI 3 "immediate_operand"))
17117 (clobber (match_operand 0 "register_operand"))
17118 (clobber (match_operand 1 "register_operand"))
17119 (clobber (match_operand 2 "register_operand"))])
17120 (set (match_operand:QI 7 "register_operand")
17121 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17122 (set (match_operand:QI 8 "register_operand")
17123 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17124 (set (reg FLAGS_REG)
17125 (compare (match_dup 7) (match_dup 8)))
17127 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17129 (set (reg:CC FLAGS_REG)
17130 (compare:CC (mem:BLK (match_dup 4))
17131 (mem:BLK (match_dup 5))))
17132 (use (match_dup 6))
17133 (use (match_dup 3))
17134 (clobber (match_dup 0))
17135 (clobber (match_dup 1))
17136 (clobber (match_dup 2))])])
17138 ;; ...and this one handles cmpstrn*_1.
17141 (set (reg:CC FLAGS_REG)
17142 (if_then_else:CC (ne (match_operand 6 "register_operand")
17144 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17145 (mem:BLK (match_operand 5 "register_operand")))
17147 (use (match_operand:SI 3 "immediate_operand"))
17148 (use (reg:CC FLAGS_REG))
17149 (clobber (match_operand 0 "register_operand"))
17150 (clobber (match_operand 1 "register_operand"))
17151 (clobber (match_operand 2 "register_operand"))])
17152 (set (match_operand:QI 7 "register_operand")
17153 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17154 (set (match_operand:QI 8 "register_operand")
17155 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17156 (set (reg FLAGS_REG)
17157 (compare (match_dup 7) (match_dup 8)))
17159 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17161 (set (reg:CC FLAGS_REG)
17162 (if_then_else:CC (ne (match_dup 6)
17164 (compare:CC (mem:BLK (match_dup 4))
17165 (mem:BLK (match_dup 5)))
17167 (use (match_dup 3))
17168 (use (reg:CC FLAGS_REG))
17169 (clobber (match_dup 0))
17170 (clobber (match_dup 1))
17171 (clobber (match_dup 2))])])
17173 ;; Conditional move instructions.
17175 (define_expand "mov<mode>cc"
17176 [(set (match_operand:SWIM 0 "register_operand")
17177 (if_then_else:SWIM (match_operand 1 "comparison_operator")
17178 (match_operand:SWIM 2 "<general_operand>")
17179 (match_operand:SWIM 3 "<general_operand>")))]
17181 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
17183 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17184 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17185 ;; So just document what we're doing explicitly.
17187 (define_expand "x86_mov<mode>cc_0_m1"
17189 [(set (match_operand:SWI48 0 "register_operand")
17190 (if_then_else:SWI48
17191 (match_operator:SWI48 2 "ix86_carry_flag_operator"
17192 [(match_operand 1 "flags_reg_operand")
17196 (clobber (reg:CC FLAGS_REG))])])
17198 (define_insn "*x86_mov<mode>cc_0_m1"
17199 [(set (match_operand:SWI48 0 "register_operand" "=r")
17200 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17201 [(reg FLAGS_REG) (const_int 0)])
17204 (clobber (reg:CC FLAGS_REG))]
17206 "sbb{<imodesuffix>}\t%0, %0"
17207 ; Since we don't have the proper number of operands for an alu insn,
17208 ; fill in all the blanks.
17209 [(set_attr "type" "alu")
17210 (set_attr "modrm_class" "op0")
17211 (set_attr "use_carry" "1")
17212 (set_attr "pent_pair" "pu")
17213 (set_attr "memory" "none")
17214 (set_attr "imm_disp" "false")
17215 (set_attr "mode" "<MODE>")
17216 (set_attr "length_immediate" "0")])
17218 (define_insn "*x86_mov<mode>cc_0_m1_se"
17219 [(set (match_operand:SWI48 0 "register_operand" "=r")
17220 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17221 [(reg FLAGS_REG) (const_int 0)])
17224 (clobber (reg:CC FLAGS_REG))]
17226 "sbb{<imodesuffix>}\t%0, %0"
17227 [(set_attr "type" "alu")
17228 (set_attr "modrm_class" "op0")
17229 (set_attr "use_carry" "1")
17230 (set_attr "pent_pair" "pu")
17231 (set_attr "memory" "none")
17232 (set_attr "imm_disp" "false")
17233 (set_attr "mode" "<MODE>")
17234 (set_attr "length_immediate" "0")])
17236 (define_insn "*x86_mov<mode>cc_0_m1_neg"
17237 [(set (match_operand:SWI48 0 "register_operand" "=r")
17238 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17239 [(reg FLAGS_REG) (const_int 0)])))
17240 (clobber (reg:CC FLAGS_REG))]
17242 "sbb{<imodesuffix>}\t%0, %0"
17243 [(set_attr "type" "alu")
17244 (set_attr "modrm_class" "op0")
17245 (set_attr "use_carry" "1")
17246 (set_attr "pent_pair" "pu")
17247 (set_attr "memory" "none")
17248 (set_attr "imm_disp" "false")
17249 (set_attr "mode" "<MODE>")
17250 (set_attr "length_immediate" "0")])
17252 (define_insn "*mov<mode>cc_noc"
17253 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
17254 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17255 [(reg FLAGS_REG) (const_int 0)])
17256 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
17257 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
17258 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17260 cmov%O2%C1\t{%2, %0|%0, %2}
17261 cmov%O2%c1\t{%3, %0|%0, %3}"
17262 [(set_attr "type" "icmov")
17263 (set_attr "mode" "<MODE>")])
17265 (define_insn "*movsicc_noc_zext"
17266 [(set (match_operand:DI 0 "register_operand" "=r,r")
17267 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17268 [(reg FLAGS_REG) (const_int 0)])
17270 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
17272 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
17274 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17276 cmov%O2%C1\t{%2, %k0|%k0, %2}
17277 cmov%O2%c1\t{%3, %k0|%k0, %3}"
17278 [(set_attr "type" "icmov")
17279 (set_attr "mode" "SI")])
17281 ;; Don't do conditional moves with memory inputs. This splitter helps
17282 ;; register starved x86_32 by forcing inputs into registers before reload.
17284 [(set (match_operand:SWI248 0 "register_operand")
17285 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17286 [(reg FLAGS_REG) (const_int 0)])
17287 (match_operand:SWI248 2 "nonimmediate_operand")
17288 (match_operand:SWI248 3 "nonimmediate_operand")))]
17289 "!TARGET_64BIT && TARGET_CMOVE
17290 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17291 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17292 && can_create_pseudo_p ()
17293 && optimize_insn_for_speed_p ()"
17294 [(set (match_dup 0)
17295 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17297 if (MEM_P (operands[2]))
17298 operands[2] = force_reg (<MODE>mode, operands[2]);
17299 if (MEM_P (operands[3]))
17300 operands[3] = force_reg (<MODE>mode, operands[3]);
17303 (define_insn "*movqicc_noc"
17304 [(set (match_operand:QI 0 "register_operand" "=r,r")
17305 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17306 [(reg FLAGS_REG) (const_int 0)])
17307 (match_operand:QI 2 "register_operand" "r,0")
17308 (match_operand:QI 3 "register_operand" "0,r")))]
17309 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17311 [(set_attr "type" "icmov")
17312 (set_attr "mode" "QI")])
17315 [(set (match_operand:SWI12 0 "register_operand")
17316 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
17317 [(reg FLAGS_REG) (const_int 0)])
17318 (match_operand:SWI12 2 "register_operand")
17319 (match_operand:SWI12 3 "register_operand")))]
17320 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
17321 && reload_completed"
17322 [(set (match_dup 0)
17323 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17325 operands[0] = gen_lowpart (SImode, operands[0]);
17326 operands[2] = gen_lowpart (SImode, operands[2]);
17327 operands[3] = gen_lowpart (SImode, operands[3]);
17330 ;; Don't do conditional moves with memory inputs
17332 [(match_scratch:SWI248 4 "r")
17333 (set (match_operand:SWI248 0 "register_operand")
17334 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17335 [(reg FLAGS_REG) (const_int 0)])
17336 (match_operand:SWI248 2 "nonimmediate_operand")
17337 (match_operand:SWI248 3 "nonimmediate_operand")))]
17338 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17339 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17340 && optimize_insn_for_speed_p ()"
17341 [(set (match_dup 4) (match_dup 5))
17343 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17345 if (MEM_P (operands[2]))
17347 operands[5] = operands[2];
17348 operands[2] = operands[4];
17350 else if (MEM_P (operands[3]))
17352 operands[5] = operands[3];
17353 operands[3] = operands[4];
17356 gcc_unreachable ();
17360 [(match_scratch:SI 4 "r")
17361 (set (match_operand:DI 0 "register_operand")
17362 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17363 [(reg FLAGS_REG) (const_int 0)])
17365 (match_operand:SI 2 "nonimmediate_operand"))
17367 (match_operand:SI 3 "nonimmediate_operand"))))]
17369 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17370 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17371 && optimize_insn_for_speed_p ()"
17372 [(set (match_dup 4) (match_dup 5))
17374 (if_then_else:DI (match_dup 1)
17375 (zero_extend:DI (match_dup 2))
17376 (zero_extend:DI (match_dup 3))))]
17378 if (MEM_P (operands[2]))
17380 operands[5] = operands[2];
17381 operands[2] = operands[4];
17383 else if (MEM_P (operands[3]))
17385 operands[5] = operands[3];
17386 operands[3] = operands[4];
17389 gcc_unreachable ();
17392 (define_expand "mov<mode>cc"
17393 [(set (match_operand:X87MODEF 0 "register_operand")
17394 (if_then_else:X87MODEF
17395 (match_operand 1 "comparison_operator")
17396 (match_operand:X87MODEF 2 "register_operand")
17397 (match_operand:X87MODEF 3 "register_operand")))]
17398 "(TARGET_80387 && TARGET_CMOVE)
17399 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17400 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
17402 (define_insn "*movxfcc_1"
17403 [(set (match_operand:XF 0 "register_operand" "=f,f")
17404 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17405 [(reg FLAGS_REG) (const_int 0)])
17406 (match_operand:XF 2 "register_operand" "f,0")
17407 (match_operand:XF 3 "register_operand" "0,f")))]
17408 "TARGET_80387 && TARGET_CMOVE"
17410 fcmov%F1\t{%2, %0|%0, %2}
17411 fcmov%f1\t{%3, %0|%0, %3}"
17412 [(set_attr "type" "fcmov")
17413 (set_attr "mode" "XF")])
17415 (define_insn "*movdfcc_1"
17416 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
17417 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17418 [(reg FLAGS_REG) (const_int 0)])
17419 (match_operand:DF 2 "nonimmediate_operand"
17421 (match_operand:DF 3 "nonimmediate_operand"
17422 "0 ,f,0 ,rm,0, rm")))]
17423 "TARGET_80387 && TARGET_CMOVE
17424 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17426 fcmov%F1\t{%2, %0|%0, %2}
17427 fcmov%f1\t{%3, %0|%0, %3}
17430 cmov%O2%C1\t{%2, %0|%0, %2}
17431 cmov%O2%c1\t{%3, %0|%0, %3}"
17432 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
17433 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
17434 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
17437 [(set (match_operand:DF 0 "general_reg_operand")
17438 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17439 [(reg FLAGS_REG) (const_int 0)])
17440 (match_operand:DF 2 "nonimmediate_operand")
17441 (match_operand:DF 3 "nonimmediate_operand")))]
17442 "!TARGET_64BIT && reload_completed"
17443 [(set (match_dup 2)
17444 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
17446 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
17448 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
17449 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
17452 (define_insn "*movsfcc_1_387"
17453 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
17454 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17455 [(reg FLAGS_REG) (const_int 0)])
17456 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
17457 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
17458 "TARGET_80387 && TARGET_CMOVE
17459 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17461 fcmov%F1\t{%2, %0|%0, %2}
17462 fcmov%f1\t{%3, %0|%0, %3}
17463 cmov%O2%C1\t{%2, %0|%0, %2}
17464 cmov%O2%c1\t{%3, %0|%0, %3}"
17465 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17466 (set_attr "mode" "SF,SF,SI,SI")])
17468 ;; Don't do conditional moves with memory inputs. This splitter helps
17469 ;; register starved x86_32 by forcing inputs into registers before reload.
17471 [(set (match_operand:MODEF 0 "register_operand")
17472 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
17473 [(reg FLAGS_REG) (const_int 0)])
17474 (match_operand:MODEF 2 "nonimmediate_operand")
17475 (match_operand:MODEF 3 "nonimmediate_operand")))]
17476 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17477 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17478 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17479 && can_create_pseudo_p ()
17480 && optimize_insn_for_speed_p ()"
17481 [(set (match_dup 0)
17482 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17484 if (MEM_P (operands[2]))
17485 operands[2] = force_reg (<MODE>mode, operands[2]);
17486 if (MEM_P (operands[3]))
17487 operands[3] = force_reg (<MODE>mode, operands[3]);
17490 ;; Don't do conditional moves with memory inputs
17492 [(match_scratch:MODEF 4 "r")
17493 (set (match_operand:MODEF 0 "general_reg_operand")
17494 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
17495 [(reg FLAGS_REG) (const_int 0)])
17496 (match_operand:MODEF 2 "nonimmediate_operand")
17497 (match_operand:MODEF 3 "nonimmediate_operand")))]
17498 "(<MODE>mode != DFmode || TARGET_64BIT)
17499 && TARGET_80387 && TARGET_CMOVE
17500 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17501 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17502 && optimize_insn_for_speed_p ()"
17503 [(set (match_dup 4) (match_dup 5))
17505 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17507 if (MEM_P (operands[2]))
17509 operands[5] = operands[2];
17510 operands[2] = operands[4];
17512 else if (MEM_P (operands[3]))
17514 operands[5] = operands[3];
17515 operands[3] = operands[4];
17518 gcc_unreachable ();
17521 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
17522 ;; the scalar versions to have only XMM registers as operands.
17524 ;; XOP conditional move
17525 (define_insn "*xop_pcmov_<mode>"
17526 [(set (match_operand:MODEF 0 "register_operand" "=x")
17527 (if_then_else:MODEF
17528 (match_operand:MODEF 1 "register_operand" "x")
17529 (match_operand:MODEF 2 "register_operand" "x")
17530 (match_operand:MODEF 3 "register_operand" "x")))]
17532 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
17533 [(set_attr "type" "sse4arg")])
17535 ;; These versions of the min/max patterns are intentionally ignorant of
17536 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17537 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17538 ;; are undefined in this condition, we're certain this is correct.
17540 (define_insn "<code><mode>3"
17541 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17543 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
17544 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
17545 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17547 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
17548 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17549 [(set_attr "isa" "noavx,avx")
17550 (set_attr "prefix" "orig,vex")
17551 (set_attr "type" "sseadd")
17552 (set_attr "mode" "<MODE>")])
17554 ;; These versions of the min/max patterns implement exactly the operations
17555 ;; min = (op1 < op2 ? op1 : op2)
17556 ;; max = (!(op1 < op2) ? op1 : op2)
17557 ;; Their operands are not commutative, and thus they may be used in the
17558 ;; presence of -0.0 and NaN.
17560 (define_insn "*ieee_s<ieee_maxmin><mode>3"
17561 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17563 [(match_operand:MODEF 1 "register_operand" "0,v")
17564 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
17566 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17568 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
17569 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17570 [(set_attr "isa" "noavx,avx")
17571 (set_attr "prefix" "orig,maybe_evex")
17572 (set_attr "type" "sseadd")
17573 (set_attr "mode" "<MODE>")])
17575 ;; Make two stack loads independent:
17577 ;; fld %st(0) -> fld bb
17578 ;; fmul bb fmul %st(1), %st
17580 ;; Actually we only match the last two instructions for simplicity.
17583 [(set (match_operand 0 "fp_register_operand")
17584 (match_operand 1 "fp_register_operand"))
17586 (match_operator 2 "binary_fp_operator"
17588 (match_operand 3 "memory_operand")]))]
17589 "REGNO (operands[0]) != REGNO (operands[1])"
17590 [(set (match_dup 0) (match_dup 3))
17593 [(match_dup 5) (match_dup 4)]))]
17595 operands[4] = operands[0];
17596 operands[5] = operands[1];
17598 /* The % modifier is not operational anymore in peephole2's, so we have to
17599 swap the operands manually in the case of addition and multiplication. */
17600 if (COMMUTATIVE_ARITH_P (operands[2]))
17601 std::swap (operands[4], operands[5]);
17605 [(set (match_operand 0 "fp_register_operand")
17606 (match_operand 1 "fp_register_operand"))
17608 (match_operator 2 "binary_fp_operator"
17609 [(match_operand 3 "memory_operand")
17611 "REGNO (operands[0]) != REGNO (operands[1])"
17612 [(set (match_dup 0) (match_dup 3))
17615 [(match_dup 4) (match_dup 5)]))]
17617 operands[4] = operands[0];
17618 operands[5] = operands[1];
17620 /* The % modifier is not operational anymore in peephole2's, so we have to
17621 swap the operands manually in the case of addition and multiplication. */
17622 if (COMMUTATIVE_ARITH_P (operands[2]))
17623 std::swap (operands[4], operands[5]);
17626 ;; Conditional addition patterns
17627 (define_expand "add<mode>cc"
17628 [(match_operand:SWI 0 "register_operand")
17629 (match_operand 1 "ordered_comparison_operator")
17630 (match_operand:SWI 2 "register_operand")
17631 (match_operand:SWI 3 "const_int_operand")]
17633 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17635 ;; Misc patterns (?)
17637 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17638 ;; Otherwise there will be nothing to keep
17640 ;; [(set (reg ebp) (reg esp))]
17641 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17642 ;; (clobber (eflags)]
17643 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17645 ;; in proper program order.
17647 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
17648 [(set (match_operand:P 0 "register_operand" "=r,r")
17649 (plus:P (match_operand:P 1 "register_operand" "0,r")
17650 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17651 (clobber (reg:CC FLAGS_REG))
17652 (clobber (mem:BLK (scratch)))]
17655 switch (get_attr_type (insn))
17658 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17661 gcc_assert (rtx_equal_p (operands[0], operands[1]));
17662 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17663 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17665 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17668 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17669 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17672 [(set (attr "type")
17673 (cond [(and (eq_attr "alternative" "0")
17674 (not (match_test "TARGET_OPT_AGU")))
17675 (const_string "alu")
17676 (match_operand:<MODE> 2 "const0_operand")
17677 (const_string "imov")
17679 (const_string "lea")))
17680 (set (attr "length_immediate")
17681 (cond [(eq_attr "type" "imov")
17683 (and (eq_attr "type" "alu")
17684 (match_operand 2 "const128_operand"))
17687 (const_string "*")))
17688 (set_attr "mode" "<MODE>")])
17690 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
17691 [(set (match_operand:P 0 "register_operand" "=r")
17692 (minus:P (match_operand:P 1 "register_operand" "0")
17693 (match_operand:P 2 "register_operand" "r")))
17694 (clobber (reg:CC FLAGS_REG))
17695 (clobber (mem:BLK (scratch)))]
17697 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17698 [(set_attr "type" "alu")
17699 (set_attr "mode" "<MODE>")])
17701 (define_insn "allocate_stack_worker_probe_<mode>"
17702 [(set (match_operand:P 0 "register_operand" "=a")
17703 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17704 UNSPECV_STACK_PROBE))
17705 (clobber (reg:CC FLAGS_REG))]
17706 "ix86_target_stack_probe ()"
17707 "call\t___chkstk_ms"
17708 [(set_attr "type" "multi")
17709 (set_attr "length" "5")])
17711 (define_expand "allocate_stack"
17712 [(match_operand 0 "register_operand")
17713 (match_operand 1 "general_operand")]
17714 "ix86_target_stack_probe ()"
17718 #ifndef CHECK_STACK_LIMIT
17719 #define CHECK_STACK_LIMIT 0
17722 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17723 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17727 rtx (*insn) (rtx, rtx);
17729 x = copy_to_mode_reg (Pmode, operands[1]);
17731 insn = (TARGET_64BIT
17732 ? gen_allocate_stack_worker_probe_di
17733 : gen_allocate_stack_worker_probe_si);
17735 emit_insn (insn (x, x));
17738 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17739 stack_pointer_rtx, 0, OPTAB_DIRECT);
17741 if (x != stack_pointer_rtx)
17742 emit_move_insn (stack_pointer_rtx, x);
17744 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17748 (define_expand "probe_stack"
17749 [(match_operand 0 "memory_operand")]
17752 rtx (*insn) (rtx, rtx)
17753 = (GET_MODE (operands[0]) == DImode
17754 ? gen_probe_stack_di : gen_probe_stack_si);
17756 emit_insn (insn (operands[0], const0_rtx));
17760 ;; Use OR for stack probes, this is shorter.
17761 (define_insn "probe_stack_<mode>"
17762 [(set (match_operand:W 0 "memory_operand" "=m")
17763 (unspec:W [(match_operand:W 1 "const0_operand")]
17764 UNSPEC_PROBE_STACK))
17765 (clobber (reg:CC FLAGS_REG))]
17767 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
17768 [(set_attr "type" "alu1")
17769 (set_attr "mode" "<MODE>")
17770 (set_attr "length_immediate" "1")])
17772 (define_insn "adjust_stack_and_probe<mode>"
17773 [(set (match_operand:P 0 "register_operand" "=r")
17774 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17775 UNSPECV_PROBE_STACK_RANGE))
17776 (set (reg:P SP_REG)
17777 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17778 (clobber (reg:CC FLAGS_REG))
17779 (clobber (mem:BLK (scratch)))]
17781 "* return output_adjust_stack_and_probe (operands[0]);"
17782 [(set_attr "type" "multi")])
17784 (define_insn "probe_stack_range<mode>"
17785 [(set (match_operand:P 0 "register_operand" "=r")
17786 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17787 (match_operand:P 2 "const_int_operand" "n")]
17788 UNSPECV_PROBE_STACK_RANGE))
17789 (clobber (reg:CC FLAGS_REG))]
17791 "* return output_probe_stack_range (operands[0], operands[2]);"
17792 [(set_attr "type" "multi")])
17794 (define_expand "builtin_setjmp_receiver"
17795 [(label_ref (match_operand 0))]
17796 "!TARGET_64BIT && flag_pic"
17802 rtx_code_label *label_rtx = gen_label_rtx ();
17803 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17804 xops[0] = xops[1] = pic_offset_table_rtx;
17805 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17806 ix86_expand_binary_operator (MINUS, SImode, xops);
17810 emit_insn (gen_set_got (pic_offset_table_rtx));
17814 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17815 ;; Do not split instructions with mask registers.
17817 [(set (match_operand 0 "general_reg_operand")
17818 (match_operator 3 "promotable_binary_operator"
17819 [(match_operand 1 "general_reg_operand")
17820 (match_operand 2 "aligned_operand")]))
17821 (clobber (reg:CC FLAGS_REG))]
17822 "! TARGET_PARTIAL_REG_STALL && reload_completed
17823 && ((GET_MODE (operands[0]) == HImode
17824 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17825 /* ??? next two lines just !satisfies_constraint_K (...) */
17826 || !CONST_INT_P (operands[2])
17827 || satisfies_constraint_K (operands[2])))
17828 || (GET_MODE (operands[0]) == QImode
17829 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17830 [(parallel [(set (match_dup 0)
17831 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17832 (clobber (reg:CC FLAGS_REG))])]
17834 operands[0] = gen_lowpart (SImode, operands[0]);
17835 operands[1] = gen_lowpart (SImode, operands[1]);
17836 if (GET_CODE (operands[3]) != ASHIFT)
17837 operands[2] = gen_lowpart (SImode, operands[2]);
17838 operands[3] = shallow_copy_rtx (operands[3]);
17839 PUT_MODE (operands[3], SImode);
17842 ; Promote the QImode tests, as i386 has encoding of the AND
17843 ; instruction with 32-bit sign-extended immediate and thus the
17844 ; instruction size is unchanged, except in the %eax case for
17845 ; which it is increased by one byte, hence the ! optimize_size.
17847 [(set (match_operand 0 "flags_reg_operand")
17848 (match_operator 2 "compare_operator"
17849 [(and (match_operand 3 "aligned_operand")
17850 (match_operand 4 "const_int_operand"))
17852 (set (match_operand 1 "register_operand")
17853 (and (match_dup 3) (match_dup 4)))]
17854 "! TARGET_PARTIAL_REG_STALL && reload_completed
17855 && optimize_insn_for_speed_p ()
17856 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17857 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17858 /* Ensure that the operand will remain sign-extended immediate. */
17859 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17860 [(parallel [(set (match_dup 0)
17861 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17864 (and:SI (match_dup 3) (match_dup 4)))])]
17867 = gen_int_mode (INTVAL (operands[4])
17868 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17869 operands[1] = gen_lowpart (SImode, operands[1]);
17870 operands[3] = gen_lowpart (SImode, operands[3]);
17873 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17874 ; the TEST instruction with 32-bit sign-extended immediate and thus
17875 ; the instruction size would at least double, which is not what we
17876 ; want even with ! optimize_size.
17878 [(set (match_operand 0 "flags_reg_operand")
17879 (match_operator 1 "compare_operator"
17880 [(and (match_operand:HI 2 "aligned_operand")
17881 (match_operand:HI 3 "const_int_operand"))
17883 "! TARGET_PARTIAL_REG_STALL && reload_completed
17884 && ! TARGET_FAST_PREFIX
17885 && optimize_insn_for_speed_p ()
17886 /* Ensure that the operand will remain sign-extended immediate. */
17887 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17888 [(set (match_dup 0)
17889 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17893 = gen_int_mode (INTVAL (operands[3])
17894 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17895 operands[2] = gen_lowpart (SImode, operands[2]);
17899 [(set (match_operand 0 "register_operand")
17900 (neg (match_operand 1 "register_operand")))
17901 (clobber (reg:CC FLAGS_REG))]
17902 "! TARGET_PARTIAL_REG_STALL && reload_completed
17903 && (GET_MODE (operands[0]) == HImode
17904 || (GET_MODE (operands[0]) == QImode
17905 && (TARGET_PROMOTE_QImode
17906 || optimize_insn_for_size_p ())))"
17907 [(parallel [(set (match_dup 0)
17908 (neg:SI (match_dup 1)))
17909 (clobber (reg:CC FLAGS_REG))])]
17911 operands[0] = gen_lowpart (SImode, operands[0]);
17912 operands[1] = gen_lowpart (SImode, operands[1]);
17915 ;; Do not split instructions with mask regs.
17917 [(set (match_operand 0 "general_reg_operand")
17918 (not (match_operand 1 "general_reg_operand")))]
17919 "! TARGET_PARTIAL_REG_STALL && reload_completed
17920 && (GET_MODE (operands[0]) == HImode
17921 || (GET_MODE (operands[0]) == QImode
17922 && (TARGET_PROMOTE_QImode
17923 || optimize_insn_for_size_p ())))"
17924 [(set (match_dup 0)
17925 (not:SI (match_dup 1)))]
17927 operands[0] = gen_lowpart (SImode, operands[0]);
17928 operands[1] = gen_lowpart (SImode, operands[1]);
17931 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17932 ;; transform a complex memory operation into two memory to register operations.
17934 ;; Don't push memory operands
17936 [(set (match_operand:SWI 0 "push_operand")
17937 (match_operand:SWI 1 "memory_operand"))
17938 (match_scratch:SWI 2 "<r>")]
17939 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17940 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17941 [(set (match_dup 2) (match_dup 1))
17942 (set (match_dup 0) (match_dup 2))])
17944 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17947 [(set (match_operand:SF 0 "push_operand")
17948 (match_operand:SF 1 "memory_operand"))
17949 (match_scratch:SF 2 "r")]
17950 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17951 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17952 [(set (match_dup 2) (match_dup 1))
17953 (set (match_dup 0) (match_dup 2))])
17955 ;; Don't move an immediate directly to memory when the instruction
17956 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17958 [(match_scratch:SWI124 1 "<r>")
17959 (set (match_operand:SWI124 0 "memory_operand")
17961 "optimize_insn_for_speed_p ()
17962 && ((<MODE>mode == HImode
17963 && TARGET_LCP_STALL)
17964 || (!TARGET_USE_MOV0
17965 && TARGET_SPLIT_LONG_MOVES
17966 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17967 && peep2_regno_dead_p (0, FLAGS_REG)"
17968 [(parallel [(set (match_dup 2) (const_int 0))
17969 (clobber (reg:CC FLAGS_REG))])
17970 (set (match_dup 0) (match_dup 1))]
17971 "operands[2] = gen_lowpart (SImode, operands[1]);")
17974 [(match_scratch:SWI124 2 "<r>")
17975 (set (match_operand:SWI124 0 "memory_operand")
17976 (match_operand:SWI124 1 "immediate_operand"))]
17977 "optimize_insn_for_speed_p ()
17978 && ((<MODE>mode == HImode
17979 && TARGET_LCP_STALL)
17980 || (TARGET_SPLIT_LONG_MOVES
17981 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17982 [(set (match_dup 2) (match_dup 1))
17983 (set (match_dup 0) (match_dup 2))])
17985 ;; Don't compare memory with zero, load and use a test instead.
17987 [(set (match_operand 0 "flags_reg_operand")
17988 (match_operator 1 "compare_operator"
17989 [(match_operand:SI 2 "memory_operand")
17991 (match_scratch:SI 3 "r")]
17992 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17993 [(set (match_dup 3) (match_dup 2))
17994 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17996 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17997 ;; Don't split NOTs with a displacement operand, because resulting XOR
17998 ;; will not be pairable anyway.
18000 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18001 ;; represented using a modRM byte. The XOR replacement is long decoded,
18002 ;; so this split helps here as well.
18004 ;; Note: Can't do this as a regular split because we can't get proper
18005 ;; lifetime information then.
18008 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
18009 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
18010 "optimize_insn_for_speed_p ()
18011 && ((TARGET_NOT_UNPAIRABLE
18012 && (!MEM_P (operands[0])
18013 || !memory_displacement_operand (operands[0], <MODE>mode)))
18014 || (TARGET_NOT_VECTORMODE
18015 && long_memory_operand (operands[0], <MODE>mode)))
18016 && peep2_regno_dead_p (0, FLAGS_REG)"
18017 [(parallel [(set (match_dup 0)
18018 (xor:SWI124 (match_dup 1) (const_int -1)))
18019 (clobber (reg:CC FLAGS_REG))])])
18021 ;; Non pairable "test imm, reg" instructions can be translated to
18022 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18023 ;; byte opcode instead of two, have a short form for byte operands),
18024 ;; so do it for other CPUs as well. Given that the value was dead,
18025 ;; this should not create any new dependencies. Pass on the sub-word
18026 ;; versions if we're concerned about partial register stalls.
18029 [(set (match_operand 0 "flags_reg_operand")
18030 (match_operator 1 "compare_operator"
18031 [(and:SI (match_operand:SI 2 "register_operand")
18032 (match_operand:SI 3 "immediate_operand"))
18034 "ix86_match_ccmode (insn, CCNOmode)
18035 && (REGNO (operands[2]) != AX_REG
18036 || satisfies_constraint_K (operands[3]))
18037 && peep2_reg_dead_p (1, operands[2])"
18039 [(set (match_dup 0)
18040 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18043 (and:SI (match_dup 2) (match_dup 3)))])])
18045 ;; We don't need to handle HImode case, because it will be promoted to SImode
18046 ;; on ! TARGET_PARTIAL_REG_STALL
18049 [(set (match_operand 0 "flags_reg_operand")
18050 (match_operator 1 "compare_operator"
18051 [(and:QI (match_operand:QI 2 "register_operand")
18052 (match_operand:QI 3 "immediate_operand"))
18054 "! TARGET_PARTIAL_REG_STALL
18055 && ix86_match_ccmode (insn, CCNOmode)
18056 && REGNO (operands[2]) != AX_REG
18057 && peep2_reg_dead_p (1, operands[2])"
18059 [(set (match_dup 0)
18060 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18063 (and:QI (match_dup 2) (match_dup 3)))])])
18066 [(set (match_operand 0 "flags_reg_operand")
18067 (match_operator 1 "compare_operator"
18070 (zero_extract:SI (match_operand 2 "QIreg_operand")
18073 (match_operand 3 "const_int_operand"))
18075 "! TARGET_PARTIAL_REG_STALL
18076 && ix86_match_ccmode (insn, CCNOmode)
18077 && REGNO (operands[2]) != AX_REG
18078 && peep2_reg_dead_p (1, operands[2])"
18080 [(set (match_dup 0)
18084 (zero_extract:SI (match_dup 2)
18089 (set (zero_extract:SI (match_dup 2)
18095 (zero_extract:SI (match_dup 2)
18098 (match_dup 3)) 0))])])
18100 ;; Don't do logical operations with memory inputs.
18102 [(match_scratch:SWI 2 "<r>")
18103 (parallel [(set (match_operand:SWI 0 "register_operand")
18104 (match_operator:SWI 3 "arith_or_logical_operator"
18106 (match_operand:SWI 1 "memory_operand")]))
18107 (clobber (reg:CC FLAGS_REG))])]
18108 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18109 [(set (match_dup 2) (match_dup 1))
18110 (parallel [(set (match_dup 0)
18111 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18112 (clobber (reg:CC FLAGS_REG))])])
18115 [(match_scratch:SWI 2 "<r>")
18116 (parallel [(set (match_operand:SWI 0 "register_operand")
18117 (match_operator:SWI 3 "arith_or_logical_operator"
18118 [(match_operand:SWI 1 "memory_operand")
18120 (clobber (reg:CC FLAGS_REG))])]
18121 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18122 [(set (match_dup 2) (match_dup 1))
18123 (parallel [(set (match_dup 0)
18124 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18125 (clobber (reg:CC FLAGS_REG))])])
18127 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
18128 ;; the memory address refers to the destination of the load!
18131 [(set (match_operand:SWI 0 "general_reg_operand")
18132 (match_operand:SWI 1 "general_reg_operand"))
18133 (parallel [(set (match_dup 0)
18134 (match_operator:SWI 3 "commutative_operator"
18136 (match_operand:SWI 2 "memory_operand")]))
18137 (clobber (reg:CC FLAGS_REG))])]
18138 "REGNO (operands[0]) != REGNO (operands[1])
18139 && (<MODE>mode != QImode
18140 || any_QIreg_operand (operands[1], QImode))"
18141 [(set (match_dup 0) (match_dup 4))
18142 (parallel [(set (match_dup 0)
18143 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
18144 (clobber (reg:CC FLAGS_REG))])]
18145 "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
18148 [(set (match_operand 0 "mmx_reg_operand")
18149 (match_operand 1 "mmx_reg_operand"))
18151 (match_operator 3 "commutative_operator"
18153 (match_operand 2 "memory_operand")]))]
18154 "REGNO (operands[0]) != REGNO (operands[1])"
18155 [(set (match_dup 0) (match_dup 2))
18157 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18160 [(set (match_operand 0 "sse_reg_operand")
18161 (match_operand 1 "sse_reg_operand"))
18163 (match_operator 3 "commutative_operator"
18165 (match_operand 2 "memory_operand")]))]
18166 "REGNO (operands[0]) != REGNO (operands[1])"
18167 [(set (match_dup 0) (match_dup 2))
18169 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18171 ; Don't do logical operations with memory outputs
18173 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18174 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
18175 ; the same decoder scheduling characteristics as the original.
18178 [(match_scratch:SWI 2 "<r>")
18179 (parallel [(set (match_operand:SWI 0 "memory_operand")
18180 (match_operator:SWI 3 "arith_or_logical_operator"
18182 (match_operand:SWI 1 "<nonmemory_operand>")]))
18183 (clobber (reg:CC FLAGS_REG))])]
18184 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18185 [(set (match_dup 2) (match_dup 0))
18186 (parallel [(set (match_dup 2)
18187 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18188 (clobber (reg:CC FLAGS_REG))])
18189 (set (match_dup 0) (match_dup 2))])
18192 [(match_scratch:SWI 2 "<r>")
18193 (parallel [(set (match_operand:SWI 0 "memory_operand")
18194 (match_operator:SWI 3 "arith_or_logical_operator"
18195 [(match_operand:SWI 1 "<nonmemory_operand>")
18197 (clobber (reg:CC FLAGS_REG))])]
18198 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18199 [(set (match_dup 2) (match_dup 0))
18200 (parallel [(set (match_dup 2)
18201 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18202 (clobber (reg:CC FLAGS_REG))])
18203 (set (match_dup 0) (match_dup 2))])
18205 ;; Attempt to use arith or logical operations with memory outputs with
18206 ;; setting of flags.
18208 [(set (match_operand:SWI 0 "register_operand")
18209 (match_operand:SWI 1 "memory_operand"))
18210 (parallel [(set (match_dup 0)
18211 (match_operator:SWI 3 "plusminuslogic_operator"
18213 (match_operand:SWI 2 "<nonmemory_operand>")]))
18214 (clobber (reg:CC FLAGS_REG))])
18215 (set (match_dup 1) (match_dup 0))
18216 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18217 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18218 && peep2_reg_dead_p (4, operands[0])
18219 && !reg_overlap_mentioned_p (operands[0], operands[1])
18220 && !reg_overlap_mentioned_p (operands[0], operands[2])
18221 && (<MODE>mode != QImode
18222 || immediate_operand (operands[2], QImode)
18223 || any_QIreg_operand (operands[2], QImode))
18224 && ix86_match_ccmode (peep2_next_insn (3),
18225 (GET_CODE (operands[3]) == PLUS
18226 || GET_CODE (operands[3]) == MINUS)
18227 ? CCGOCmode : CCNOmode)"
18228 [(parallel [(set (match_dup 4) (match_dup 6))
18229 (set (match_dup 1) (match_dup 5))])]
18231 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18233 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18234 copy_rtx (operands[1]),
18237 = gen_rtx_COMPARE (GET_MODE (operands[4]),
18238 copy_rtx (operands[5]),
18242 ;; Likewise for instances where we have a lea pattern.
18244 [(set (match_operand:SWI 0 "register_operand")
18245 (match_operand:SWI 1 "memory_operand"))
18246 (set (match_operand:SWI 3 "register_operand")
18247 (plus:SWI (match_dup 0)
18248 (match_operand:SWI 2 "<nonmemory_operand>")))
18249 (set (match_dup 1) (match_dup 3))
18250 (set (reg FLAGS_REG) (compare (match_dup 3) (const_int 0)))]
18251 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18252 && peep2_reg_dead_p (4, operands[3])
18253 && (rtx_equal_p (operands[0], operands[3])
18254 || peep2_reg_dead_p (2, operands[0]))
18255 && !reg_overlap_mentioned_p (operands[0], operands[1])
18256 && !reg_overlap_mentioned_p (operands[3], operands[1])
18257 && !reg_overlap_mentioned_p (operands[0], operands[2])
18258 && (<MODE>mode != QImode
18259 || immediate_operand (operands[2], QImode)
18260 || any_QIreg_operand (operands[2], QImode))
18261 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
18262 [(parallel [(set (match_dup 4) (match_dup 6))
18263 (set (match_dup 1) (match_dup 5))])]
18265 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18267 = gen_rtx_PLUS (<MODE>mode,
18268 copy_rtx (operands[1]),
18271 = gen_rtx_COMPARE (GET_MODE (operands[4]),
18272 copy_rtx (operands[5]),
18277 [(parallel [(set (match_operand:SWI 0 "register_operand")
18278 (match_operator:SWI 2 "plusminuslogic_operator"
18280 (match_operand:SWI 1 "memory_operand")]))
18281 (clobber (reg:CC FLAGS_REG))])
18282 (set (match_dup 1) (match_dup 0))
18283 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18284 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18285 && GET_CODE (operands[2]) != MINUS
18286 && peep2_reg_dead_p (3, operands[0])
18287 && !reg_overlap_mentioned_p (operands[0], operands[1])
18288 && ix86_match_ccmode (peep2_next_insn (2),
18289 GET_CODE (operands[2]) == PLUS
18290 ? CCGOCmode : CCNOmode)"
18291 [(parallel [(set (match_dup 3) (match_dup 5))
18292 (set (match_dup 1) (match_dup 4))])]
18294 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
18296 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18297 copy_rtx (operands[1]),
18300 = gen_rtx_COMPARE (GET_MODE (operands[3]),
18301 copy_rtx (operands[4]),
18306 [(set (match_operand:SWI12 0 "register_operand")
18307 (match_operand:SWI12 1 "memory_operand"))
18308 (parallel [(set (match_operand:SI 4 "register_operand")
18309 (match_operator:SI 3 "plusminuslogic_operator"
18311 (match_operand:SI 2 "nonmemory_operand")]))
18312 (clobber (reg:CC FLAGS_REG))])
18313 (set (match_dup 1) (match_dup 0))
18314 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18315 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18316 && REGNO (operands[0]) == REGNO (operands[4])
18317 && peep2_reg_dead_p (4, operands[0])
18318 && (<MODE>mode != QImode
18319 || immediate_operand (operands[2], SImode)
18320 || any_QIreg_operand (operands[2], SImode))
18321 && !reg_overlap_mentioned_p (operands[0], operands[1])
18322 && !reg_overlap_mentioned_p (operands[0], operands[2])
18323 && ix86_match_ccmode (peep2_next_insn (3),
18324 (GET_CODE (operands[3]) == PLUS
18325 || GET_CODE (operands[3]) == MINUS)
18326 ? CCGOCmode : CCNOmode)"
18327 [(parallel [(set (match_dup 4) (match_dup 6))
18328 (set (match_dup 1) (match_dup 5))])]
18330 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18332 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18333 copy_rtx (operands[1]),
18334 gen_lowpart (<MODE>mode, operands[2]));
18336 = gen_rtx_COMPARE (GET_MODE (operands[4]),
18337 copy_rtx (operands[5]),
18341 ;; Attempt to always use XOR for zeroing registers (including FP modes).
18343 [(set (match_operand 0 "general_reg_operand")
18344 (match_operand 1 "const0_operand"))]
18345 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18346 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18347 && peep2_regno_dead_p (0, FLAGS_REG)"
18348 [(parallel [(set (match_dup 0) (const_int 0))
18349 (clobber (reg:CC FLAGS_REG))])]
18350 "operands[0] = gen_lowpart (word_mode, operands[0]);")
18353 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
18355 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18356 && peep2_regno_dead_p (0, FLAGS_REG)"
18357 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18358 (clobber (reg:CC FLAGS_REG))])])
18360 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
18362 [(set (match_operand:SWI248 0 "general_reg_operand")
18364 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
18365 && peep2_regno_dead_p (0, FLAGS_REG)"
18366 [(parallel [(set (match_dup 0) (const_int -1))
18367 (clobber (reg:CC FLAGS_REG))])]
18369 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
18370 operands[0] = gen_lowpart (SImode, operands[0]);
18373 ;; Attempt to convert simple lea to add/shift.
18374 ;; These can be created by move expanders.
18375 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
18376 ;; relevant lea instructions were already split.
18379 [(set (match_operand:SWI48 0 "register_operand")
18380 (plus:SWI48 (match_dup 0)
18381 (match_operand:SWI48 1 "<nonmemory_operand>")))]
18383 && peep2_regno_dead_p (0, FLAGS_REG)"
18384 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18385 (clobber (reg:CC FLAGS_REG))])])
18388 [(set (match_operand:SWI48 0 "register_operand")
18389 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
18392 && peep2_regno_dead_p (0, FLAGS_REG)"
18393 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18394 (clobber (reg:CC FLAGS_REG))])])
18397 [(set (match_operand:DI 0 "register_operand")
18399 (plus:SI (match_operand:SI 1 "register_operand")
18400 (match_operand:SI 2 "nonmemory_operand"))))]
18401 "TARGET_64BIT && !TARGET_OPT_AGU
18402 && REGNO (operands[0]) == REGNO (operands[1])
18403 && peep2_regno_dead_p (0, FLAGS_REG)"
18404 [(parallel [(set (match_dup 0)
18405 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
18406 (clobber (reg:CC FLAGS_REG))])])
18409 [(set (match_operand:DI 0 "register_operand")
18411 (plus:SI (match_operand:SI 1 "nonmemory_operand")
18412 (match_operand:SI 2 "register_operand"))))]
18413 "TARGET_64BIT && !TARGET_OPT_AGU
18414 && REGNO (operands[0]) == REGNO (operands[2])
18415 && peep2_regno_dead_p (0, FLAGS_REG)"
18416 [(parallel [(set (match_dup 0)
18417 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
18418 (clobber (reg:CC FLAGS_REG))])])
18421 [(set (match_operand:SWI48 0 "register_operand")
18422 (mult:SWI48 (match_dup 0)
18423 (match_operand:SWI48 1 "const_int_operand")))]
18424 "pow2p_hwi (INTVAL (operands[1]))
18425 && peep2_regno_dead_p (0, FLAGS_REG)"
18426 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
18427 (clobber (reg:CC FLAGS_REG))])]
18428 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18431 [(set (match_operand:DI 0 "register_operand")
18433 (mult:SI (match_operand:SI 1 "register_operand")
18434 (match_operand:SI 2 "const_int_operand"))))]
18436 && pow2p_hwi (INTVAL (operands[2]))
18437 && REGNO (operands[0]) == REGNO (operands[1])
18438 && peep2_regno_dead_p (0, FLAGS_REG)"
18439 [(parallel [(set (match_dup 0)
18440 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
18441 (clobber (reg:CC FLAGS_REG))])]
18442 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18444 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18445 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
18446 ;; On many CPUs it is also faster, since special hardware to avoid esp
18447 ;; dependencies is present.
18449 ;; While some of these conversions may be done using splitters, we use
18450 ;; peepholes in order to allow combine_stack_adjustments pass to see
18451 ;; nonobfuscated RTL.
18453 ;; Convert prologue esp subtractions to push.
18454 ;; We need register to push. In order to keep verify_flow_info happy we have
18456 ;; - use scratch and clobber it in order to avoid dependencies
18457 ;; - use already live register
18458 ;; We can't use the second way right now, since there is no reliable way how to
18459 ;; verify that given register is live. First choice will also most likely in
18460 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18461 ;; call clobbered registers are dead. We may want to use base pointer as an
18462 ;; alternative when no register is available later.
18465 [(match_scratch:W 1 "r")
18466 (parallel [(set (reg:P SP_REG)
18467 (plus:P (reg:P SP_REG)
18468 (match_operand:P 0 "const_int_operand")))
18469 (clobber (reg:CC FLAGS_REG))
18470 (clobber (mem:BLK (scratch)))])]
18471 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18472 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
18473 && !ix86_using_red_zone ()"
18474 [(clobber (match_dup 1))
18475 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18476 (clobber (mem:BLK (scratch)))])])
18479 [(match_scratch:W 1 "r")
18480 (parallel [(set (reg:P SP_REG)
18481 (plus:P (reg:P SP_REG)
18482 (match_operand:P 0 "const_int_operand")))
18483 (clobber (reg:CC FLAGS_REG))
18484 (clobber (mem:BLK (scratch)))])]
18485 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
18486 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
18487 && !ix86_using_red_zone ()"
18488 [(clobber (match_dup 1))
18489 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18490 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18491 (clobber (mem:BLK (scratch)))])])
18493 ;; Convert esp subtractions to push.
18495 [(match_scratch:W 1 "r")
18496 (parallel [(set (reg:P SP_REG)
18497 (plus:P (reg:P SP_REG)
18498 (match_operand:P 0 "const_int_operand")))
18499 (clobber (reg:CC FLAGS_REG))])]
18500 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18501 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
18502 && !ix86_using_red_zone ()"
18503 [(clobber (match_dup 1))
18504 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
18507 [(match_scratch:W 1 "r")
18508 (parallel [(set (reg:P SP_REG)
18509 (plus:P (reg:P SP_REG)
18510 (match_operand:P 0 "const_int_operand")))
18511 (clobber (reg:CC FLAGS_REG))])]
18512 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
18513 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
18514 && !ix86_using_red_zone ()"
18515 [(clobber (match_dup 1))
18516 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18517 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
18519 ;; Convert epilogue deallocator to pop.
18521 [(match_scratch:W 1 "r")
18522 (parallel [(set (reg:P SP_REG)
18523 (plus:P (reg:P SP_REG)
18524 (match_operand:P 0 "const_int_operand")))
18525 (clobber (reg:CC FLAGS_REG))
18526 (clobber (mem:BLK (scratch)))])]
18527 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
18528 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
18529 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18530 (clobber (mem:BLK (scratch)))])])
18532 ;; Two pops case is tricky, since pop causes dependency
18533 ;; on destination register. We use two registers if available.
18535 [(match_scratch:W 1 "r")
18536 (match_scratch:W 2 "r")
18537 (parallel [(set (reg:P SP_REG)
18538 (plus:P (reg:P SP_REG)
18539 (match_operand:P 0 "const_int_operand")))
18540 (clobber (reg:CC FLAGS_REG))
18541 (clobber (mem:BLK (scratch)))])]
18542 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
18543 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18544 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18545 (clobber (mem:BLK (scratch)))])
18546 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
18549 [(match_scratch:W 1 "r")
18550 (parallel [(set (reg:P SP_REG)
18551 (plus:P (reg:P SP_REG)
18552 (match_operand:P 0 "const_int_operand")))
18553 (clobber (reg:CC FLAGS_REG))
18554 (clobber (mem:BLK (scratch)))])]
18555 "optimize_insn_for_size_p ()
18556 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18557 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18558 (clobber (mem:BLK (scratch)))])
18559 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18561 ;; Convert esp additions to pop.
18563 [(match_scratch:W 1 "r")
18564 (parallel [(set (reg:P SP_REG)
18565 (plus:P (reg:P SP_REG)
18566 (match_operand:P 0 "const_int_operand")))
18567 (clobber (reg:CC FLAGS_REG))])]
18568 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
18569 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18571 ;; Two pops case is tricky, since pop causes dependency
18572 ;; on destination register. We use two registers if available.
18574 [(match_scratch:W 1 "r")
18575 (match_scratch:W 2 "r")
18576 (parallel [(set (reg:P SP_REG)
18577 (plus:P (reg:P SP_REG)
18578 (match_operand:P 0 "const_int_operand")))
18579 (clobber (reg:CC FLAGS_REG))])]
18580 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18581 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18582 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
18585 [(match_scratch:W 1 "r")
18586 (parallel [(set (reg:P SP_REG)
18587 (plus:P (reg:P SP_REG)
18588 (match_operand:P 0 "const_int_operand")))
18589 (clobber (reg:CC FLAGS_REG))])]
18590 "optimize_insn_for_size_p ()
18591 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18592 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18593 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18595 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18596 ;; required and register dies. Similarly for 128 to -128.
18598 [(set (match_operand 0 "flags_reg_operand")
18599 (match_operator 1 "compare_operator"
18600 [(match_operand 2 "register_operand")
18601 (match_operand 3 "const_int_operand")]))]
18602 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
18603 && incdec_operand (operands[3], GET_MODE (operands[3])))
18604 || (!TARGET_FUSE_CMP_AND_BRANCH
18605 && INTVAL (operands[3]) == 128))
18606 && ix86_match_ccmode (insn, CCGCmode)
18607 && peep2_reg_dead_p (1, operands[2])"
18608 [(parallel [(set (match_dup 0)
18609 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18610 (clobber (match_dup 2))])])
18612 ;; Convert imul by three, five and nine into lea
18615 [(set (match_operand:SWI48 0 "register_operand")
18616 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
18617 (match_operand:SWI48 2 "const359_operand")))
18618 (clobber (reg:CC FLAGS_REG))])]
18619 "!TARGET_PARTIAL_REG_STALL
18620 || <MODE>mode == SImode
18621 || optimize_function_for_size_p (cfun)"
18622 [(set (match_dup 0)
18623 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
18625 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18629 [(set (match_operand:SWI48 0 "register_operand")
18630 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
18631 (match_operand:SWI48 2 "const359_operand")))
18632 (clobber (reg:CC FLAGS_REG))])]
18633 "optimize_insn_for_speed_p ()
18634 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
18635 [(set (match_dup 0) (match_dup 1))
18637 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
18639 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18641 ;; imul $32bit_imm, mem, reg is vector decoded, while
18642 ;; imul $32bit_imm, reg, reg is direct decoded.
18644 [(match_scratch:SWI48 3 "r")
18645 (parallel [(set (match_operand:SWI48 0 "register_operand")
18646 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
18647 (match_operand:SWI48 2 "immediate_operand")))
18648 (clobber (reg:CC FLAGS_REG))])]
18649 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18650 && !satisfies_constraint_K (operands[2])"
18651 [(set (match_dup 3) (match_dup 1))
18652 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
18653 (clobber (reg:CC FLAGS_REG))])])
18656 [(match_scratch:SI 3 "r")
18657 (parallel [(set (match_operand:DI 0 "register_operand")
18659 (mult:SI (match_operand:SI 1 "memory_operand")
18660 (match_operand:SI 2 "immediate_operand"))))
18661 (clobber (reg:CC FLAGS_REG))])]
18663 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18664 && !satisfies_constraint_K (operands[2])"
18665 [(set (match_dup 3) (match_dup 1))
18666 (parallel [(set (match_dup 0)
18667 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18668 (clobber (reg:CC FLAGS_REG))])])
18670 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18671 ;; Convert it into imul reg, reg
18672 ;; It would be better to force assembler to encode instruction using long
18673 ;; immediate, but there is apparently no way to do so.
18675 [(parallel [(set (match_operand:SWI248 0 "register_operand")
18677 (match_operand:SWI248 1 "nonimmediate_operand")
18678 (match_operand:SWI248 2 "const_int_operand")))
18679 (clobber (reg:CC FLAGS_REG))])
18680 (match_scratch:SWI248 3 "r")]
18681 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18682 && satisfies_constraint_K (operands[2])"
18683 [(set (match_dup 3) (match_dup 2))
18684 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
18685 (clobber (reg:CC FLAGS_REG))])]
18687 if (!rtx_equal_p (operands[0], operands[1]))
18688 emit_move_insn (operands[0], operands[1]);
18691 ;; After splitting up read-modify operations, array accesses with memory
18692 ;; operands might end up in form:
18694 ;; movl 4(%esp), %edx
18696 ;; instead of pre-splitting:
18698 ;; addl 4(%esp), %eax
18700 ;; movl 4(%esp), %edx
18701 ;; leal (%edx,%eax,4), %eax
18704 [(match_scratch:W 5 "r")
18705 (parallel [(set (match_operand 0 "register_operand")
18706 (ashift (match_operand 1 "register_operand")
18707 (match_operand 2 "const_int_operand")))
18708 (clobber (reg:CC FLAGS_REG))])
18709 (parallel [(set (match_operand 3 "register_operand")
18710 (plus (match_dup 0)
18711 (match_operand 4 "x86_64_general_operand")))
18712 (clobber (reg:CC FLAGS_REG))])]
18713 "IN_RANGE (INTVAL (operands[2]), 1, 3)
18714 /* Validate MODE for lea. */
18715 && ((!TARGET_PARTIAL_REG_STALL
18716 && (GET_MODE (operands[0]) == QImode
18717 || GET_MODE (operands[0]) == HImode))
18718 || GET_MODE (operands[0]) == SImode
18719 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18720 && (rtx_equal_p (operands[0], operands[3])
18721 || peep2_reg_dead_p (2, operands[0]))
18722 /* We reorder load and the shift. */
18723 && !reg_overlap_mentioned_p (operands[0], operands[4])"
18724 [(set (match_dup 5) (match_dup 4))
18725 (set (match_dup 0) (match_dup 1))]
18727 machine_mode op1mode = GET_MODE (operands[1]);
18728 machine_mode mode = op1mode == DImode ? DImode : SImode;
18729 int scale = 1 << INTVAL (operands[2]);
18730 rtx index = gen_lowpart (word_mode, operands[1]);
18731 rtx base = gen_lowpart (word_mode, operands[5]);
18732 rtx dest = gen_lowpart (mode, operands[3]);
18734 operands[1] = gen_rtx_PLUS (word_mode, base,
18735 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
18736 if (mode != word_mode)
18737 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18739 operands[5] = base;
18740 if (op1mode != word_mode)
18741 operands[5] = gen_lowpart (op1mode, operands[5]);
18743 operands[0] = dest;
18746 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18747 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18748 ;; caught for use by garbage collectors and the like. Using an insn that
18749 ;; maps to SIGILL makes it more likely the program will rightfully die.
18750 ;; Keeping with tradition, "6" is in honor of #UD.
18751 (define_insn "trap"
18752 [(trap_if (const_int 1) (const_int 6))]
18755 #ifdef HAVE_AS_IX86_UD2
18758 return ASM_SHORT "0x0b0f";
18761 [(set_attr "length" "2")])
18764 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
18767 #ifdef HAVE_AS_IX86_UD2
18770 return ASM_SHORT "0x0b0f";
18773 [(set_attr "length" "2")])
18775 (define_expand "prefetch"
18776 [(prefetch (match_operand 0 "address_operand")
18777 (match_operand:SI 1 "const_int_operand")
18778 (match_operand:SI 2 "const_int_operand"))]
18779 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18781 bool write = INTVAL (operands[1]) != 0;
18782 int locality = INTVAL (operands[2]);
18784 gcc_assert (IN_RANGE (locality, 0, 3));
18786 /* Use 3dNOW prefetch in case we are asking for write prefetch not
18787 supported by SSE counterpart (non-SSE2 athlon machines) or the
18788 SSE prefetch is not available (K6 machines). Otherwise use SSE
18789 prefetch as it allows specifying of locality. */
18793 if (TARGET_PREFETCHWT1)
18794 operands[2] = GEN_INT (MAX (locality, 2));
18795 else if (TARGET_PRFCHW)
18796 operands[2] = GEN_INT (3);
18797 else if (TARGET_3DNOW && !TARGET_SSE2)
18798 operands[2] = GEN_INT (3);
18799 else if (TARGET_PREFETCH_SSE)
18800 operands[1] = const0_rtx;
18803 gcc_assert (TARGET_3DNOW);
18804 operands[2] = GEN_INT (3);
18809 if (TARGET_PREFETCH_SSE)
18813 gcc_assert (TARGET_3DNOW);
18814 operands[2] = GEN_INT (3);
18819 (define_insn "*prefetch_sse"
18820 [(prefetch (match_operand 0 "address_operand" "p")
18822 (match_operand:SI 1 "const_int_operand"))]
18823 "TARGET_PREFETCH_SSE"
18825 static const char * const patterns[4] = {
18826 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18829 int locality = INTVAL (operands[1]);
18830 gcc_assert (IN_RANGE (locality, 0, 3));
18832 return patterns[locality];
18834 [(set_attr "type" "sse")
18835 (set_attr "atom_sse_attr" "prefetch")
18836 (set (attr "length_address")
18837 (symbol_ref "memory_address_length (operands[0], false)"))
18838 (set_attr "memory" "none")])
18840 (define_insn "*prefetch_3dnow"
18841 [(prefetch (match_operand 0 "address_operand" "p")
18842 (match_operand:SI 1 "const_int_operand" "n")
18844 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18846 if (INTVAL (operands[1]) == 0)
18847 return "prefetch\t%a0";
18849 return "prefetchw\t%a0";
18851 [(set_attr "type" "mmx")
18852 (set (attr "length_address")
18853 (symbol_ref "memory_address_length (operands[0], false)"))
18854 (set_attr "memory" "none")])
18856 (define_insn "*prefetch_prefetchwt1"
18857 [(prefetch (match_operand 0 "address_operand" "p")
18860 "TARGET_PREFETCHWT1"
18861 "prefetchwt1\t%a0";
18862 [(set_attr "type" "sse")
18863 (set (attr "length_address")
18864 (symbol_ref "memory_address_length (operands[0], false)"))
18865 (set_attr "memory" "none")])
18867 (define_expand "stack_protect_set"
18868 [(match_operand 0 "memory_operand")
18869 (match_operand 1 "memory_operand")]
18870 "TARGET_SSP_TLS_GUARD"
18872 rtx (*insn)(rtx, rtx);
18874 insn = (TARGET_LP64
18875 ? gen_stack_protect_set_di
18876 : gen_stack_protect_set_si);
18878 emit_insn (insn (operands[0], operands[1]));
18882 (define_insn "stack_protect_set_<mode>"
18883 [(set (match_operand:PTR 0 "memory_operand" "=m")
18884 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18886 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18887 (clobber (reg:CC FLAGS_REG))]
18888 "TARGET_SSP_TLS_GUARD"
18889 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18890 [(set_attr "type" "multi")])
18892 (define_expand "stack_protect_test"
18893 [(match_operand 0 "memory_operand")
18894 (match_operand 1 "memory_operand")
18896 "TARGET_SSP_TLS_GUARD"
18898 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18900 rtx (*insn)(rtx, rtx, rtx);
18902 insn = (TARGET_LP64
18903 ? gen_stack_protect_test_di
18904 : gen_stack_protect_test_si);
18906 emit_insn (insn (flags, operands[0], operands[1]));
18908 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18909 flags, const0_rtx, operands[2]));
18913 (define_insn "stack_protect_test_<mode>"
18914 [(set (match_operand:CCZ 0 "flags_reg_operand")
18915 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18916 (match_operand:PTR 2 "memory_operand" "m")]
18918 (clobber (match_scratch:PTR 3 "=&r"))]
18919 "TARGET_SSP_TLS_GUARD"
18920 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18921 [(set_attr "type" "multi")])
18923 (define_insn "sse4_2_crc32<mode>"
18924 [(set (match_operand:SI 0 "register_operand" "=r")
18926 [(match_operand:SI 1 "register_operand" "0")
18927 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18929 "TARGET_SSE4_2 || TARGET_CRC32"
18930 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18931 [(set_attr "type" "sselog1")
18932 (set_attr "prefix_rep" "1")
18933 (set_attr "prefix_extra" "1")
18934 (set (attr "prefix_data16")
18935 (if_then_else (match_operand:HI 2)
18937 (const_string "*")))
18938 (set (attr "prefix_rex")
18939 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18941 (const_string "*")))
18942 (set_attr "mode" "SI")])
18944 (define_insn "sse4_2_crc32di"
18945 [(set (match_operand:DI 0 "register_operand" "=r")
18947 [(match_operand:DI 1 "register_operand" "0")
18948 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18950 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18951 "crc32{q}\t{%2, %0|%0, %2}"
18952 [(set_attr "type" "sselog1")
18953 (set_attr "prefix_rep" "1")
18954 (set_attr "prefix_extra" "1")
18955 (set_attr "mode" "DI")])
18957 (define_insn "rdpmc"
18958 [(set (match_operand:DI 0 "register_operand" "=A")
18959 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18963 [(set_attr "type" "other")
18964 (set_attr "length" "2")])
18966 (define_insn "rdpmc_rex64"
18967 [(set (match_operand:DI 0 "register_operand" "=a")
18968 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18970 (set (match_operand:DI 1 "register_operand" "=d")
18971 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18974 [(set_attr "type" "other")
18975 (set_attr "length" "2")])
18977 (define_insn "rdtsc"
18978 [(set (match_operand:DI 0 "register_operand" "=A")
18979 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18982 [(set_attr "type" "other")
18983 (set_attr "length" "2")])
18985 (define_insn "rdtsc_rex64"
18986 [(set (match_operand:DI 0 "register_operand" "=a")
18987 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18988 (set (match_operand:DI 1 "register_operand" "=d")
18989 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18992 [(set_attr "type" "other")
18993 (set_attr "length" "2")])
18995 (define_insn "rdtscp"
18996 [(set (match_operand:DI 0 "register_operand" "=A")
18997 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18998 (set (match_operand:SI 1 "register_operand" "=c")
18999 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19002 [(set_attr "type" "other")
19003 (set_attr "length" "3")])
19005 (define_insn "rdtscp_rex64"
19006 [(set (match_operand:DI 0 "register_operand" "=a")
19007 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19008 (set (match_operand:DI 1 "register_operand" "=d")
19009 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19010 (set (match_operand:SI 2 "register_operand" "=c")
19011 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19014 [(set_attr "type" "other")
19015 (set_attr "length" "3")])
19017 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19019 ;; FXSR, XSAVE and XSAVEOPT instructions
19021 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19023 (define_insn "fxsave"
19024 [(set (match_operand:BLK 0 "memory_operand" "=m")
19025 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
19028 [(set_attr "type" "other")
19029 (set_attr "memory" "store")
19030 (set (attr "length")
19031 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19033 (define_insn "fxsave64"
19034 [(set (match_operand:BLK 0 "memory_operand" "=m")
19035 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
19036 "TARGET_64BIT && TARGET_FXSR"
19038 [(set_attr "type" "other")
19039 (set_attr "memory" "store")
19040 (set (attr "length")
19041 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19043 (define_insn "fxrstor"
19044 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19048 [(set_attr "type" "other")
19049 (set_attr "memory" "load")
19050 (set (attr "length")
19051 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19053 (define_insn "fxrstor64"
19054 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19055 UNSPECV_FXRSTOR64)]
19056 "TARGET_64BIT && TARGET_FXSR"
19058 [(set_attr "type" "other")
19059 (set_attr "memory" "load")
19060 (set (attr "length")
19061 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19063 (define_int_iterator ANY_XSAVE
19065 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
19066 (UNSPECV_XSAVEC "TARGET_XSAVEC")
19067 (UNSPECV_XSAVES "TARGET_XSAVES")])
19069 (define_int_iterator ANY_XSAVE64
19071 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
19072 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
19073 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
19075 (define_int_attr xsave
19076 [(UNSPECV_XSAVE "xsave")
19077 (UNSPECV_XSAVE64 "xsave64")
19078 (UNSPECV_XSAVEOPT "xsaveopt")
19079 (UNSPECV_XSAVEOPT64 "xsaveopt64")
19080 (UNSPECV_XSAVEC "xsavec")
19081 (UNSPECV_XSAVEC64 "xsavec64")
19082 (UNSPECV_XSAVES "xsaves")
19083 (UNSPECV_XSAVES64 "xsaves64")])
19085 (define_int_iterator ANY_XRSTOR
19087 (UNSPECV_XRSTORS "TARGET_XSAVES")])
19089 (define_int_iterator ANY_XRSTOR64
19091 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
19093 (define_int_attr xrstor
19094 [(UNSPECV_XRSTOR "xrstor")
19095 (UNSPECV_XRSTOR64 "xrstor")
19096 (UNSPECV_XRSTORS "xrstors")
19097 (UNSPECV_XRSTORS64 "xrstors")])
19099 (define_insn "<xsave>"
19100 [(set (match_operand:BLK 0 "memory_operand" "=m")
19101 (unspec_volatile:BLK
19102 [(match_operand:DI 1 "register_operand" "A")]
19104 "!TARGET_64BIT && TARGET_XSAVE"
19106 [(set_attr "type" "other")
19107 (set_attr "memory" "store")
19108 (set (attr "length")
19109 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19111 (define_insn "<xsave>_rex64"
19112 [(set (match_operand:BLK 0 "memory_operand" "=m")
19113 (unspec_volatile:BLK
19114 [(match_operand:SI 1 "register_operand" "a")
19115 (match_operand:SI 2 "register_operand" "d")]
19117 "TARGET_64BIT && TARGET_XSAVE"
19119 [(set_attr "type" "other")
19120 (set_attr "memory" "store")
19121 (set (attr "length")
19122 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19124 (define_insn "<xsave>"
19125 [(set (match_operand:BLK 0 "memory_operand" "=m")
19126 (unspec_volatile:BLK
19127 [(match_operand:SI 1 "register_operand" "a")
19128 (match_operand:SI 2 "register_operand" "d")]
19130 "TARGET_64BIT && TARGET_XSAVE"
19132 [(set_attr "type" "other")
19133 (set_attr "memory" "store")
19134 (set (attr "length")
19135 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19137 (define_insn "<xrstor>"
19138 [(unspec_volatile:BLK
19139 [(match_operand:BLK 0 "memory_operand" "m")
19140 (match_operand:DI 1 "register_operand" "A")]
19142 "!TARGET_64BIT && TARGET_XSAVE"
19144 [(set_attr "type" "other")
19145 (set_attr "memory" "load")
19146 (set (attr "length")
19147 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19149 (define_insn "<xrstor>_rex64"
19150 [(unspec_volatile:BLK
19151 [(match_operand:BLK 0 "memory_operand" "m")
19152 (match_operand:SI 1 "register_operand" "a")
19153 (match_operand:SI 2 "register_operand" "d")]
19155 "TARGET_64BIT && TARGET_XSAVE"
19157 [(set_attr "type" "other")
19158 (set_attr "memory" "load")
19159 (set (attr "length")
19160 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19162 (define_insn "<xrstor>64"
19163 [(unspec_volatile:BLK
19164 [(match_operand:BLK 0 "memory_operand" "m")
19165 (match_operand:SI 1 "register_operand" "a")
19166 (match_operand:SI 2 "register_operand" "d")]
19168 "TARGET_64BIT && TARGET_XSAVE"
19170 [(set_attr "type" "other")
19171 (set_attr "memory" "load")
19172 (set (attr "length")
19173 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19175 (define_insn "xsetbv"
19176 [(unspec_volatile:SI
19177 [(match_operand:SI 0 "register_operand" "c")
19178 (match_operand:DI 1 "register_operand" "A")]
19180 "!TARGET_64BIT && TARGET_XSAVE"
19182 [(set_attr "type" "other")])
19184 (define_insn "xsetbv_rex64"
19185 [(unspec_volatile:SI
19186 [(match_operand:SI 0 "register_operand" "c")
19187 (match_operand:SI 1 "register_operand" "a")
19188 (match_operand:SI 2 "register_operand" "d")]
19190 "TARGET_64BIT && TARGET_XSAVE"
19192 [(set_attr "type" "other")])
19194 (define_insn "xgetbv"
19195 [(set (match_operand:DI 0 "register_operand" "=A")
19196 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19198 "!TARGET_64BIT && TARGET_XSAVE"
19200 [(set_attr "type" "other")])
19202 (define_insn "xgetbv_rex64"
19203 [(set (match_operand:DI 0 "register_operand" "=a")
19204 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19206 (set (match_operand:DI 1 "register_operand" "=d")
19207 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
19208 "TARGET_64BIT && TARGET_XSAVE"
19210 [(set_attr "type" "other")])
19212 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19214 ;; Floating-point instructions for atomic compound assignments
19216 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19218 ; Clobber all floating-point registers on environment save and restore
19219 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
19220 (define_insn "fnstenv"
19221 [(set (match_operand:BLK 0 "memory_operand" "=m")
19222 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
19223 (clobber (reg:HI FPCR_REG))
19224 (clobber (reg:XF ST0_REG))
19225 (clobber (reg:XF ST1_REG))
19226 (clobber (reg:XF ST2_REG))
19227 (clobber (reg:XF ST3_REG))
19228 (clobber (reg:XF ST4_REG))
19229 (clobber (reg:XF ST5_REG))
19230 (clobber (reg:XF ST6_REG))
19231 (clobber (reg:XF ST7_REG))]
19234 [(set_attr "type" "other")
19235 (set_attr "memory" "store")
19236 (set (attr "length")
19237 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19239 (define_insn "fldenv"
19240 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19242 (clobber (reg:CCFP FPSR_REG))
19243 (clobber (reg:HI FPCR_REG))
19244 (clobber (reg:XF ST0_REG))
19245 (clobber (reg:XF ST1_REG))
19246 (clobber (reg:XF ST2_REG))
19247 (clobber (reg:XF ST3_REG))
19248 (clobber (reg:XF ST4_REG))
19249 (clobber (reg:XF ST5_REG))
19250 (clobber (reg:XF ST6_REG))
19251 (clobber (reg:XF ST7_REG))]
19254 [(set_attr "type" "other")
19255 (set_attr "memory" "load")
19256 (set (attr "length")
19257 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19259 (define_insn "fnstsw"
19260 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
19261 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
19264 [(set_attr "type" "other,other")
19265 (set_attr "memory" "none,store")
19266 (set (attr "length")
19267 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19269 (define_insn "fnclex"
19270 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
19273 [(set_attr "type" "other")
19274 (set_attr "memory" "none")
19275 (set_attr "length" "2")])
19277 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19279 ;; LWP instructions
19281 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19283 (define_expand "lwp_llwpcb"
19284 [(unspec_volatile [(match_operand 0 "register_operand")]
19285 UNSPECV_LLWP_INTRINSIC)]
19288 (define_insn "*lwp_llwpcb<mode>1"
19289 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
19290 UNSPECV_LLWP_INTRINSIC)]
19293 [(set_attr "type" "lwp")
19294 (set_attr "mode" "<MODE>")
19295 (set_attr "length" "5")])
19297 (define_expand "lwp_slwpcb"
19298 [(set (match_operand 0 "register_operand")
19299 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19304 insn = (Pmode == DImode
19306 : gen_lwp_slwpcbsi);
19308 emit_insn (insn (operands[0]));
19312 (define_insn "lwp_slwpcb<mode>"
19313 [(set (match_operand:P 0 "register_operand" "=r")
19314 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19317 [(set_attr "type" "lwp")
19318 (set_attr "mode" "<MODE>")
19319 (set_attr "length" "5")])
19321 (define_expand "lwp_lwpval<mode>3"
19322 [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
19323 (match_operand:SI 2 "nonimmediate_operand")
19324 (match_operand:SI 3 "const_int_operand")]
19325 UNSPECV_LWPVAL_INTRINSIC)]
19327 ;; Avoid unused variable warning.
19328 "(void) operands[0];")
19330 (define_insn "*lwp_lwpval<mode>3_1"
19331 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
19332 (match_operand:SI 1 "nonimmediate_operand" "rm")
19333 (match_operand:SI 2 "const_int_operand" "i")]
19334 UNSPECV_LWPVAL_INTRINSIC)]
19336 "lwpval\t{%2, %1, %0|%0, %1, %2}"
19337 [(set_attr "type" "lwp")
19338 (set_attr "mode" "<MODE>")
19339 (set (attr "length")
19340 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19342 (define_expand "lwp_lwpins<mode>3"
19343 [(set (reg:CCC FLAGS_REG)
19344 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
19345 (match_operand:SI 2 "nonimmediate_operand")
19346 (match_operand:SI 3 "const_int_operand")]
19347 UNSPECV_LWPINS_INTRINSIC))
19348 (set (match_operand:QI 0 "nonimmediate_operand")
19349 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
19352 (define_insn "*lwp_lwpins<mode>3_1"
19353 [(set (reg:CCC FLAGS_REG)
19354 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
19355 (match_operand:SI 1 "nonimmediate_operand" "rm")
19356 (match_operand:SI 2 "const_int_operand" "i")]
19357 UNSPECV_LWPINS_INTRINSIC))]
19359 "lwpins\t{%2, %1, %0|%0, %1, %2}"
19360 [(set_attr "type" "lwp")
19361 (set_attr "mode" "<MODE>")
19362 (set (attr "length")
19363 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19365 (define_int_iterator RDFSGSBASE
19369 (define_int_iterator WRFSGSBASE
19373 (define_int_attr fsgs
19374 [(UNSPECV_RDFSBASE "fs")
19375 (UNSPECV_RDGSBASE "gs")
19376 (UNSPECV_WRFSBASE "fs")
19377 (UNSPECV_WRGSBASE "gs")])
19379 (define_insn "rd<fsgs>base<mode>"
19380 [(set (match_operand:SWI48 0 "register_operand" "=r")
19381 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
19382 "TARGET_64BIT && TARGET_FSGSBASE"
19384 [(set_attr "type" "other")
19385 (set_attr "prefix_extra" "2")])
19387 (define_insn "wr<fsgs>base<mode>"
19388 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
19390 "TARGET_64BIT && TARGET_FSGSBASE"
19392 [(set_attr "type" "other")
19393 (set_attr "prefix_extra" "2")])
19395 (define_insn "rdrand<mode>_1"
19396 [(set (match_operand:SWI248 0 "register_operand" "=r")
19397 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
19398 (set (reg:CCC FLAGS_REG)
19399 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
19402 [(set_attr "type" "other")
19403 (set_attr "prefix_extra" "1")])
19405 (define_insn "rdseed<mode>_1"
19406 [(set (match_operand:SWI248 0 "register_operand" "=r")
19407 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
19408 (set (reg:CCC FLAGS_REG)
19409 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
19412 [(set_attr "type" "other")
19413 (set_attr "prefix_extra" "1")])
19415 (define_expand "pause"
19416 [(set (match_dup 0)
19417 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19420 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
19421 MEM_VOLATILE_P (operands[0]) = 1;
19424 ;; Use "rep; nop", instead of "pause", to support older assemblers.
19425 ;; They have the same encoding.
19426 (define_insn "*pause"
19427 [(set (match_operand:BLK 0)
19428 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19431 [(set_attr "length" "2")
19432 (set_attr "memory" "unknown")])
19434 (define_expand "xbegin"
19435 [(set (match_operand:SI 0 "register_operand")
19436 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
19439 rtx_code_label *label = gen_label_rtx ();
19441 /* xbegin is emitted as jump_insn, so reload won't be able
19442 to reload its operand. Force the value into AX hard register. */
19443 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
19444 emit_move_insn (ax_reg, constm1_rtx);
19446 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
19448 emit_label (label);
19449 LABEL_NUSES (label) = 1;
19451 emit_move_insn (operands[0], ax_reg);
19456 (define_insn "xbegin_1"
19458 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
19460 (label_ref (match_operand 1))
19462 (set (match_operand:SI 0 "register_operand" "+a")
19463 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
19466 [(set_attr "type" "other")
19467 (set_attr "length" "6")])
19469 (define_insn "xend"
19470 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
19473 [(set_attr "type" "other")
19474 (set_attr "length" "3")])
19476 (define_insn "xabort"
19477 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
19481 [(set_attr "type" "other")
19482 (set_attr "length" "3")])
19484 (define_expand "xtest"
19485 [(set (match_operand:QI 0 "register_operand")
19486 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
19489 emit_insn (gen_xtest_1 ());
19491 ix86_expand_setcc (operands[0], NE,
19492 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
19496 (define_insn "xtest_1"
19497 [(set (reg:CCZ FLAGS_REG)
19498 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
19501 [(set_attr "type" "other")
19502 (set_attr "length" "3")])
19504 (define_insn "clwb"
19505 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
19509 [(set_attr "type" "sse")
19510 (set_attr "atom_sse_attr" "fence")
19511 (set_attr "memory" "unknown")])
19513 (define_insn "clflushopt"
19514 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
19515 UNSPECV_CLFLUSHOPT)]
19516 "TARGET_CLFLUSHOPT"
19518 [(set_attr "type" "sse")
19519 (set_attr "atom_sse_attr" "fence")
19520 (set_attr "memory" "unknown")])
19522 ;; MONITORX and MWAITX
19523 (define_insn "mwaitx"
19524 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
19525 (match_operand:SI 1 "register_operand" "a")
19526 (match_operand:SI 2 "register_operand" "b")]
19529 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
19530 ;; Since 32bit register operands are implicitly zero extended to 64bit,
19531 ;; we only need to set up 32bit registers.
19533 [(set_attr "length" "3")])
19535 (define_insn "monitorx_<mode>"
19536 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
19537 (match_operand:SI 1 "register_operand" "c")
19538 (match_operand:SI 2 "register_operand" "d")]
19541 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
19542 ;; RCX and RDX are used. Since 32bit register operands are implicitly
19543 ;; zero extended to 64bit, we only need to set up 32bit registers.
19545 [(set (attr "length")
19546 (symbol_ref ("(Pmode != word_mode) + 3")))])
19549 (define_insn "clzero_<mode>"
19550 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
19554 [(set_attr "length" "3")
19555 (set_attr "memory" "unknown")])
19557 ;; MPX instructions
19559 (define_expand "<mode>_mk"
19560 [(set (match_operand:BND 0 "register_operand")
19564 [(match_operand:<bnd_ptr> 1 "register_operand")
19565 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
19569 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
19571 UNSPEC_BNDMK_ADDR);
19574 (define_insn "*<mode>_mk"
19575 [(set (match_operand:BND 0 "register_operand" "=w")
19577 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19579 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
19580 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
19581 UNSPEC_BNDMK_ADDR)])]
19584 "bndmk\t{%3, %0|%0, %3}"
19585 [(set_attr "type" "mpxmk")])
19587 (define_expand "mov<mode>"
19588 [(set (match_operand:BND 0 "general_operand")
19589 (match_operand:BND 1 "general_operand"))]
19591 "ix86_expand_move (<MODE>mode, operands); DONE;")
19593 (define_insn "*mov<mode>_internal_mpx"
19594 [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
19595 (match_operand:BND 1 "general_operand" "wm,w"))]
19597 "bndmov\t{%1, %0|%0, %1}"
19598 [(set_attr "type" "mpxmov")])
19600 (define_expand "<mode>_<bndcheck>"
19603 [(match_operand:BND 0 "register_operand")
19604 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
19606 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
19609 operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
19610 MEM_VOLATILE_P (operands[2]) = 1;
19613 (define_insn "*<mode>_<bndcheck>"
19615 [(match_operand:BND 0 "register_operand" "w")
19616 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
19617 (set (match_operand:BLK 2 "bnd_mem_operator")
19618 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))]
19620 "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
19621 [(set_attr "type" "mpxchk")])
19623 (define_expand "<mode>_ldx"
19625 [(set (match_operand:BND 0 "register_operand")
19629 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
19630 (match_operand:<bnd_ptr> 2 "register_operand")]))]
19632 (use (mem:BLK (match_dup 1)))])]
19635 /* Avoid registers which cannot be used as index. */
19636 if (!index_register_operand (operands[2], Pmode))
19637 operands[2] = copy_addr_to_reg (operands[2]);
19639 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
19641 UNSPEC_BNDLDX_ADDR);
19644 (define_insn "*<mode>_ldx"
19645 [(set (match_operand:BND 0 "register_operand" "=w")
19647 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19649 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
19650 (match_operand:<bnd_ptr> 2 "register_operand" "l")]
19651 UNSPEC_BNDLDX_ADDR)])]
19653 (use (mem:BLK (match_dup 1)))]
19655 "bndldx\t{%3, %0|%0, %3}"
19656 [(set_attr "type" "mpxld")])
19658 (define_expand "<mode>_stx"
19663 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
19664 (match_operand:<bnd_ptr> 1 "register_operand")]))
19665 (match_operand:BND 2 "register_operand")]
19668 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
19671 /* Avoid registers which cannot be used as index. */
19672 if (!index_register_operand (operands[1], Pmode))
19673 operands[1] = copy_addr_to_reg (operands[1]);
19675 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
19677 UNSPEC_BNDLDX_ADDR);
19678 operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
19679 MEM_VOLATILE_P (operands[4]) = 1;
19682 (define_insn "*<mode>_stx"
19684 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19686 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
19687 (match_operand:<bnd_ptr> 1 "register_operand" "l")]
19688 UNSPEC_BNDLDX_ADDR)])
19689 (match_operand:BND 2 "register_operand" "w")]
19691 (set (match_operand:BLK 4 "bnd_mem_operator")
19692 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))]
19694 "bndstx\t{%2, %3|%3, %2}"
19695 [(set_attr "type" "mpxst")])
19697 (define_insn "move_size_reloc_<mode>"
19698 [(set (match_operand:SWI48 0 "register_operand" "=r")
19700 [(match_operand:SWI48 1 "symbol_operand")]
19704 if (x86_64_immediate_size_operand (operands[1], VOIDmode))
19705 return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
19707 return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
19709 [(set_attr "type" "imov")
19710 (set_attr "mode" "<MODE>")])
19712 ;; RDPKRU and WRPKRU
19714 (define_expand "rdpkru"
19716 [(set (match_operand:SI 0 "register_operand")
19717 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
19718 (set (match_dup 2) (const_int 0))])]
19721 operands[1] = force_reg (SImode, const0_rtx);
19722 operands[2] = gen_reg_rtx (SImode);
19725 (define_insn "*rdpkru"
19726 [(set (match_operand:SI 0 "register_operand" "=a")
19727 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
19729 (set (match_operand:SI 1 "register_operand" "=d")
19733 [(set_attr "type" "other")])
19735 (define_expand "wrpkru"
19736 [(unspec_volatile:SI
19737 [(match_operand:SI 0 "register_operand")
19738 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
19741 operands[1] = force_reg (SImode, const0_rtx);
19742 operands[2] = force_reg (SImode, const0_rtx);
19745 (define_insn "*wrpkru"
19746 [(unspec_volatile:SI
19747 [(match_operand:SI 0 "register_operand" "a")
19748 (match_operand:SI 1 "register_operand" "d")
19749 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
19752 [(set_attr "type" "other")])
19754 (define_insn "rdpid"
19755 [(set (match_operand:SI 0 "register_operand" "=r")
19756 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
19759 [(set_attr "type" "other")])
19763 (include "sync.md")