1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2016 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
4 ;; x86_64 support added by Jan Hubicka
6 ;; This file is part of GCC.
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>. */
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; The special asm out single letter directives following a '%' are:
28 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29 ;; C -- print opcode suffix for set/cmov insn.
30 ;; c -- like C, but print reversed condition
31 ;; F,f -- likewise, but for floating-point.
32 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
34 ;; R -- print the prefix for register names.
35 ;; z -- print the opcode suffix for the size of the current operand.
36 ;; Z -- likewise, with special suffixes for x87 instructions.
37 ;; * -- print a star (in certain assembler syntax)
38 ;; A -- print an absolute memory reference.
39 ;; E -- print address with DImode register names if TARGET_64BIT.
40 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41 ;; s -- print a shift double count, followed by the assemblers argument
43 ;; b -- print the QImode name of the register for the indicated operand.
44 ;; %b0 would print %al if operands[0] is reg 0.
45 ;; w -- likewise, print the HImode name of the register.
46 ;; k -- likewise, print the SImode name of the register.
47 ;; q -- likewise, print the DImode name of the register.
48 ;; x -- likewise, print the V4SFmode name of the register.
49 ;; t -- likewise, print the V8SFmode name of the register.
50 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; y -- print "st(0)" instead of "st" as a register.
52 ;; d -- print duplicated register operand for AVX instruction.
53 ;; D -- print condition for SSE cmp instruction.
54 ;; P -- if PIC, print an @PLT suffix.
55 ;; p -- print raw symbol name.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; K -- print HLE lock prefix
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64 ;; @ -- print a segment register of thread base pointer load
65 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
66 ;; ! -- print MPX prefix for jxx/call/ret instructions if required.
68 (define_c_enum "unspec" [
69 ;; Relocation specifiers
80 UNSPEC_MACHOPIC_OFFSET
89 UNSPEC_MEMORY_BLOCKAGE
100 ;; Other random patterns
108 UNSPEC_LD_MPIC ; load_macho_picbase
110 UNSPEC_DIV_ALREADY_SPLIT
116 UNSPEC_INSN_FALSE_DEP
118 ;; For SSE/MMX support:
126 ;; Generic math support
128 UNSPEC_IEEE_MIN ; not commutative
129 UNSPEC_IEEE_MAX ; not commutative
131 ;; x87 Floating point
147 UNSPEC_FRNDINT_MASK_PM
151 ;; x87 Double output FP
178 ;; For LZCNT suppoprt
189 ;; For AVX512F support
203 UNSPEC_INTERRUPT_RETURN
206 (define_c_enum "unspecv" [
209 UNSPECV_PROBE_STACK_RANGE
212 UNSPECV_SPLIT_STACK_RETURN
218 UNSPECV_LLWP_INTRINSIC
219 UNSPECV_SLWP_INTRINSIC
220 UNSPECV_LWPVAL_INTRINSIC
221 UNSPECV_LWPINS_INTRINSIC
243 ;; For atomic compound assignments.
249 ;; For RDRAND support
252 ;; For RDSEED support
266 ;; For CLFLUSHOPT support
269 ;; For MONITORX and MWAITX support
273 ;; For CLZERO support
276 ;; For RDPKRU and WRPKRU support
280 ;; Constants to represent rounding modes in the ROUND instruction
289 ;; Constants to represent AVX512F embeded rounding
291 [(ROUND_NEAREST_INT 0)
299 ;; Constants to represent pcomtrue/pcomfalse variants
309 ;; Constants used in the XOP pperm instruction
311 [(PPERM_SRC 0x00) /* copy source */
312 (PPERM_INVERT 0x20) /* invert source */
313 (PPERM_REVERSE 0x40) /* bit reverse source */
314 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
315 (PPERM_ZERO 0x80) /* all 0's */
316 (PPERM_ONES 0xa0) /* all 1's */
317 (PPERM_SIGN 0xc0) /* propagate sign bit */
318 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
319 (PPERM_SRC1 0x00) /* use first source byte */
320 (PPERM_SRC2 0x10) /* use second source byte */
323 ;; Registers by name.
406 (FIRST_PSEUDO_REG 81)
409 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
412 ;; In C guard expressions, put expressions which may be compile-time
413 ;; constants first. This allows for better optimization. For
414 ;; example, write "TARGET_64BIT && reload_completed", not
415 ;; "reload_completed && TARGET_64BIT".
419 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
420 atom,slm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
421 bdver4,btver2,znver1"
422 (const (symbol_ref "ix86_schedule")))
424 ;; A basic instruction type. Refinements due to arguments to be
425 ;; provided in other attributes.
428 alu,alu1,negnot,imov,imovx,lea,
429 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
430 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
431 push,pop,call,callv,leave,
433 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
434 fxch,fistp,fisttp,frndint,
435 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
436 ssemul,sseimul,ssediv,sselog,sselog1,
437 sseishft,sseishft1,ssecmp,ssecomi,
438 ssecvt,ssecvt1,sseicvt,sseins,
439 sseshuf,sseshuf1,ssemuladd,sse4arg,
441 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
442 mpxmov,mpxmk,mpxchk,mpxld,mpxst"
443 (const_string "other"))
445 ;; Main data type used by the insn
447 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
449 (const_string "unknown"))
451 ;; The CPU unit operations uses.
452 (define_attr "unit" "integer,i387,sse,mmx,unknown"
453 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
454 fxch,fistp,fisttp,frndint")
455 (const_string "i387")
456 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
457 ssemul,sseimul,ssediv,sselog,sselog1,
458 sseishft,sseishft1,ssecmp,ssecomi,
459 ssecvt,ssecvt1,sseicvt,sseins,
460 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
462 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
464 (eq_attr "type" "other")
465 (const_string "unknown")]
466 (const_string "integer")))
468 ;; The (bounding maximum) length of an instruction immediate.
469 (define_attr "length_immediate" ""
470 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
471 bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
474 (eq_attr "unit" "i387,sse,mmx")
476 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
477 rotate,rotatex,rotate1,imul,icmp,push,pop")
478 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
479 (eq_attr "type" "imov,test")
480 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
481 (eq_attr "type" "call")
482 (if_then_else (match_operand 0 "constant_call_address_operand")
485 (eq_attr "type" "callv")
486 (if_then_else (match_operand 1 "constant_call_address_operand")
489 ;; We don't know the size before shorten_branches. Expect
490 ;; the instruction to fit for better scheduling.
491 (eq_attr "type" "ibr")
494 (symbol_ref "/* Update immediate_length and other attributes! */
495 gcc_unreachable (),1")))
497 ;; The (bounding maximum) length of an instruction address.
498 (define_attr "length_address" ""
499 (cond [(eq_attr "type" "str,other,multi,fxch")
501 (and (eq_attr "type" "call")
502 (match_operand 0 "constant_call_address_operand"))
504 (and (eq_attr "type" "callv")
505 (match_operand 1 "constant_call_address_operand"))
508 (symbol_ref "ix86_attr_length_address_default (insn)")))
510 ;; Set when length prefix is used.
511 (define_attr "prefix_data16" ""
512 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
514 (eq_attr "mode" "HI")
516 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
521 ;; Set when string REP prefix is used.
522 (define_attr "prefix_rep" ""
523 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
525 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
527 (and (eq_attr "type" "ibr,call,callv")
528 (match_test "ix86_bnd_prefixed_insn_p (insn)"))
533 ;; Set when 0f opcode prefix is used.
534 (define_attr "prefix_0f" ""
536 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
537 mpxmk,mpxmov,mpxchk,mpxld,mpxst")
538 (eq_attr "unit" "sse,mmx"))
542 ;; Set when REX opcode prefix is used.
543 (define_attr "prefix_rex" ""
544 (cond [(not (match_test "TARGET_64BIT"))
546 (and (eq_attr "mode" "DI")
547 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
548 (eq_attr "unit" "!mmx")))
550 (and (eq_attr "mode" "QI")
551 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
553 (match_test "x86_extended_reg_mentioned_p (insn)")
555 (and (eq_attr "type" "imovx")
556 (match_operand:QI 1 "ext_QIreg_operand"))
561 ;; There are also additional prefixes in 3DNOW, SSSE3.
562 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
563 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
564 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
565 (define_attr "prefix_extra" ""
566 (cond [(eq_attr "type" "ssemuladd,sse4arg")
568 (eq_attr "type" "sseiadd1,ssecvt1")
573 ;; Set when BND opcode prefix may be used.
574 (define_attr "maybe_prefix_bnd" "" (const_int 0))
576 ;; Prefix used: original, VEX or maybe VEX.
577 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
578 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
580 (eq_attr "mode" "XI,V16SF,V8DF")
581 (const_string "evex")
583 (const_string "orig")))
585 ;; VEX W bit is used.
586 (define_attr "prefix_vex_w" "" (const_int 0))
588 ;; The length of VEX prefix
589 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
590 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
591 ;; still prefix_0f 1, with prefix_extra 1.
592 (define_attr "length_vex" ""
593 (if_then_else (and (eq_attr "prefix_0f" "1")
594 (eq_attr "prefix_extra" "0"))
595 (if_then_else (eq_attr "prefix_vex_w" "1")
596 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
597 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
598 (if_then_else (eq_attr "prefix_vex_w" "1")
599 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
600 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
602 ;; 4-bytes evex prefix and 1 byte opcode.
603 (define_attr "length_evex" "" (const_int 5))
605 ;; Set when modrm byte is used.
606 (define_attr "modrm" ""
607 (cond [(eq_attr "type" "str,leave")
609 (eq_attr "unit" "i387")
611 (and (eq_attr "type" "incdec")
612 (and (not (match_test "TARGET_64BIT"))
613 (ior (match_operand:SI 1 "register_operand")
614 (match_operand:HI 1 "register_operand"))))
616 (and (eq_attr "type" "push")
617 (not (match_operand 1 "memory_operand")))
619 (and (eq_attr "type" "pop")
620 (not (match_operand 0 "memory_operand")))
622 (and (eq_attr "type" "imov")
623 (and (not (eq_attr "mode" "DI"))
624 (ior (and (match_operand 0 "register_operand")
625 (match_operand 1 "immediate_operand"))
626 (ior (and (match_operand 0 "ax_reg_operand")
627 (match_operand 1 "memory_displacement_only_operand"))
628 (and (match_operand 0 "memory_displacement_only_operand")
629 (match_operand 1 "ax_reg_operand"))))))
631 (and (eq_attr "type" "call")
632 (match_operand 0 "constant_call_address_operand"))
634 (and (eq_attr "type" "callv")
635 (match_operand 1 "constant_call_address_operand"))
637 (and (eq_attr "type" "alu,alu1,icmp,test")
638 (match_operand 0 "ax_reg_operand"))
639 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
643 (define_attr "modrm_class" "none,incdec,op0,op01,op02,pushpop,unknown"
644 (cond [(eq_attr "modrm" "0")
645 (const_string "none")
646 (eq_attr "type" "alu,imul,ishift")
647 (const_string "op02")
648 (eq_attr "type" "imov,imovx,lea,alu1,icmp")
649 (const_string "op01")
650 (eq_attr "type" "incdec")
651 (const_string "incdec")
652 (eq_attr "type" "push,pop")
653 (const_string "pushpop")]
654 (const_string "unknown")))
656 ;; The (bounding maximum) length of an instruction in bytes.
657 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
658 ;; Later we may want to split them and compute proper length as for
660 (define_attr "length" ""
661 (cond [(eq_attr "type" "other,multi,fistp,frndint")
663 (eq_attr "type" "fcmp")
665 (eq_attr "unit" "i387")
667 (plus (attr "prefix_data16")
668 (attr "length_address")))
669 (ior (eq_attr "prefix" "evex")
670 (and (ior (eq_attr "prefix" "maybe_evex")
671 (eq_attr "prefix" "maybe_vex"))
672 (match_test "TARGET_AVX512F")))
673 (plus (attr "length_evex")
674 (plus (attr "length_immediate")
676 (attr "length_address"))))
677 (ior (eq_attr "prefix" "vex")
678 (and (ior (eq_attr "prefix" "maybe_vex")
679 (eq_attr "prefix" "maybe_evex"))
680 (match_test "TARGET_AVX")))
681 (plus (attr "length_vex")
682 (plus (attr "length_immediate")
684 (attr "length_address"))))]
685 (plus (plus (attr "modrm")
686 (plus (attr "prefix_0f")
687 (plus (attr "prefix_rex")
688 (plus (attr "prefix_extra")
690 (plus (attr "prefix_rep")
691 (plus (attr "prefix_data16")
692 (plus (attr "length_immediate")
693 (attr "length_address")))))))
695 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
696 ;; `store' if there is a simple memory reference therein, or `unknown'
697 ;; if the instruction is complex.
699 (define_attr "memory" "none,load,store,both,unknown"
700 (cond [(eq_attr "type" "other,multi,str,lwp")
701 (const_string "unknown")
702 (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
703 (const_string "none")
704 (eq_attr "type" "fistp,leave")
705 (const_string "both")
706 (eq_attr "type" "frndint")
707 (const_string "load")
708 (eq_attr "type" "mpxld")
709 (const_string "load")
710 (eq_attr "type" "mpxst")
711 (const_string "store")
712 (eq_attr "type" "push")
713 (if_then_else (match_operand 1 "memory_operand")
714 (const_string "both")
715 (const_string "store"))
716 (eq_attr "type" "pop")
717 (if_then_else (match_operand 0 "memory_operand")
718 (const_string "both")
719 (const_string "load"))
720 (eq_attr "type" "setcc")
721 (if_then_else (match_operand 0 "memory_operand")
722 (const_string "store")
723 (const_string "none"))
724 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
725 (if_then_else (ior (match_operand 0 "memory_operand")
726 (match_operand 1 "memory_operand"))
727 (const_string "load")
728 (const_string "none"))
729 (eq_attr "type" "ibr")
730 (if_then_else (match_operand 0 "memory_operand")
731 (const_string "load")
732 (const_string "none"))
733 (eq_attr "type" "call")
734 (if_then_else (match_operand 0 "constant_call_address_operand")
735 (const_string "none")
736 (const_string "load"))
737 (eq_attr "type" "callv")
738 (if_then_else (match_operand 1 "constant_call_address_operand")
739 (const_string "none")
740 (const_string "load"))
741 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
742 (match_operand 1 "memory_operand"))
743 (const_string "both")
744 (and (match_operand 0 "memory_operand")
745 (match_operand 1 "memory_operand"))
746 (const_string "both")
747 (match_operand 0 "memory_operand")
748 (const_string "store")
749 (match_operand 1 "memory_operand")
750 (const_string "load")
752 "!alu1,negnot,ishift1,
753 imov,imovx,icmp,test,bitmanip,
755 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
756 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
757 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
758 (match_operand 2 "memory_operand"))
759 (const_string "load")
760 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
761 (match_operand 3 "memory_operand"))
762 (const_string "load")
764 (const_string "none")))
766 ;; Indicates if an instruction has both an immediate and a displacement.
768 (define_attr "imm_disp" "false,true,unknown"
769 (cond [(eq_attr "type" "other,multi")
770 (const_string "unknown")
771 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
772 (and (match_operand 0 "memory_displacement_operand")
773 (match_operand 1 "immediate_operand")))
774 (const_string "true")
775 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
776 (and (match_operand 0 "memory_displacement_operand")
777 (match_operand 2 "immediate_operand")))
778 (const_string "true")
780 (const_string "false")))
782 ;; Indicates if an FP operation has an integer source.
784 (define_attr "fp_int_src" "false,true"
785 (const_string "false"))
787 ;; Defines rounding mode of an FP operation.
789 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
790 (const_string "any"))
792 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
793 (define_attr "use_carry" "0,1" (const_string "0"))
795 ;; Define attribute to indicate unaligned ssemov insns
796 (define_attr "movu" "0,1" (const_string "0"))
798 ;; Used to control the "enabled" attribute on a per-instruction basis.
799 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
800 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
801 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
802 fma_avx512f,avx512bw,noavx512bw,avx512dq,noavx512dq,
803 avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw"
804 (const_string "base"))
806 (define_attr "enabled" ""
807 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
808 (eq_attr "isa" "x64_sse4")
809 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
810 (eq_attr "isa" "x64_sse4_noavx")
811 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
812 (eq_attr "isa" "x64_avx")
813 (symbol_ref "TARGET_64BIT && TARGET_AVX")
814 (eq_attr "isa" "x64_avx512dq")
815 (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
816 (eq_attr "isa" "x64_avx512bw")
817 (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
818 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
819 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
820 (eq_attr "isa" "sse2_noavx")
821 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
822 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
823 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
824 (eq_attr "isa" "sse4_noavx")
825 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
826 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
827 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
828 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
829 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
830 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
831 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
832 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
833 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
834 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
835 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
836 (eq_attr "isa" "fma_avx512f")
837 (symbol_ref "TARGET_FMA || TARGET_AVX512F")
838 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
839 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
840 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
841 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
842 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
843 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
847 (define_attr "preferred_for_size" "" (const_int 1))
848 (define_attr "preferred_for_speed" "" (const_int 1))
850 ;; Describe a user's asm statement.
851 (define_asm_attributes
852 [(set_attr "length" "128")
853 (set_attr "type" "multi")])
855 (define_code_iterator plusminus [plus minus])
857 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
859 (define_code_iterator multdiv [mult div])
861 ;; Base name for define_insn
862 (define_code_attr plusminus_insn
863 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
864 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
866 ;; Base name for insn mnemonic.
867 (define_code_attr plusminus_mnemonic
868 [(plus "add") (ss_plus "adds") (us_plus "addus")
869 (minus "sub") (ss_minus "subs") (us_minus "subus")])
870 (define_code_attr multdiv_mnemonic
871 [(mult "mul") (div "div")])
873 ;; Mark commutative operators as such in constraints.
874 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
875 (minus "") (ss_minus "") (us_minus "")])
877 ;; Mapping of max and min
878 (define_code_iterator maxmin [smax smin umax umin])
880 ;; Mapping of signed max and min
881 (define_code_iterator smaxmin [smax smin])
883 ;; Mapping of unsigned max and min
884 (define_code_iterator umaxmin [umax umin])
886 ;; Base name for integer and FP insn mnemonic
887 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
888 (umax "maxu") (umin "minu")])
889 (define_code_attr maxmin_float [(smax "max") (smin "min")])
891 (define_int_iterator IEEE_MAXMIN
895 (define_int_attr ieee_maxmin
896 [(UNSPEC_IEEE_MAX "max")
897 (UNSPEC_IEEE_MIN "min")])
899 ;; Mapping of logic operators
900 (define_code_iterator any_logic [and ior xor])
901 (define_code_iterator any_or [ior xor])
902 (define_code_iterator fpint_logic [and xor])
904 ;; Base name for insn mnemonic.
905 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
907 ;; Mapping of logic-shift operators
908 (define_code_iterator any_lshift [ashift lshiftrt])
910 ;; Mapping of shift-right operators
911 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
913 ;; Mapping of all shift operators
914 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
916 ;; Base name for define_insn
917 (define_code_attr shift_insn
918 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
920 ;; Base name for insn mnemonic.
921 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
922 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
924 ;; Mask variant left right mnemonics
925 (define_code_attr mshift [(ashift "shiftl") (lshiftrt "shiftr")])
927 ;; Mapping of rotate operators
928 (define_code_iterator any_rotate [rotate rotatert])
930 ;; Base name for define_insn
931 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
933 ;; Base name for insn mnemonic.
934 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
936 ;; Mapping of abs neg operators
937 (define_code_iterator absneg [abs neg])
939 ;; Base name for x87 insn mnemonic.
940 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
942 ;; Used in signed and unsigned widening multiplications.
943 (define_code_iterator any_extend [sign_extend zero_extend])
945 ;; Prefix for insn menmonic.
946 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
948 ;; Prefix for define_insn
949 (define_code_attr u [(sign_extend "") (zero_extend "u")])
950 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
951 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
953 ;; Used in signed and unsigned truncations.
954 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
955 ;; Instruction suffix for truncations.
956 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
958 ;; Used in signed and unsigned fix.
959 (define_code_iterator any_fix [fix unsigned_fix])
960 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
962 ;; Used in signed and unsigned float.
963 (define_code_iterator any_float [float unsigned_float])
964 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
966 ;; All integer modes.
967 (define_mode_iterator SWI1248x [QI HI SI DI])
969 ;; All integer modes with AVX512BW/DQ.
970 (define_mode_iterator SWI1248_AVX512BWDQ
971 [(QI "TARGET_AVX512DQ") HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
973 ;; All integer modes without QImode.
974 (define_mode_iterator SWI248x [HI SI DI])
976 ;; All integer modes without QImode and HImode.
977 (define_mode_iterator SWI48x [SI DI])
979 ;; All integer modes without SImode and DImode.
980 (define_mode_iterator SWI12 [QI HI])
982 ;; All integer modes without DImode.
983 (define_mode_iterator SWI124 [QI HI SI])
985 ;; All integer modes without QImode and DImode.
986 (define_mode_iterator SWI24 [HI SI])
988 ;; Single word integer modes.
989 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
991 ;; Single word integer modes without QImode.
992 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
994 ;; Single word integer modes without QImode and HImode.
995 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
997 ;; All math-dependant single and double word integer modes.
998 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
999 (HI "TARGET_HIMODE_MATH")
1000 SI DI (TI "TARGET_64BIT")])
1002 ;; Math-dependant single word integer modes.
1003 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1004 (HI "TARGET_HIMODE_MATH")
1005 SI (DI "TARGET_64BIT")])
1007 ;; Math-dependant integer modes without DImode.
1008 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1009 (HI "TARGET_HIMODE_MATH")
1012 ;; Math-dependant integer modes with DImode.
1013 (define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH")
1014 (HI "TARGET_HIMODE_MATH")
1015 SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")])
1017 ;; Math-dependant single word integer modes without QImode.
1018 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1019 SI (DI "TARGET_64BIT")])
1021 ;; Double word integer modes.
1022 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1023 (TI "TARGET_64BIT")])
1025 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1026 ;; compile time constant, it is faster to use <MODE_SIZE> than
1027 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1028 ;; command line options just use GET_MODE_SIZE macro.
1029 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1030 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1031 (V16QI "16") (V32QI "32") (V64QI "64")
1032 (V8HI "16") (V16HI "32") (V32HI "64")
1033 (V4SI "16") (V8SI "32") (V16SI "64")
1034 (V2DI "16") (V4DI "32") (V8DI "64")
1035 (V1TI "16") (V2TI "32") (V4TI "64")
1036 (V2DF "16") (V4DF "32") (V8DF "64")
1037 (V4SF "16") (V8SF "32") (V16SF "64")])
1039 ;; Double word integer modes as mode attribute.
1040 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1041 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1043 ;; LEA mode corresponding to an integer mode
1044 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1046 ;; Half mode for double word integer modes.
1047 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1048 (DI "TARGET_64BIT")])
1051 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1052 (BND64 "TARGET_LP64")])
1054 ;; Pointer mode corresponding to bound mode.
1055 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1058 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1061 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1063 (UNSPEC_BNDCN "cn")])
1065 ;; Instruction suffix for integer modes.
1066 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1068 ;; Instruction suffix for masks.
1069 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1071 ;; Pointer size prefix for integer modes (Intel asm dialect)
1072 (define_mode_attr iptrsize [(QI "BYTE")
1077 ;; Register class for integer modes.
1078 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1080 ;; Immediate operand constraint for integer modes.
1081 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1083 ;; General operand constraint for word modes.
1084 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1086 ;; Immediate operand constraint for double integer modes.
1087 (define_mode_attr di [(SI "nF") (DI "Wd")])
1089 ;; Immediate operand constraint for shifts.
1090 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1092 ;; General operand predicate for integer modes.
1093 (define_mode_attr general_operand
1094 [(QI "general_operand")
1095 (HI "general_operand")
1096 (SI "x86_64_general_operand")
1097 (DI "x86_64_general_operand")
1098 (TI "x86_64_general_operand")])
1100 ;; General operand predicate for integer modes, where for TImode
1101 ;; we need both words of the operand to be general operands.
1102 (define_mode_attr general_hilo_operand
1103 [(QI "general_operand")
1104 (HI "general_operand")
1105 (SI "x86_64_general_operand")
1106 (DI "x86_64_general_operand")
1107 (TI "x86_64_hilo_general_operand")])
1109 ;; General sign extend operand predicate for integer modes,
1110 ;; which disallows VOIDmode operands and thus it is suitable
1111 ;; for use inside sign_extend.
1112 (define_mode_attr general_sext_operand
1113 [(QI "sext_operand")
1115 (SI "x86_64_sext_operand")
1116 (DI "x86_64_sext_operand")])
1118 ;; General sign/zero extend operand predicate for integer modes.
1119 (define_mode_attr general_szext_operand
1120 [(QI "general_operand")
1121 (HI "general_operand")
1122 (SI "x86_64_szext_general_operand")
1123 (DI "x86_64_szext_general_operand")])
1125 ;; Immediate operand predicate for integer modes.
1126 (define_mode_attr immediate_operand
1127 [(QI "immediate_operand")
1128 (HI "immediate_operand")
1129 (SI "x86_64_immediate_operand")
1130 (DI "x86_64_immediate_operand")])
1132 ;; Nonmemory operand predicate for integer modes.
1133 (define_mode_attr nonmemory_operand
1134 [(QI "nonmemory_operand")
1135 (HI "nonmemory_operand")
1136 (SI "x86_64_nonmemory_operand")
1137 (DI "x86_64_nonmemory_operand")])
1139 ;; Operand predicate for shifts.
1140 (define_mode_attr shift_operand
1141 [(QI "nonimmediate_operand")
1142 (HI "nonimmediate_operand")
1143 (SI "nonimmediate_operand")
1144 (DI "shiftdi_operand")
1145 (TI "register_operand")])
1147 ;; Operand predicate for shift argument.
1148 (define_mode_attr shift_immediate_operand
1149 [(QI "const_1_to_31_operand")
1150 (HI "const_1_to_31_operand")
1151 (SI "const_1_to_31_operand")
1152 (DI "const_1_to_63_operand")])
1154 ;; Input operand predicate for arithmetic left shifts.
1155 (define_mode_attr ashl_input_operand
1156 [(QI "nonimmediate_operand")
1157 (HI "nonimmediate_operand")
1158 (SI "nonimmediate_operand")
1159 (DI "ashldi_input_operand")
1160 (TI "reg_or_pm1_operand")])
1162 ;; SSE and x87 SFmode and DFmode floating point modes
1163 (define_mode_iterator MODEF [SF DF])
1165 ;; All x87 floating point modes
1166 (define_mode_iterator X87MODEF [SF DF XF])
1168 ;; SSE instruction suffix for various modes
1169 (define_mode_attr ssemodesuffix
1170 [(SF "ss") (DF "sd")
1171 (V16SF "ps") (V8DF "pd")
1172 (V8SF "ps") (V4DF "pd")
1173 (V4SF "ps") (V2DF "pd")
1174 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1175 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1176 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1178 ;; SSE vector suffix for floating point modes
1179 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1181 ;; SSE vector mode corresponding to a scalar mode
1182 (define_mode_attr ssevecmode
1183 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1184 (define_mode_attr ssevecmodelower
1185 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1187 ;; AVX512F vector mode corresponding to a scalar mode
1188 (define_mode_attr avx512fvecmode
1189 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1191 ;; Instruction suffix for REX 64bit operators.
1192 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1194 ;; This mode iterator allows :P to be used for patterns that operate on
1195 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1196 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1198 ;; This mode iterator allows :W to be used for patterns that operate on
1199 ;; word_mode sized quantities.
1200 (define_mode_iterator W
1201 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1203 ;; This mode iterator allows :PTR to be used for patterns that operate on
1204 ;; ptr_mode sized quantities.
1205 (define_mode_iterator PTR
1206 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1208 ;; Scheduling descriptions
1210 (include "pentium.md")
1213 (include "athlon.md")
1214 (include "bdver1.md")
1215 (include "bdver3.md")
1216 (include "btver2.md")
1217 (include "znver1.md")
1218 (include "geode.md")
1221 (include "core2.md")
1222 (include "haswell.md")
1225 ;; Operand and operator predicates and constraints
1227 (include "predicates.md")
1228 (include "constraints.md")
1231 ;; Compare and branch/compare and store instructions.
1233 (define_expand "cbranch<mode>4"
1234 [(set (reg:CC FLAGS_REG)
1235 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1236 (match_operand:SDWIM 2 "<general_operand>")))
1237 (set (pc) (if_then_else
1238 (match_operator 0 "ordered_comparison_operator"
1239 [(reg:CC FLAGS_REG) (const_int 0)])
1240 (label_ref (match_operand 3))
1244 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1245 operands[1] = force_reg (<MODE>mode, operands[1]);
1246 ix86_expand_branch (GET_CODE (operands[0]),
1247 operands[1], operands[2], operands[3]);
1251 (define_expand "cstore<mode>4"
1252 [(set (reg:CC FLAGS_REG)
1253 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1254 (match_operand:SWIM 3 "<general_operand>")))
1255 (set (match_operand:QI 0 "register_operand")
1256 (match_operator 1 "ordered_comparison_operator"
1257 [(reg:CC FLAGS_REG) (const_int 0)]))]
1260 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1261 operands[2] = force_reg (<MODE>mode, operands[2]);
1262 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1263 operands[2], operands[3]);
1267 (define_expand "cmp<mode>_1"
1268 [(set (reg:CC FLAGS_REG)
1269 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1270 (match_operand:SWI48 1 "<general_operand>")))])
1272 (define_insn "*cmp<mode>_ccno_1"
1273 [(set (reg FLAGS_REG)
1274 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1275 (match_operand:SWI 1 "const0_operand")))]
1276 "ix86_match_ccmode (insn, CCNOmode)"
1278 test{<imodesuffix>}\t%0, %0
1279 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1280 [(set_attr "type" "test,icmp")
1281 (set_attr "length_immediate" "0,1")
1282 (set_attr "modrm_class" "op0,unknown")
1283 (set_attr "mode" "<MODE>")])
1285 (define_insn "*cmp<mode>_1"
1286 [(set (reg FLAGS_REG)
1287 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1288 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1289 "ix86_match_ccmode (insn, CCmode)"
1290 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1291 [(set_attr "type" "icmp")
1292 (set_attr "mode" "<MODE>")])
1294 (define_insn "*cmp<mode>_minus_1"
1295 [(set (reg FLAGS_REG)
1297 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1298 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1300 "ix86_match_ccmode (insn, CCGOCmode)"
1301 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1302 [(set_attr "type" "icmp")
1303 (set_attr "mode" "<MODE>")])
1305 (define_insn "*cmpqi_ext_1"
1306 [(set (reg FLAGS_REG)
1308 (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1311 (match_operand 1 "ext_register_operand" "Q,Q")
1313 (const_int 8)) 0)))]
1314 "ix86_match_ccmode (insn, CCmode)"
1315 "cmp{b}\t{%h1, %0|%0, %h1}"
1316 [(set_attr "isa" "*,nox64")
1317 (set_attr "type" "icmp")
1318 (set_attr "mode" "QI")])
1320 (define_insn "*cmpqi_ext_2"
1321 [(set (reg FLAGS_REG)
1325 (match_operand 0 "ext_register_operand" "Q")
1328 (match_operand:QI 1 "const0_operand")))]
1329 "ix86_match_ccmode (insn, CCNOmode)"
1331 [(set_attr "type" "test")
1332 (set_attr "length_immediate" "0")
1333 (set_attr "mode" "QI")])
1335 (define_expand "cmpqi_ext_3"
1336 [(set (reg:CC FLAGS_REG)
1340 (match_operand 0 "ext_register_operand")
1343 (match_operand:QI 1 "const_int_operand")))])
1345 (define_insn "*cmpqi_ext_3"
1346 [(set (reg FLAGS_REG)
1350 (match_operand 0 "ext_register_operand" "Q,Q")
1353 (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1354 "ix86_match_ccmode (insn, CCmode)"
1355 "cmp{b}\t{%1, %h0|%h0, %1}"
1356 [(set_attr "isa" "*,nox64")
1357 (set_attr "type" "icmp")
1358 (set_attr "modrm" "1")
1359 (set_attr "mode" "QI")])
1361 (define_insn "*cmpqi_ext_4"
1362 [(set (reg FLAGS_REG)
1366 (match_operand 0 "ext_register_operand" "Q")
1371 (match_operand 1 "ext_register_operand" "Q")
1373 (const_int 8)) 0)))]
1374 "ix86_match_ccmode (insn, CCmode)"
1375 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1376 [(set_attr "type" "icmp")
1377 (set_attr "mode" "QI")])
1379 ;; These implement float point compares.
1380 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1381 ;; which would allow mix and match FP modes on the compares. Which is what
1382 ;; the old patterns did, but with many more of them.
1384 (define_expand "cbranchxf4"
1385 [(set (reg:CC FLAGS_REG)
1386 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1387 (match_operand:XF 2 "nonmemory_operand")))
1388 (set (pc) (if_then_else
1389 (match_operator 0 "ix86_fp_comparison_operator"
1392 (label_ref (match_operand 3))
1396 ix86_expand_branch (GET_CODE (operands[0]),
1397 operands[1], operands[2], operands[3]);
1401 (define_expand "cstorexf4"
1402 [(set (reg:CC FLAGS_REG)
1403 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1404 (match_operand:XF 3 "nonmemory_operand")))
1405 (set (match_operand:QI 0 "register_operand")
1406 (match_operator 1 "ix86_fp_comparison_operator"
1411 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1412 operands[2], operands[3]);
1416 (define_expand "cbranch<mode>4"
1417 [(set (reg:CC FLAGS_REG)
1418 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1419 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1420 (set (pc) (if_then_else
1421 (match_operator 0 "ix86_fp_comparison_operator"
1424 (label_ref (match_operand 3))
1426 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1428 ix86_expand_branch (GET_CODE (operands[0]),
1429 operands[1], operands[2], operands[3]);
1433 (define_expand "cstore<mode>4"
1434 [(set (reg:CC FLAGS_REG)
1435 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1436 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1437 (set (match_operand:QI 0 "register_operand")
1438 (match_operator 1 "ix86_fp_comparison_operator"
1441 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1443 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1444 operands[2], operands[3]);
1448 (define_expand "cbranchcc4"
1449 [(set (pc) (if_then_else
1450 (match_operator 0 "comparison_operator"
1451 [(match_operand 1 "flags_reg_operand")
1452 (match_operand 2 "const0_operand")])
1453 (label_ref (match_operand 3))
1457 ix86_expand_branch (GET_CODE (operands[0]),
1458 operands[1], operands[2], operands[3]);
1462 (define_expand "cstorecc4"
1463 [(set (match_operand:QI 0 "register_operand")
1464 (match_operator 1 "comparison_operator"
1465 [(match_operand 2 "flags_reg_operand")
1466 (match_operand 3 "const0_operand")]))]
1469 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1470 operands[2], operands[3]);
1475 ;; FP compares, step 1:
1476 ;; Set the FP condition codes.
1478 ;; CCFPmode compare with exceptions
1479 ;; CCFPUmode compare with no exceptions
1481 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1482 ;; used to manage the reg stack popping would not be preserved.
1484 (define_insn "*cmp<mode>_0_i387"
1485 [(set (match_operand:HI 0 "register_operand" "=a")
1488 (match_operand:X87MODEF 1 "register_operand" "f")
1489 (match_operand:X87MODEF 2 "const0_operand"))]
1492 "* return output_fp_compare (insn, operands, false, false);"
1493 [(set_attr "type" "multi")
1494 (set_attr "unit" "i387")
1495 (set_attr "mode" "<MODE>")])
1497 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1498 [(set (reg:CCFP FLAGS_REG)
1500 (match_operand:X87MODEF 1 "register_operand" "f")
1501 (match_operand:X87MODEF 2 "const0_operand")))
1502 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1503 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1505 "&& reload_completed"
1508 [(compare:CCFP (match_dup 1)(match_dup 2))]
1510 (set (reg:CC FLAGS_REG)
1511 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1513 [(set_attr "type" "multi")
1514 (set_attr "unit" "i387")
1515 (set_attr "mode" "<MODE>")])
1517 (define_insn "*cmpxf_i387"
1518 [(set (match_operand:HI 0 "register_operand" "=a")
1521 (match_operand:XF 1 "register_operand" "f")
1522 (match_operand:XF 2 "register_operand" "f"))]
1525 "* return output_fp_compare (insn, operands, false, false);"
1526 [(set_attr "type" "multi")
1527 (set_attr "unit" "i387")
1528 (set_attr "mode" "XF")])
1530 (define_insn_and_split "*cmpxf_cc_i387"
1531 [(set (reg:CCFP FLAGS_REG)
1533 (match_operand:XF 1 "register_operand" "f")
1534 (match_operand:XF 2 "register_operand" "f")))
1535 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1536 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1538 "&& reload_completed"
1541 [(compare:CCFP (match_dup 1)(match_dup 2))]
1543 (set (reg:CC FLAGS_REG)
1544 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1546 [(set_attr "type" "multi")
1547 (set_attr "unit" "i387")
1548 (set_attr "mode" "XF")])
1550 (define_insn "*cmp<mode>_i387"
1551 [(set (match_operand:HI 0 "register_operand" "=a")
1554 (match_operand:MODEF 1 "register_operand" "f")
1555 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1558 "* return output_fp_compare (insn, operands, false, false);"
1559 [(set_attr "type" "multi")
1560 (set_attr "unit" "i387")
1561 (set_attr "mode" "<MODE>")])
1563 (define_insn_and_split "*cmp<mode>_cc_i387"
1564 [(set (reg:CCFP FLAGS_REG)
1566 (match_operand:MODEF 1 "register_operand" "f")
1567 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1568 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1569 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1571 "&& reload_completed"
1574 [(compare:CCFP (match_dup 1)(match_dup 2))]
1576 (set (reg:CC FLAGS_REG)
1577 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1579 [(set_attr "type" "multi")
1580 (set_attr "unit" "i387")
1581 (set_attr "mode" "<MODE>")])
1583 (define_insn "*cmpu<mode>_i387"
1584 [(set (match_operand:HI 0 "register_operand" "=a")
1587 (match_operand:X87MODEF 1 "register_operand" "f")
1588 (match_operand:X87MODEF 2 "register_operand" "f"))]
1591 "* return output_fp_compare (insn, operands, false, true);"
1592 [(set_attr "type" "multi")
1593 (set_attr "unit" "i387")
1594 (set_attr "mode" "<MODE>")])
1596 (define_insn_and_split "*cmpu<mode>_cc_i387"
1597 [(set (reg:CCFPU FLAGS_REG)
1599 (match_operand:X87MODEF 1 "register_operand" "f")
1600 (match_operand:X87MODEF 2 "register_operand" "f")))
1601 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1602 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1604 "&& reload_completed"
1607 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1609 (set (reg:CC FLAGS_REG)
1610 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1612 [(set_attr "type" "multi")
1613 (set_attr "unit" "i387")
1614 (set_attr "mode" "<MODE>")])
1616 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1617 [(set (match_operand:HI 0 "register_operand" "=a")
1620 (match_operand:X87MODEF 1 "register_operand" "f")
1621 (match_operator:X87MODEF 3 "float_operator"
1622 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1625 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1626 || optimize_function_for_size_p (cfun))"
1627 "* return output_fp_compare (insn, operands, false, false);"
1628 [(set_attr "type" "multi")
1629 (set_attr "unit" "i387")
1630 (set_attr "fp_int_src" "true")
1631 (set_attr "mode" "<SWI24:MODE>")])
1633 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1634 [(set (reg:CCFP FLAGS_REG)
1636 (match_operand:X87MODEF 1 "register_operand" "f")
1637 (match_operator:X87MODEF 3 "float_operator"
1638 [(match_operand:SWI24 2 "memory_operand" "m")])))
1639 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1640 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1641 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1642 || optimize_function_for_size_p (cfun))"
1644 "&& reload_completed"
1649 (match_op_dup 3 [(match_dup 2)]))]
1651 (set (reg:CC FLAGS_REG)
1652 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1654 [(set_attr "type" "multi")
1655 (set_attr "unit" "i387")
1656 (set_attr "fp_int_src" "true")
1657 (set_attr "mode" "<SWI24:MODE>")])
1659 ;; FP compares, step 2
1660 ;; Move the fpsw to ax.
1662 (define_insn "x86_fnstsw_1"
1663 [(set (match_operand:HI 0 "register_operand" "=a")
1664 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1667 [(set_attr "length" "2")
1668 (set_attr "mode" "SI")
1669 (set_attr "unit" "i387")])
1671 ;; FP compares, step 3
1672 ;; Get ax into flags, general case.
1674 (define_insn "x86_sahf_1"
1675 [(set (reg:CC FLAGS_REG)
1676 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1680 #ifndef HAVE_AS_IX86_SAHF
1682 return ASM_BYTE "0x9e";
1687 [(set_attr "length" "1")
1688 (set_attr "athlon_decode" "vector")
1689 (set_attr "amdfam10_decode" "direct")
1690 (set_attr "bdver1_decode" "direct")
1691 (set_attr "mode" "SI")])
1693 ;; Pentium Pro can do steps 1 through 3 in one go.
1694 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1695 ;; (these i387 instructions set flags directly)
1697 (define_mode_iterator FPCMP [CCFP CCFPU])
1698 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1700 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>"
1701 [(set (reg:FPCMP FLAGS_REG)
1703 (match_operand:MODEF 0 "register_operand" "f,v")
1704 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1705 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1706 || (TARGET_80387 && TARGET_CMOVE)"
1707 "* return output_fp_compare (insn, operands, true,
1708 <FPCMP:MODE>mode == CCFPUmode);"
1709 [(set_attr "type" "fcmp,ssecomi")
1710 (set_attr "prefix" "orig,maybe_vex")
1711 (set_attr "mode" "<MODEF:MODE>")
1712 (set_attr "prefix_rep" "*,0")
1713 (set (attr "prefix_data16")
1714 (cond [(eq_attr "alternative" "0")
1716 (eq_attr "mode" "DF")
1719 (const_string "0")))
1720 (set_attr "athlon_decode" "vector")
1721 (set_attr "amdfam10_decode" "direct")
1722 (set_attr "bdver1_decode" "double")
1723 (set_attr "znver1_decode" "double")
1724 (set (attr "enabled")
1726 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1728 (eq_attr "alternative" "0")
1729 (symbol_ref "TARGET_MIX_SSE_I387")
1730 (symbol_ref "true"))
1732 (eq_attr "alternative" "0")
1734 (symbol_ref "false"))))])
1736 (define_insn "*cmpi<unord>xf_i387"
1737 [(set (reg:FPCMP FLAGS_REG)
1739 (match_operand:XF 0 "register_operand" "f")
1740 (match_operand:XF 1 "register_operand" "f")))]
1741 "TARGET_80387 && TARGET_CMOVE"
1742 "* return output_fp_compare (insn, operands, true,
1743 <MODE>mode == CCFPUmode);"
1744 [(set_attr "type" "fcmp")
1745 (set_attr "mode" "XF")
1746 (set_attr "athlon_decode" "vector")
1747 (set_attr "amdfam10_decode" "direct")
1748 (set_attr "bdver1_decode" "double")
1749 (set_attr "znver1_decode" "double")])
1751 ;; Push/pop instructions.
1753 (define_insn "*push<mode>2"
1754 [(set (match_operand:DWI 0 "push_operand" "=<")
1755 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1758 [(set_attr "type" "multi")
1759 (set_attr "mode" "<MODE>")])
1762 [(set (match_operand:TI 0 "push_operand")
1763 (match_operand:TI 1 "general_operand"))]
1764 "TARGET_64BIT && reload_completed
1765 && !SSE_REG_P (operands[1])"
1767 "ix86_split_long_move (operands); DONE;")
1769 (define_insn "*pushdi2_rex64"
1770 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1771 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1776 [(set_attr "type" "push,multi")
1777 (set_attr "mode" "DI")])
1779 ;; Convert impossible pushes of immediate to existing instructions.
1780 ;; First try to get scratch register and go through it. In case this
1781 ;; fails, push sign extended lower part first and then overwrite
1782 ;; upper part by 32bit move.
1784 [(match_scratch:DI 2 "r")
1785 (set (match_operand:DI 0 "push_operand")
1786 (match_operand:DI 1 "immediate_operand"))]
1787 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1788 && !x86_64_immediate_operand (operands[1], DImode)"
1789 [(set (match_dup 2) (match_dup 1))
1790 (set (match_dup 0) (match_dup 2))])
1792 ;; We need to define this as both peepholer and splitter for case
1793 ;; peephole2 pass is not run.
1794 ;; "&& 1" is needed to keep it from matching the previous pattern.
1796 [(set (match_operand:DI 0 "push_operand")
1797 (match_operand:DI 1 "immediate_operand"))]
1798 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1799 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1800 [(set (match_dup 0) (match_dup 1))
1801 (set (match_dup 2) (match_dup 3))]
1803 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1805 operands[1] = gen_lowpart (DImode, operands[2]);
1806 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1811 [(set (match_operand:DI 0 "push_operand")
1812 (match_operand:DI 1 "immediate_operand"))]
1813 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1814 ? epilogue_completed : reload_completed)
1815 && !symbolic_operand (operands[1], DImode)
1816 && !x86_64_immediate_operand (operands[1], DImode)"
1817 [(set (match_dup 0) (match_dup 1))
1818 (set (match_dup 2) (match_dup 3))]
1820 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1822 operands[1] = gen_lowpart (DImode, operands[2]);
1823 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1828 [(set (match_operand:DI 0 "push_operand")
1829 (match_operand:DI 1 "general_operand"))]
1830 "!TARGET_64BIT && reload_completed
1831 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1833 "ix86_split_long_move (operands); DONE;")
1835 (define_insn "*pushsi2"
1836 [(set (match_operand:SI 0 "push_operand" "=<")
1837 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1840 [(set_attr "type" "push")
1841 (set_attr "mode" "SI")])
1843 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1844 ;; "push a byte/word". But actually we use pushl, which has the effect
1845 ;; of rounding the amount pushed up to a word.
1847 ;; For TARGET_64BIT we always round up to 8 bytes.
1848 (define_insn "*push<mode>2_rex64"
1849 [(set (match_operand:SWI124 0 "push_operand" "=X")
1850 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1853 [(set_attr "type" "push")
1854 (set_attr "mode" "DI")])
1856 (define_insn "*push<mode>2"
1857 [(set (match_operand:SWI12 0 "push_operand" "=X")
1858 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1861 [(set_attr "type" "push")
1862 (set_attr "mode" "SI")])
1864 (define_insn "*push<mode>2_prologue"
1865 [(set (match_operand:W 0 "push_operand" "=<")
1866 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1867 (clobber (mem:BLK (scratch)))]
1869 "push{<imodesuffix>}\t%1"
1870 [(set_attr "type" "push")
1871 (set_attr "mode" "<MODE>")])
1873 (define_insn "*pop<mode>1"
1874 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1875 (match_operand:W 1 "pop_operand" ">"))]
1877 "pop{<imodesuffix>}\t%0"
1878 [(set_attr "type" "pop")
1879 (set_attr "mode" "<MODE>")])
1881 (define_insn "*pop<mode>1_epilogue"
1882 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1883 (match_operand:W 1 "pop_operand" ">"))
1884 (clobber (mem:BLK (scratch)))]
1886 "pop{<imodesuffix>}\t%0"
1887 [(set_attr "type" "pop")
1888 (set_attr "mode" "<MODE>")])
1890 (define_insn "*pushfl<mode>2"
1891 [(set (match_operand:W 0 "push_operand" "=<")
1892 (match_operand:W 1 "flags_reg_operand"))]
1894 "pushf{<imodesuffix>}"
1895 [(set_attr "type" "push")
1896 (set_attr "mode" "<MODE>")])
1898 (define_insn "*popfl<mode>1"
1899 [(set (match_operand:W 0 "flags_reg_operand")
1900 (match_operand:W 1 "pop_operand" ">"))]
1902 "popf{<imodesuffix>}"
1903 [(set_attr "type" "pop")
1904 (set_attr "mode" "<MODE>")])
1907 ;; Reload patterns to support multi-word load/store
1908 ;; with non-offsetable address.
1909 (define_expand "reload_noff_store"
1910 [(parallel [(match_operand 0 "memory_operand" "=m")
1911 (match_operand 1 "register_operand" "r")
1912 (match_operand:DI 2 "register_operand" "=&r")])]
1915 rtx mem = operands[0];
1916 rtx addr = XEXP (mem, 0);
1918 emit_move_insn (operands[2], addr);
1919 mem = replace_equiv_address_nv (mem, operands[2]);
1921 emit_insn (gen_rtx_SET (mem, operands[1]));
1925 (define_expand "reload_noff_load"
1926 [(parallel [(match_operand 0 "register_operand" "=r")
1927 (match_operand 1 "memory_operand" "m")
1928 (match_operand:DI 2 "register_operand" "=r")])]
1931 rtx mem = operands[1];
1932 rtx addr = XEXP (mem, 0);
1934 emit_move_insn (operands[2], addr);
1935 mem = replace_equiv_address_nv (mem, operands[2]);
1937 emit_insn (gen_rtx_SET (operands[0], mem));
1941 ;; Move instructions.
1943 (define_expand "movxi"
1944 [(set (match_operand:XI 0 "nonimmediate_operand")
1945 (match_operand:XI 1 "general_operand"))]
1947 "ix86_expand_vector_move (XImode, operands); DONE;")
1949 (define_expand "movoi"
1950 [(set (match_operand:OI 0 "nonimmediate_operand")
1951 (match_operand:OI 1 "general_operand"))]
1953 "ix86_expand_vector_move (OImode, operands); DONE;")
1955 (define_expand "movti"
1956 [(set (match_operand:TI 0 "nonimmediate_operand")
1957 (match_operand:TI 1 "general_operand"))]
1958 "TARGET_64BIT || TARGET_SSE"
1961 ix86_expand_move (TImode, operands);
1963 ix86_expand_vector_move (TImode, operands);
1967 ;; This expands to what emit_move_complex would generate if we didn't
1968 ;; have a movti pattern. Having this avoids problems with reload on
1969 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1970 ;; to have around all the time.
1971 (define_expand "movcdi"
1972 [(set (match_operand:CDI 0 "nonimmediate_operand")
1973 (match_operand:CDI 1 "general_operand"))]
1976 if (push_operand (operands[0], CDImode))
1977 emit_move_complex_push (CDImode, operands[0], operands[1]);
1979 emit_move_complex_parts (operands[0], operands[1]);
1983 (define_expand "mov<mode>"
1984 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1985 (match_operand:SWI1248x 1 "general_operand"))]
1987 "ix86_expand_move (<MODE>mode, operands); DONE;")
1989 (define_insn "*mov<mode>_xor"
1990 [(set (match_operand:SWI48 0 "register_operand" "=r")
1991 (match_operand:SWI48 1 "const0_operand"))
1992 (clobber (reg:CC FLAGS_REG))]
1995 [(set_attr "type" "alu1")
1996 (set_attr "modrm_class" "op0")
1997 (set_attr "mode" "SI")
1998 (set_attr "length_immediate" "0")])
2000 (define_insn "*mov<mode>_or"
2001 [(set (match_operand:SWI48 0 "register_operand" "=r")
2002 (match_operand:SWI48 1 "constm1_operand"))
2003 (clobber (reg:CC FLAGS_REG))]
2005 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
2006 [(set_attr "type" "alu1")
2007 (set_attr "mode" "<MODE>")
2008 (set_attr "length_immediate" "1")])
2010 (define_insn "*movxi_internal_avx512f"
2011 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m")
2012 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2014 && (register_operand (operands[0], XImode)
2015 || register_operand (operands[1], XImode))"
2017 switch (get_attr_type (insn))
2020 return standard_sse_constant_opcode (insn, operands[1]);
2023 if (misaligned_operand (operands[0], XImode)
2024 || misaligned_operand (operands[1], XImode))
2025 return "vmovdqu32\t{%1, %0|%0, %1}";
2027 return "vmovdqa32\t{%1, %0|%0, %1}";
2033 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2034 (set_attr "prefix" "evex")
2035 (set_attr "mode" "XI")])
2037 (define_insn "*movoi_internal_avx"
2038 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m")
2039 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2041 && (register_operand (operands[0], OImode)
2042 || register_operand (operands[1], OImode))"
2044 switch (get_attr_type (insn))
2047 return standard_sse_constant_opcode (insn, operands[1]);
2050 if (misaligned_operand (operands[0], OImode)
2051 || misaligned_operand (operands[1], OImode))
2053 if (get_attr_mode (insn) == MODE_V8SF)
2054 return "vmovups\t{%1, %0|%0, %1}";
2055 else if (get_attr_mode (insn) == MODE_XI)
2056 return "vmovdqu32\t{%1, %0|%0, %1}";
2058 return "vmovdqu\t{%1, %0|%0, %1}";
2062 if (get_attr_mode (insn) == MODE_V8SF)
2063 return "vmovaps\t{%1, %0|%0, %1}";
2064 else if (get_attr_mode (insn) == MODE_XI)
2065 return "vmovdqa32\t{%1, %0|%0, %1}";
2067 return "vmovdqa\t{%1, %0|%0, %1}";
2074 [(set_attr "isa" "*,avx2,*,*")
2075 (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2076 (set_attr "prefix" "vex")
2078 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2079 (match_operand 1 "ext_sse_reg_operand"))
2081 (and (eq_attr "alternative" "1")
2082 (match_test "TARGET_AVX512VL"))
2084 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2085 (and (eq_attr "alternative" "3")
2086 (match_test "TARGET_SSE_TYPELESS_STORES")))
2087 (const_string "V8SF")
2089 (const_string "OI")))])
2091 (define_insn "*movti_internal"
2092 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m")
2093 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v"))]
2095 && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2097 && nonimmediate_or_sse_const_operand (operands[1], TImode)
2098 && (register_operand (operands[0], TImode)
2099 || register_operand (operands[1], TImode)))"
2101 switch (get_attr_type (insn))
2107 return standard_sse_constant_opcode (insn, operands[1]);
2110 /* TDmode values are passed as TImode on the stack. Moving them
2111 to stack may result in unaligned memory access. */
2112 if (misaligned_operand (operands[0], TImode)
2113 || misaligned_operand (operands[1], TImode))
2115 if (get_attr_mode (insn) == MODE_V4SF)
2116 return "%vmovups\t{%1, %0|%0, %1}";
2117 else if (get_attr_mode (insn) == MODE_XI)
2118 return "vmovdqu32\t{%1, %0|%0, %1}";
2120 return "%vmovdqu\t{%1, %0|%0, %1}";
2124 if (get_attr_mode (insn) == MODE_V4SF)
2125 return "%vmovaps\t{%1, %0|%0, %1}";
2126 else if (get_attr_mode (insn) == MODE_XI)
2127 return "vmovdqa32\t{%1, %0|%0, %1}";
2129 return "%vmovdqa\t{%1, %0|%0, %1}";
2136 [(set_attr "isa" "x64,x64,*,sse2,*,*")
2137 (set_attr "type" "multi,multi,sselog1,sselog1,ssemov,ssemov")
2138 (set (attr "prefix")
2139 (if_then_else (eq_attr "type" "sselog1,ssemov")
2140 (const_string "maybe_vex")
2141 (const_string "orig")))
2143 (cond [(eq_attr "alternative" "0,1")
2145 (ior (match_operand 0 "ext_sse_reg_operand")
2146 (match_operand 1 "ext_sse_reg_operand"))
2148 (and (eq_attr "alternative" "3")
2149 (match_test "TARGET_AVX512VL"))
2151 (ior (not (match_test "TARGET_SSE2"))
2152 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2153 (and (eq_attr "alternative" "5")
2154 (match_test "TARGET_SSE_TYPELESS_STORES"))))
2155 (const_string "V4SF")
2156 (match_test "TARGET_AVX")
2158 (match_test "optimize_function_for_size_p (cfun)")
2159 (const_string "V4SF")
2161 (const_string "TI")))])
2164 [(set (match_operand:TI 0 "nonimmediate_operand")
2165 (match_operand:TI 1 "general_operand"))]
2167 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2169 "ix86_split_long_move (operands); DONE;")
2171 (define_insn "*movdi_internal"
2172 [(set (match_operand:DI 0 "nonimmediate_operand"
2173 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,m,?r ,?r,?*Yi,?*Ym,?*Yi,*k,*k ,*r ,*m")
2174 (match_operand:DI 1 "general_operand"
2175 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,v,*Yj,*v,r ,*Yj ,*Yn ,*r ,*km,*k,*k"))]
2176 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2178 switch (get_attr_type (insn))
2181 return "kmovq\t{%1, %0|%0, %1}";
2187 return "pxor\t%0, %0";
2190 /* Handle broken assemblers that require movd instead of movq. */
2191 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2192 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2193 return "movd\t{%1, %0|%0, %1}";
2194 return "movq\t{%1, %0|%0, %1}";
2197 if (GENERAL_REG_P (operands[0]))
2198 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2200 return standard_sse_constant_opcode (insn, operands[1]);
2203 switch (get_attr_mode (insn))
2206 /* Handle broken assemblers that require movd instead of movq. */
2207 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2208 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2209 return "%vmovd\t{%1, %0|%0, %1}";
2210 return "%vmovq\t{%1, %0|%0, %1}";
2212 return "%vmovdqa\t{%1, %0|%0, %1}";
2214 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2217 gcc_assert (!TARGET_AVX);
2218 return "movlps\t{%1, %0|%0, %1}";
2220 return "%vmovaps\t{%1, %0|%0, %1}";
2227 if (SSE_REG_P (operands[0]))
2228 return "movq2dq\t{%1, %0|%0, %1}";
2230 return "movdq2q\t{%1, %0|%0, %1}";
2233 return "lea{q}\t{%E1, %0|%0, %E1}";
2236 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2237 if (get_attr_mode (insn) == MODE_SI)
2238 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2239 else if (which_alternative == 4)
2240 return "movabs{q}\t{%1, %0|%0, %1}";
2241 else if (ix86_use_lea_for_mov (insn, operands))
2242 return "lea{q}\t{%E1, %0|%0, %E1}";
2244 return "mov{q}\t{%1, %0|%0, %1}";
2251 (cond [(eq_attr "alternative" "0,1")
2252 (const_string "nox64")
2253 (eq_attr "alternative" "2,3,4,5,10,11,17,19,22,24")
2254 (const_string "x64")
2255 (eq_attr "alternative" "18")
2256 (const_string "x64_sse4")
2258 (const_string "*")))
2260 (cond [(eq_attr "alternative" "0,1")
2261 (const_string "multi")
2262 (eq_attr "alternative" "6")
2263 (const_string "mmx")
2264 (eq_attr "alternative" "7,8,9,10,11")
2265 (const_string "mmxmov")
2266 (eq_attr "alternative" "12,18")
2267 (const_string "sselog1")
2268 (eq_attr "alternative" "13,14,15,16,17,19")
2269 (const_string "ssemov")
2270 (eq_attr "alternative" "20,21")
2271 (const_string "ssecvt")
2272 (eq_attr "alternative" "22,23,24,25")
2273 (const_string "mskmov")
2274 (and (match_operand 0 "register_operand")
2275 (match_operand 1 "pic_32bit_operand"))
2276 (const_string "lea")
2278 (const_string "imov")))
2281 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2283 (const_string "*")))
2284 (set (attr "length_immediate")
2285 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2287 (eq_attr "alternative" "18")
2290 (const_string "*")))
2291 (set (attr "prefix_rex")
2292 (if_then_else (eq_attr "alternative" "10,11,17,18,19")
2294 (const_string "*")))
2295 (set (attr "prefix_extra")
2296 (if_then_else (eq_attr "alternative" "18")
2298 (const_string "*")))
2299 (set (attr "prefix")
2300 (if_then_else (eq_attr "type" "sselog1,ssemov")
2301 (const_string "maybe_vex")
2302 (const_string "orig")))
2303 (set (attr "prefix_data16")
2304 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2306 (const_string "*")))
2308 (cond [(eq_attr "alternative" "2")
2310 (eq_attr "alternative" "12,13")
2311 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2312 (match_operand 1 "ext_sse_reg_operand"))
2314 (ior (not (match_test "TARGET_SSE2"))
2315 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2316 (const_string "V4SF")
2317 (match_test "TARGET_AVX")
2319 (match_test "optimize_function_for_size_p (cfun)")
2320 (const_string "V4SF")
2322 (const_string "TI"))
2324 (and (eq_attr "alternative" "14,15,16")
2325 (not (match_test "TARGET_SSE2")))
2326 (const_string "V2SF")
2327 (eq_attr "alternative" "18")
2330 (const_string "DI")))
2331 (set (attr "enabled")
2332 (cond [(eq_attr "alternative" "15")
2334 (match_test "TARGET_STV && TARGET_SSE2")
2335 (symbol_ref "false")
2337 (eq_attr "alternative" "16")
2339 (match_test "TARGET_STV && TARGET_SSE2")
2341 (symbol_ref "false"))
2343 (const_string "*")))])
2346 [(set (match_operand:DI 0 "nonimmediate_operand")
2347 (match_operand:DI 1 "general_operand"))]
2348 "!TARGET_64BIT && reload_completed
2349 && !(MMX_REG_P (operands[0])
2350 || SSE_REG_P (operands[0])
2351 || MASK_REG_P (operands[0]))
2352 && !(MMX_REG_P (operands[1])
2353 || SSE_REG_P (operands[1])
2354 || MASK_REG_P (operands[1]))"
2356 "ix86_split_long_move (operands); DONE;")
2358 (define_insn "*movsi_internal"
2359 [(set (match_operand:SI 0 "nonimmediate_operand"
2360 "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k ,*rm")
2361 (match_operand:SI 1 "general_operand"
2362 "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r ,*krm,*k"))]
2363 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2365 switch (get_attr_type (insn))
2368 if (GENERAL_REG_P (operands[0]))
2369 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2371 return standard_sse_constant_opcode (insn, operands[1]);
2374 return "kmovd\t{%1, %0|%0, %1}";
2377 switch (get_attr_mode (insn))
2380 return "%vmovd\t{%1, %0|%0, %1}";
2382 return "%vmovdqa\t{%1, %0|%0, %1}";
2384 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2387 return "%vmovaps\t{%1, %0|%0, %1}";
2390 gcc_assert (!TARGET_AVX);
2391 return "movss\t{%1, %0|%0, %1}";
2398 return "pxor\t%0, %0";
2401 switch (get_attr_mode (insn))
2404 return "movq\t{%1, %0|%0, %1}";
2406 return "movd\t{%1, %0|%0, %1}";
2413 return "lea{l}\t{%E1, %0|%0, %E1}";
2416 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2417 if (ix86_use_lea_for_mov (insn, operands))
2418 return "lea{l}\t{%E1, %0|%0, %E1}";
2420 return "mov{l}\t{%1, %0|%0, %1}";
2427 (if_then_else (eq_attr "alternative" "11")
2428 (const_string "sse4")
2429 (const_string "*")))
2431 (cond [(eq_attr "alternative" "2")
2432 (const_string "mmx")
2433 (eq_attr "alternative" "3,4,5")
2434 (const_string "mmxmov")
2435 (eq_attr "alternative" "6,11")
2436 (const_string "sselog1")
2437 (eq_attr "alternative" "7,8,9,10,12")
2438 (const_string "ssemov")
2439 (eq_attr "alternative" "13,14")
2440 (const_string "mskmov")
2441 (and (match_operand 0 "register_operand")
2442 (match_operand 1 "pic_32bit_operand"))
2443 (const_string "lea")
2445 (const_string "imov")))
2446 (set (attr "length_immediate")
2447 (if_then_else (eq_attr "alternative" "11")
2449 (const_string "*")))
2450 (set (attr "prefix_extra")
2451 (if_then_else (eq_attr "alternative" "11")
2453 (const_string "*")))
2454 (set (attr "prefix")
2455 (if_then_else (eq_attr "type" "sselog1,ssemov")
2456 (const_string "maybe_vex")
2457 (const_string "orig")))
2458 (set (attr "prefix_data16")
2459 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2461 (const_string "*")))
2463 (cond [(eq_attr "alternative" "2,3")
2465 (eq_attr "alternative" "6,7")
2466 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2467 (match_operand 1 "ext_sse_reg_operand"))
2469 (ior (not (match_test "TARGET_SSE2"))
2470 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2471 (const_string "V4SF")
2472 (match_test "TARGET_AVX")
2474 (match_test "optimize_function_for_size_p (cfun)")
2475 (const_string "V4SF")
2477 (const_string "TI"))
2479 (and (eq_attr "alternative" "8,9")
2480 (not (match_test "TARGET_SSE2")))
2482 (eq_attr "alternative" "11")
2485 (const_string "SI")))])
2487 (define_insn "kmovw"
2488 [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2490 [(match_operand:HI 1 "nonimmediate_operand" "r,km")]
2492 "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2494 kmovw\t{%k1, %0|%0, %k1}
2495 kmovw\t{%1, %0|%0, %1}";
2496 [(set_attr "mode" "HI")
2497 (set_attr "type" "mskmov")
2498 (set_attr "prefix" "vex")])
2501 (define_insn "*movhi_internal"
2502 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k, r,m")
2503 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,r,km,k,k"))]
2504 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2506 switch (get_attr_type (insn))
2509 /* movzwl is faster than movw on p2 due to partial word stalls,
2510 though not as fast as an aligned movl. */
2511 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2514 switch (which_alternative)
2516 case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2517 case 5: /* FALLTHRU */
2518 case 7: return "kmovw\t{%1, %0|%0, %1}";
2519 case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2520 default: gcc_unreachable ();
2524 if (get_attr_mode (insn) == MODE_SI)
2525 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2527 return "mov{w}\t{%1, %0|%0, %1}";
2531 (cond [(eq_attr "alternative" "4,5,6,7")
2532 (const_string "mskmov")
2533 (match_test "optimize_function_for_size_p (cfun)")
2534 (const_string "imov")
2535 (and (eq_attr "alternative" "0")
2536 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2537 (not (match_test "TARGET_HIMODE_MATH"))))
2538 (const_string "imov")
2539 (and (eq_attr "alternative" "1,2")
2540 (match_operand:HI 1 "aligned_operand"))
2541 (const_string "imov")
2542 (and (match_test "TARGET_MOVX")
2543 (eq_attr "alternative" "0,2"))
2544 (const_string "imovx")
2546 (const_string "imov")))
2547 (set (attr "prefix")
2548 (if_then_else (eq_attr "alternative" "4,5,6,7")
2549 (const_string "vex")
2550 (const_string "orig")))
2552 (cond [(eq_attr "type" "imovx")
2554 (and (eq_attr "alternative" "1,2")
2555 (match_operand:HI 1 "aligned_operand"))
2557 (and (eq_attr "alternative" "0")
2558 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2559 (not (match_test "TARGET_HIMODE_MATH"))))
2562 (const_string "HI")))])
2564 ;; Situation is quite tricky about when to choose full sized (SImode) move
2565 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2566 ;; partial register dependency machines (such as AMD Athlon), where QImode
2567 ;; moves issue extra dependency and for partial register stalls machines
2568 ;; that don't use QImode patterns (and QImode move cause stall on the next
2571 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2572 ;; register stall machines with, where we use QImode instructions, since
2573 ;; partial register stall can be caused there. Then we use movzx.
2575 (define_insn "*movqi_internal"
2576 [(set (match_operand:QI 0 "nonimmediate_operand"
2577 "=q,q ,q ,r,r ,?r,m ,k,k,r ,m,k")
2578 (match_operand:QI 1 "general_operand"
2579 "q ,qn,qm,q,rn,qm,qn,r ,k,k,k,m"))]
2580 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2582 switch (get_attr_type (insn))
2585 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2586 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2589 switch (which_alternative)
2591 case 7: return TARGET_AVX512DQ ? "kmovb\t{%k1, %0|%0, %k1}"
2592 : "kmovw\t{%k1, %0|%0, %k1}";
2593 case 8: return TARGET_AVX512DQ ? "kmovb\t{%1, %0|%0, %1}"
2594 : "kmovw\t{%1, %0|%0, %1}";
2595 case 9: return TARGET_AVX512DQ ? "kmovb\t{%1, %k0|%k0, %1}"
2596 : "kmovw\t{%1, %k0|%k0, %1}";
2599 gcc_assert (TARGET_AVX512DQ);
2600 return "kmovb\t{%1, %0|%0, %1}";
2601 default: gcc_unreachable ();
2605 if (get_attr_mode (insn) == MODE_SI)
2606 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2608 return "mov{b}\t{%1, %0|%0, %1}";
2612 (if_then_else (eq_attr "alternative" "10,11")
2613 (const_string "avx512dq")
2614 (const_string "*")))
2616 (cond [(eq_attr "alternative" "7,8,9,10,11")
2617 (const_string "mskmov")
2618 (and (eq_attr "alternative" "5")
2619 (not (match_operand:QI 1 "aligned_operand")))
2620 (const_string "imovx")
2621 (match_test "optimize_function_for_size_p (cfun)")
2622 (const_string "imov")
2623 (and (eq_attr "alternative" "3")
2624 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2625 (not (match_test "TARGET_QIMODE_MATH"))))
2626 (const_string "imov")
2627 (eq_attr "alternative" "3,5")
2628 (const_string "imovx")
2629 (and (match_test "TARGET_MOVX")
2630 (eq_attr "alternative" "2"))
2631 (const_string "imovx")
2633 (const_string "imov")))
2634 (set (attr "prefix")
2635 (if_then_else (eq_attr "alternative" "7,8,9")
2636 (const_string "vex")
2637 (const_string "orig")))
2639 (cond [(eq_attr "alternative" "3,4,5")
2641 (eq_attr "alternative" "6")
2643 (eq_attr "type" "imovx")
2645 (and (eq_attr "type" "imov")
2646 (and (eq_attr "alternative" "0,1")
2647 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2648 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2649 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2651 ;; Avoid partial register stalls when not using QImode arithmetic
2652 (and (eq_attr "type" "imov")
2653 (and (eq_attr "alternative" "0,1")
2654 (and (match_test "TARGET_PARTIAL_REG_STALL")
2655 (not (match_test "TARGET_QIMODE_MATH")))))
2658 (const_string "QI")))])
2660 ;; Stores and loads of ax to arbitrary constant address.
2661 ;; We fake an second form of instruction to force reload to load address
2662 ;; into register when rax is not available
2663 (define_insn "*movabs<mode>_1"
2664 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2665 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2666 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2668 /* Recover the full memory rtx. */
2669 operands[0] = SET_DEST (PATTERN (insn));
2670 switch (which_alternative)
2673 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2675 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2680 [(set_attr "type" "imov")
2681 (set_attr "modrm" "0,*")
2682 (set_attr "length_address" "8,0")
2683 (set_attr "length_immediate" "0,*")
2684 (set_attr "memory" "store")
2685 (set_attr "mode" "<MODE>")])
2687 (define_insn "*movabs<mode>_2"
2688 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2689 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2690 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2692 /* Recover the full memory rtx. */
2693 operands[1] = SET_SRC (PATTERN (insn));
2694 switch (which_alternative)
2697 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2699 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2704 [(set_attr "type" "imov")
2705 (set_attr "modrm" "0,*")
2706 (set_attr "length_address" "8,0")
2707 (set_attr "length_immediate" "0")
2708 (set_attr "memory" "load")
2709 (set_attr "mode" "<MODE>")])
2711 (define_insn "*swap<mode>"
2712 [(set (match_operand:SWI48 0 "register_operand" "+r")
2713 (match_operand:SWI48 1 "register_operand" "+r"))
2717 "xchg{<imodesuffix>}\t%1, %0"
2718 [(set_attr "type" "imov")
2719 (set_attr "mode" "<MODE>")
2720 (set_attr "pent_pair" "np")
2721 (set_attr "athlon_decode" "vector")
2722 (set_attr "amdfam10_decode" "double")
2723 (set_attr "bdver1_decode" "double")])
2725 (define_insn "*swap<mode>"
2726 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2727 (match_operand:SWI12 1 "register_operand" "+<r>,r"))
2732 xchg{<imodesuffix>}\t%1, %0
2734 [(set_attr "type" "imov")
2735 (set_attr "mode" "<MODE>,SI")
2736 (set (attr "preferred_for_size")
2737 (cond [(eq_attr "alternative" "0")
2738 (symbol_ref "false")]
2739 (symbol_ref "true")))
2740 ;; Potential partial reg stall on alternative 1.
2741 (set (attr "preferred_for_speed")
2742 (cond [(eq_attr "alternative" "1")
2743 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2744 (symbol_ref "true")))
2745 (set_attr "pent_pair" "np")
2746 (set_attr "athlon_decode" "vector")
2747 (set_attr "amdfam10_decode" "double")
2748 (set_attr "bdver1_decode" "double")])
2750 (define_expand "movstrict<mode>"
2751 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2752 (match_operand:SWI12 1 "general_operand"))]
2755 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2757 if (SUBREG_P (operands[0])
2758 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2760 /* Don't generate memory->memory moves, go through a register */
2761 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2762 operands[1] = force_reg (<MODE>mode, operands[1]);
2765 (define_insn "*movstrict<mode>_1"
2766 [(set (strict_low_part
2767 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2768 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2769 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2770 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2771 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2772 [(set_attr "type" "imov")
2773 (set_attr "mode" "<MODE>")])
2775 (define_insn "*movstrict<mode>_xor"
2776 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2777 (match_operand:SWI12 1 "const0_operand"))
2778 (clobber (reg:CC FLAGS_REG))]
2780 "xor{<imodesuffix>}\t%0, %0"
2781 [(set_attr "type" "alu1")
2782 (set_attr "modrm_class" "op0")
2783 (set_attr "mode" "<MODE>")
2784 (set_attr "length_immediate" "0")])
2786 (define_expand "extv<mode>"
2787 [(set (match_operand:SWI24 0 "register_operand")
2788 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2789 (match_operand:SI 2 "const_int_operand")
2790 (match_operand:SI 3 "const_int_operand")))]
2793 /* Handle extractions from %ah et al. */
2794 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2797 if (! ext_register_operand (operands[1], VOIDmode))
2798 operands[1] = copy_to_reg (operands[1]);
2801 (define_insn "*extv<mode>"
2802 [(set (match_operand:SWI24 0 "register_operand" "=R")
2803 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2807 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2808 [(set_attr "type" "imovx")
2809 (set_attr "mode" "SI")])
2811 (define_insn "*extvqi"
2812 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2813 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2818 switch (get_attr_type (insn))
2821 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2823 return "mov{b}\t{%h1, %0|%0, %h1}";
2826 [(set_attr "isa" "*,*,nox64")
2828 (if_then_else (and (match_operand:QI 0 "register_operand")
2829 (ior (not (match_operand:QI 0 "QIreg_operand"))
2830 (match_test "TARGET_MOVX")))
2831 (const_string "imovx")
2832 (const_string "imov")))
2834 (if_then_else (eq_attr "type" "imovx")
2836 (const_string "QI")))])
2838 (define_expand "extzv<mode>"
2839 [(set (match_operand:SWI248 0 "register_operand")
2840 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2841 (match_operand:SI 2 "const_int_operand")
2842 (match_operand:SI 3 "const_int_operand")))]
2845 if (ix86_expand_pextr (operands))
2848 /* Handle extractions from %ah et al. */
2849 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2852 if (! ext_register_operand (operands[1], VOIDmode))
2853 operands[1] = copy_to_reg (operands[1]);
2856 (define_insn "*extzv<mode>"
2857 [(set (match_operand:SWI248 0 "register_operand" "=R")
2858 (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2862 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2863 [(set_attr "type" "imovx")
2864 (set_attr "mode" "SI")])
2866 (define_insn "*extzvqi"
2867 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2869 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2874 switch (get_attr_type (insn))
2877 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2879 return "mov{b}\t{%h1, %0|%0, %h1}";
2882 [(set_attr "isa" "*,*,nox64")
2884 (if_then_else (and (match_operand:QI 0 "register_operand")
2885 (ior (not (match_operand:QI 0 "QIreg_operand"))
2886 (match_test "TARGET_MOVX")))
2887 (const_string "imovx")
2888 (const_string "imov")))
2890 (if_then_else (eq_attr "type" "imovx")
2892 (const_string "QI")))])
2894 (define_expand "insv<mode>"
2895 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
2896 (match_operand:SI 1 "const_int_operand")
2897 (match_operand:SI 2 "const_int_operand"))
2898 (match_operand:SWI248 3 "register_operand"))]
2903 if (ix86_expand_pinsr (operands))
2906 /* Handle insertions to %ah et al. */
2907 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
2912 if (!ext_register_operand (dst, VOIDmode))
2913 dst = copy_to_reg (dst);
2915 emit_insn (gen_insv<mode>_1 (dst, operands[3]));
2917 /* Fix up the destination if needed. */
2918 if (dst != operands[0])
2919 emit_move_insn (operands[0], dst);
2924 (define_insn "insv<mode>_1"
2925 [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
2928 (match_operand:SWI248 1 "general_x64nomem_operand" "Qn,m"))]
2931 if (CONST_INT_P (operands[1]))
2932 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
2933 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2935 [(set_attr "isa" "*,nox64")
2936 (set_attr "type" "imov")
2937 (set_attr "mode" "QI")])
2939 (define_insn "*insvqi"
2940 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2943 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2946 "mov{b}\t{%h1, %h0|%h0, %h1}"
2947 [(set_attr "type" "imov")
2948 (set_attr "mode" "QI")])
2950 ;; Floating point push instructions.
2952 (define_insn "*pushtf"
2953 [(set (match_operand:TF 0 "push_operand" "=<,<")
2954 (match_operand:TF 1 "general_no_elim_operand" "v,*roF"))]
2955 "TARGET_64BIT || TARGET_SSE"
2957 /* This insn should be already split before reg-stack. */
2960 [(set_attr "isa" "*,x64")
2961 (set_attr "type" "multi")
2962 (set_attr "unit" "sse,*")
2963 (set_attr "mode" "TF,DI")])
2965 ;; %%% Kill this when call knows how to work this out.
2967 [(set (match_operand:TF 0 "push_operand")
2968 (match_operand:TF 1 "sse_reg_operand"))]
2969 "TARGET_SSE && reload_completed"
2970 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2971 (set (match_dup 0) (match_dup 1))]
2973 /* Preserve memory attributes. */
2974 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2977 (define_insn "*pushxf"
2978 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<")
2979 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF"))]
2982 /* This insn should be already split before reg-stack. */
2985 [(set_attr "type" "multi")
2986 (set_attr "unit" "i387,*,*,*")
2988 (cond [(eq_attr "alternative" "1,2,3")
2989 (if_then_else (match_test "TARGET_64BIT")
2991 (const_string "SI"))
2993 (const_string "XF")))
2994 (set (attr "preferred_for_size")
2995 (cond [(eq_attr "alternative" "1")
2996 (symbol_ref "false")]
2997 (symbol_ref "true")))])
2999 ;; %%% Kill this when call knows how to work this out.
3001 [(set (match_operand:XF 0 "push_operand")
3002 (match_operand:XF 1 "fp_register_operand"))]
3004 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3005 (set (match_dup 0) (match_dup 1))]
3007 operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
3008 /* Preserve memory attributes. */
3009 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3012 (define_insn "*pushdf"
3013 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3014 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmF,x"))]
3017 /* This insn should be already split before reg-stack. */
3020 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3021 (set_attr "type" "multi")
3022 (set_attr "unit" "i387,*,*,*,*,sse")
3023 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3024 (set (attr "preferred_for_size")
3025 (cond [(eq_attr "alternative" "1")
3026 (symbol_ref "false")]
3027 (symbol_ref "true")))
3028 (set (attr "preferred_for_speed")
3029 (cond [(eq_attr "alternative" "1")
3030 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3031 (symbol_ref "true")))])
3033 ;; %%% Kill this when call knows how to work this out.
3035 [(set (match_operand:DF 0 "push_operand")
3036 (match_operand:DF 1 "any_fp_register_operand"))]
3038 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3039 (set (match_dup 0) (match_dup 1))]
3041 /* Preserve memory attributes. */
3042 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3045 (define_insn "*pushsf_rex64"
3046 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3047 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3050 /* Anything else should be already split before reg-stack. */
3051 gcc_assert (which_alternative == 1);
3052 return "push{q}\t%q1";
3054 [(set_attr "type" "multi,push,multi")
3055 (set_attr "unit" "i387,*,*")
3056 (set_attr "mode" "SF,DI,SF")])
3058 (define_insn "*pushsf"
3059 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3060 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3063 /* Anything else should be already split before reg-stack. */
3064 gcc_assert (which_alternative == 1);
3065 return "push{l}\t%1";
3067 [(set_attr "type" "multi,push,multi")
3068 (set_attr "unit" "i387,*,*")
3069 (set_attr "mode" "SF,SI,SF")])
3071 ;; %%% Kill this when call knows how to work this out.
3073 [(set (match_operand:SF 0 "push_operand")
3074 (match_operand:SF 1 "any_fp_register_operand"))]
3076 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3077 (set (match_dup 0) (match_dup 1))]
3079 rtx op = XEXP (operands[0], 0);
3080 if (GET_CODE (op) == PRE_DEC)
3082 gcc_assert (!TARGET_64BIT);
3087 op = XEXP (XEXP (op, 1), 1);
3088 gcc_assert (CONST_INT_P (op));
3091 /* Preserve memory attributes. */
3092 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3096 [(set (match_operand:SF 0 "push_operand")
3097 (match_operand:SF 1 "memory_operand"))]
3099 && find_constant_src (insn)"
3100 [(set (match_dup 0) (match_dup 2))]
3101 "operands[2] = find_constant_src (curr_insn);")
3104 [(set (match_operand 0 "push_operand")
3105 (match_operand 1 "general_operand"))]
3107 && (GET_MODE (operands[0]) == TFmode
3108 || GET_MODE (operands[0]) == XFmode
3109 || GET_MODE (operands[0]) == DFmode)
3110 && !ANY_FP_REG_P (operands[1])"
3112 "ix86_split_long_move (operands); DONE;")
3114 ;; Floating point move instructions.
3116 (define_expand "movtf"
3117 [(set (match_operand:TF 0 "nonimmediate_operand")
3118 (match_operand:TF 1 "nonimmediate_operand"))]
3119 "TARGET_64BIT || TARGET_SSE"
3120 "ix86_expand_move (TFmode, operands); DONE;")
3122 (define_expand "mov<mode>"
3123 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3124 (match_operand:X87MODEF 1 "general_operand"))]
3126 "ix86_expand_move (<MODE>mode, operands); DONE;")
3128 (define_insn "*movtf_internal"
3129 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3130 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3131 "(TARGET_64BIT || TARGET_SSE)
3132 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3133 && (lra_in_progress || reload_completed
3134 || !CONST_DOUBLE_P (operands[1])
3135 || ((optimize_function_for_size_p (cfun)
3136 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3137 && standard_sse_constant_p (operands[1], TFmode) == 1
3138 && !memory_operand (operands[0], TFmode))
3139 || (!TARGET_MEMORY_MISMATCH_STALL
3140 && memory_operand (operands[0], TFmode)))"
3142 switch (get_attr_type (insn))
3145 return standard_sse_constant_opcode (insn, operands[1]);
3148 /* Handle misaligned load/store since we
3149 don't have movmisaligntf pattern. */
3150 if (misaligned_operand (operands[0], TFmode)
3151 || misaligned_operand (operands[1], TFmode))
3153 if (get_attr_mode (insn) == MODE_V4SF)
3154 return "%vmovups\t{%1, %0|%0, %1}";
3155 else if (TARGET_AVX512VL
3156 && (EXT_REX_SSE_REG_P (operands[0])
3157 || EXT_REX_SSE_REG_P (operands[1])))
3158 return "vmovdqu64\t{%1, %0|%0, %1}";
3160 return "%vmovdqu\t{%1, %0|%0, %1}";
3164 if (get_attr_mode (insn) == MODE_V4SF)
3165 return "%vmovaps\t{%1, %0|%0, %1}";
3166 else if (TARGET_AVX512VL
3167 && (EXT_REX_SSE_REG_P (operands[0])
3168 || EXT_REX_SSE_REG_P (operands[1])))
3169 return "vmovdqa64\t{%1, %0|%0, %1}";
3171 return "%vmovdqa\t{%1, %0|%0, %1}";
3181 [(set_attr "isa" "*,*,*,x64,x64")
3182 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3183 (set (attr "prefix")
3184 (if_then_else (eq_attr "type" "sselog1,ssemov")
3185 (const_string "maybe_vex")
3186 (const_string "orig")))
3188 (cond [(eq_attr "alternative" "3,4")
3190 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3191 (const_string "V4SF")
3192 (and (eq_attr "alternative" "2")
3193 (match_test "TARGET_SSE_TYPELESS_STORES"))
3194 (const_string "V4SF")
3195 (match_test "TARGET_AVX")
3197 (ior (not (match_test "TARGET_SSE2"))
3198 (match_test "optimize_function_for_size_p (cfun)"))
3199 (const_string "V4SF")
3201 (const_string "TI")))])
3204 [(set (match_operand:TF 0 "nonimmediate_operand")
3205 (match_operand:TF 1 "general_operand"))]
3207 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3209 "ix86_split_long_move (operands); DONE;")
3211 ;; Possible store forwarding (partial memory) stall
3212 ;; in alternatives 4, 6, 7 and 8.
3213 (define_insn "*movxf_internal"
3214 [(set (match_operand:XF 0 "nonimmediate_operand"
3215 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o")
3216 (match_operand:XF 1 "general_operand"
3217 "fm,f,G,roF,r , *roF,*r,F ,C,roF,rF"))]
3218 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3219 && (lra_in_progress || reload_completed
3220 || !CONST_DOUBLE_P (operands[1])
3221 || ((optimize_function_for_size_p (cfun)
3222 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3223 && standard_80387_constant_p (operands[1]) > 0
3224 && !memory_operand (operands[0], XFmode))
3225 || (!TARGET_MEMORY_MISMATCH_STALL
3226 && memory_operand (operands[0], XFmode))
3227 || !TARGET_HARD_XF_REGS)"
3229 switch (get_attr_type (insn))
3232 if (which_alternative == 2)
3233 return standard_80387_constant_opcode (operands[1]);
3234 return output_387_reg_move (insn, operands);
3244 (cond [(eq_attr "alternative" "7")
3245 (const_string "nox64")
3246 (eq_attr "alternative" "8")
3247 (const_string "x64")
3249 (const_string "*")))
3251 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10")
3252 (const_string "multi")
3254 (const_string "fmov")))
3256 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10")
3257 (if_then_else (match_test "TARGET_64BIT")
3259 (const_string "SI"))
3261 (const_string "XF")))
3262 (set (attr "preferred_for_size")
3263 (cond [(eq_attr "alternative" "3,4")
3264 (symbol_ref "false")]
3265 (symbol_ref "true")))
3266 (set (attr "enabled")
3267 (cond [(eq_attr "alternative" "9,10")
3269 (match_test "TARGET_HARD_XF_REGS")
3270 (symbol_ref "false")
3272 (not (match_test "TARGET_HARD_XF_REGS"))
3273 (symbol_ref "false")
3275 (const_string "*")))])
3278 [(set (match_operand:XF 0 "nonimmediate_operand")
3279 (match_operand:XF 1 "general_operand"))]
3281 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3283 "ix86_split_long_move (operands); DONE;")
3285 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3286 (define_insn "*movdf_internal"
3287 [(set (match_operand:DF 0 "nonimmediate_operand"
3288 "=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")
3289 (match_operand:DF 1 "general_operand"
3290 "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"))]
3291 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3292 && (lra_in_progress || reload_completed
3293 || !CONST_DOUBLE_P (operands[1])
3294 || ((optimize_function_for_size_p (cfun)
3295 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3296 && ((IS_STACK_MODE (DFmode)
3297 && standard_80387_constant_p (operands[1]) > 0)
3298 || (TARGET_SSE2 && TARGET_SSE_MATH
3299 && standard_sse_constant_p (operands[1], DFmode) == 1))
3300 && !memory_operand (operands[0], DFmode))
3301 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3302 && memory_operand (operands[0], DFmode))
3303 || !TARGET_HARD_DF_REGS)"
3305 switch (get_attr_type (insn))
3308 if (which_alternative == 2)
3309 return standard_80387_constant_opcode (operands[1]);
3310 return output_387_reg_move (insn, operands);
3316 if (get_attr_mode (insn) == MODE_SI)
3317 return "mov{l}\t{%1, %k0|%k0, %1}";
3318 else if (which_alternative == 11)
3319 return "movabs{q}\t{%1, %0|%0, %1}";
3321 return "mov{q}\t{%1, %0|%0, %1}";
3324 return standard_sse_constant_opcode (insn, operands[1]);
3327 switch (get_attr_mode (insn))
3330 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3331 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3332 return "%vmovsd\t{%1, %0|%0, %1}";
3335 return "%vmovaps\t{%1, %0|%0, %1}";
3337 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3339 return "%vmovapd\t{%1, %0|%0, %1}";
3342 gcc_assert (!TARGET_AVX);
3343 return "movlps\t{%1, %0|%0, %1}";
3345 gcc_assert (!TARGET_AVX);
3346 return "movlpd\t{%1, %0|%0, %1}";
3349 /* Handle broken assemblers that require movd instead of movq. */
3350 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3351 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3352 return "%vmovd\t{%1, %0|%0, %1}";
3353 return "%vmovq\t{%1, %0|%0, %1}";
3364 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3365 (const_string "nox64")
3366 (eq_attr "alternative" "8,9,10,11,20,21,24,25")
3367 (const_string "x64")
3368 (eq_attr "alternative" "12,13,14,15")
3369 (const_string "sse2")
3371 (const_string "*")))
3373 (cond [(eq_attr "alternative" "0,1,2")
3374 (const_string "fmov")
3375 (eq_attr "alternative" "3,4,5,6,7,22,23")
3376 (const_string "multi")
3377 (eq_attr "alternative" "8,9,10,11,24,25")
3378 (const_string "imov")
3379 (eq_attr "alternative" "12,16")
3380 (const_string "sselog1")
3382 (const_string "ssemov")))
3384 (if_then_else (eq_attr "alternative" "11")
3386 (const_string "*")))
3387 (set (attr "length_immediate")
3388 (if_then_else (eq_attr "alternative" "11")
3390 (const_string "*")))
3391 (set (attr "prefix")
3392 (if_then_else (eq_attr "type" "sselog1,ssemov")
3393 (const_string "maybe_vex")
3394 (const_string "orig")))
3395 (set (attr "prefix_data16")
3397 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3398 (eq_attr "mode" "V1DF"))
3400 (const_string "*")))
3402 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3404 (eq_attr "alternative" "8,9,11,20,21,24,25")
3407 /* xorps is one byte shorter for non-AVX targets. */
3408 (eq_attr "alternative" "12,16")
3409 (cond [(not (match_test "TARGET_SSE2"))
3410 (const_string "V4SF")
3411 (match_test "TARGET_AVX512F")
3413 (match_test "TARGET_AVX")
3414 (const_string "V2DF")
3415 (match_test "optimize_function_for_size_p (cfun)")
3416 (const_string "V4SF")
3417 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3420 (const_string "V2DF"))
3422 /* For architectures resolving dependencies on
3423 whole SSE registers use movapd to break dependency
3424 chains, otherwise use short move to avoid extra work. */
3426 /* movaps is one byte shorter for non-AVX targets. */
3427 (eq_attr "alternative" "13,17")
3428 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3429 (match_operand 1 "ext_sse_reg_operand"))
3430 (const_string "V8DF")
3431 (ior (not (match_test "TARGET_SSE2"))
3432 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3433 (const_string "V4SF")
3434 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3435 (const_string "V2DF")
3436 (match_test "TARGET_AVX")
3438 (match_test "optimize_function_for_size_p (cfun)")
3439 (const_string "V4SF")
3441 (const_string "DF"))
3443 /* For architectures resolving dependencies on register
3444 parts we may avoid extra work to zero out upper part
3446 (eq_attr "alternative" "14,18")
3447 (cond [(not (match_test "TARGET_SSE2"))
3448 (const_string "V2SF")
3449 (match_test "TARGET_AVX")
3451 (match_test "TARGET_SSE_SPLIT_REGS")
3452 (const_string "V1DF")
3454 (const_string "DF"))
3456 (and (eq_attr "alternative" "15,19")
3457 (not (match_test "TARGET_SSE2")))
3458 (const_string "V2SF")
3460 (const_string "DF")))
3461 (set (attr "preferred_for_size")
3462 (cond [(eq_attr "alternative" "3,4")
3463 (symbol_ref "false")]
3464 (symbol_ref "true")))
3465 (set (attr "preferred_for_speed")
3466 (cond [(eq_attr "alternative" "3,4")
3467 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3468 (symbol_ref "true")))
3469 (set (attr "enabled")
3470 (cond [(eq_attr "alternative" "22,23,24,25")
3472 (match_test "TARGET_HARD_DF_REGS")
3473 (symbol_ref "false")
3475 (not (match_test "TARGET_HARD_DF_REGS"))
3476 (symbol_ref "false")
3478 (const_string "*")))])
3481 [(set (match_operand:DF 0 "nonimmediate_operand")
3482 (match_operand:DF 1 "general_operand"))]
3483 "!TARGET_64BIT && reload_completed
3484 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3486 "ix86_split_long_move (operands); DONE;")
3488 (define_insn "*movsf_internal"
3489 [(set (match_operand:SF 0 "nonimmediate_operand"
3490 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym,r ,m")
3491 (match_operand:SF 1 "general_operand"
3492 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r ,rmF,rF"))]
3493 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3494 && (lra_in_progress || reload_completed
3495 || !CONST_DOUBLE_P (operands[1])
3496 || ((optimize_function_for_size_p (cfun)
3497 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3498 && ((IS_STACK_MODE (SFmode)
3499 && standard_80387_constant_p (operands[1]) > 0)
3500 || (TARGET_SSE && TARGET_SSE_MATH
3501 && standard_sse_constant_p (operands[1], SFmode) == 1)))
3502 || memory_operand (operands[0], SFmode)
3503 || !TARGET_HARD_SF_REGS)"
3505 switch (get_attr_type (insn))
3508 if (which_alternative == 2)
3509 return standard_80387_constant_opcode (operands[1]);
3510 return output_387_reg_move (insn, operands);
3513 return "mov{l}\t{%1, %0|%0, %1}";
3516 return standard_sse_constant_opcode (insn, operands[1]);
3519 switch (get_attr_mode (insn))
3522 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3523 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3524 return "%vmovss\t{%1, %0|%0, %1}";
3527 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3529 return "%vmovaps\t{%1, %0|%0, %1}";
3532 return "%vmovd\t{%1, %0|%0, %1}";
3539 switch (get_attr_mode (insn))
3542 return "movq\t{%1, %0|%0, %1}";
3544 return "movd\t{%1, %0|%0, %1}";
3555 (cond [(eq_attr "alternative" "0,1,2")
3556 (const_string "fmov")
3557 (eq_attr "alternative" "3,4,16,17")
3558 (const_string "imov")
3559 (eq_attr "alternative" "5")
3560 (const_string "sselog1")
3561 (eq_attr "alternative" "11,12,13,14,15")
3562 (const_string "mmxmov")
3564 (const_string "ssemov")))
3565 (set (attr "prefix")
3566 (if_then_else (eq_attr "type" "sselog1,ssemov")
3567 (const_string "maybe_vex")
3568 (const_string "orig")))
3569 (set (attr "prefix_data16")
3570 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3572 (const_string "*")))
3574 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3576 (eq_attr "alternative" "11")
3578 (eq_attr "alternative" "5")
3579 (cond [(not (match_test "TARGET_SSE2"))
3580 (const_string "V4SF")
3581 (match_test "TARGET_AVX512F")
3582 (const_string "V16SF")
3583 (match_test "TARGET_AVX")
3584 (const_string "V4SF")
3585 (match_test "optimize_function_for_size_p (cfun)")
3586 (const_string "V4SF")
3587 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3590 (const_string "V4SF"))
3592 /* For architectures resolving dependencies on
3593 whole SSE registers use APS move to break dependency
3594 chains, otherwise use short move to avoid extra work.
3596 Do the same for architectures resolving dependencies on
3597 the parts. While in DF mode it is better to always handle
3598 just register parts, the SF mode is different due to lack
3599 of instructions to load just part of the register. It is
3600 better to maintain the whole registers in single format
3601 to avoid problems on using packed logical operations. */
3602 (eq_attr "alternative" "6")
3603 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3604 (match_operand 1 "ext_sse_reg_operand"))
3605 (const_string "V16SF")
3606 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3607 (match_test "TARGET_SSE_SPLIT_REGS"))
3608 (const_string "V4SF")
3610 (const_string "SF"))
3612 (const_string "SF")))
3613 (set (attr "enabled")
3614 (cond [(eq_attr "alternative" "16,17")
3616 (match_test "TARGET_HARD_SF_REGS")
3617 (symbol_ref "false")
3619 (not (match_test "TARGET_HARD_SF_REGS"))
3620 (symbol_ref "false")
3622 (const_string "*")))])
3625 [(set (match_operand 0 "any_fp_register_operand")
3626 (match_operand 1 "memory_operand"))]
3628 && (GET_MODE (operands[0]) == TFmode
3629 || GET_MODE (operands[0]) == XFmode
3630 || GET_MODE (operands[0]) == DFmode
3631 || GET_MODE (operands[0]) == SFmode)
3632 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3633 [(set (match_dup 0) (match_dup 2))]
3634 "operands[2] = find_constant_src (curr_insn);")
3637 [(set (match_operand 0 "any_fp_register_operand")
3638 (float_extend (match_operand 1 "memory_operand")))]
3640 && (GET_MODE (operands[0]) == TFmode
3641 || GET_MODE (operands[0]) == XFmode
3642 || GET_MODE (operands[0]) == DFmode)
3643 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3644 [(set (match_dup 0) (match_dup 2))]
3645 "operands[2] = find_constant_src (curr_insn);")
3647 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3649 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3650 (match_operand:X87MODEF 1 "immediate_operand"))]
3652 && (standard_80387_constant_p (operands[1]) == 8
3653 || standard_80387_constant_p (operands[1]) == 9)"
3654 [(set (match_dup 0)(match_dup 1))
3656 (neg:X87MODEF (match_dup 0)))]
3658 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3659 operands[1] = CONST0_RTX (<MODE>mode);
3661 operands[1] = CONST1_RTX (<MODE>mode);
3664 (define_insn "swapxf"
3665 [(set (match_operand:XF 0 "register_operand" "+f")
3666 (match_operand:XF 1 "register_operand" "+f"))
3671 if (STACK_TOP_P (operands[0]))
3676 [(set_attr "type" "fxch")
3677 (set_attr "mode" "XF")])
3679 (define_insn "*swap<mode>"
3680 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3681 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3684 "TARGET_80387 || reload_completed"
3686 if (STACK_TOP_P (operands[0]))
3691 [(set_attr "type" "fxch")
3692 (set_attr "mode" "<MODE>")])
3694 ;; Zero extension instructions
3696 (define_expand "zero_extendsidi2"
3697 [(set (match_operand:DI 0 "nonimmediate_operand")
3698 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3700 (define_insn "*zero_extendsidi2"
3701 [(set (match_operand:DI 0 "nonimmediate_operand"
3702 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x,*r")
3704 (match_operand:SI 1 "x86_64_zext_operand"
3705 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m ,*k")))]
3708 switch (get_attr_type (insn))
3711 if (ix86_use_lea_for_mov (insn, operands))
3712 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3714 return "mov{l}\t{%1, %k0|%k0, %1}";
3720 return "movd\t{%1, %0|%0, %1}";
3723 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3726 if (GENERAL_REG_P (operands[0]))
3727 return "%vmovd\t{%1, %k0|%k0, %1}";
3729 return "%vmovd\t{%1, %0|%0, %1}";
3732 return "kmovd\t{%1, %k0|%k0, %1}";
3739 (cond [(eq_attr "alternative" "0,1,2")
3740 (const_string "nox64")
3741 (eq_attr "alternative" "3,7")
3742 (const_string "x64")
3743 (eq_attr "alternative" "8")
3744 (const_string "x64_sse4")
3745 (eq_attr "alternative" "10")
3746 (const_string "sse2")
3747 (eq_attr "alternative" "11")
3748 (const_string "x64_avx512bw")
3750 (const_string "*")))
3752 (cond [(eq_attr "alternative" "0,1,2,4")
3753 (const_string "multi")
3754 (eq_attr "alternative" "5,6")
3755 (const_string "mmxmov")
3756 (eq_attr "alternative" "7,9,10")
3757 (const_string "ssemov")
3758 (eq_attr "alternative" "8")
3759 (const_string "sselog1")
3760 (eq_attr "alternative" "11")
3761 (const_string "mskmov")
3763 (const_string "imovx")))
3764 (set (attr "prefix_extra")
3765 (if_then_else (eq_attr "alternative" "8")
3767 (const_string "*")))
3768 (set (attr "length_immediate")
3769 (if_then_else (eq_attr "alternative" "8")
3771 (const_string "*")))
3772 (set (attr "prefix")
3773 (if_then_else (eq_attr "type" "ssemov,sselog1")
3774 (const_string "maybe_vex")
3775 (const_string "orig")))
3776 (set (attr "prefix_0f")
3777 (if_then_else (eq_attr "type" "imovx")
3779 (const_string "*")))
3781 (cond [(eq_attr "alternative" "5,6")
3783 (eq_attr "alternative" "7,8,9")
3786 (const_string "SI")))])
3789 [(set (match_operand:DI 0 "memory_operand")
3790 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3792 [(set (match_dup 4) (const_int 0))]
3793 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3796 [(set (match_operand:DI 0 "general_reg_operand")
3797 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
3798 "!TARGET_64BIT && reload_completed
3799 && REGNO (operands[0]) == REGNO (operands[1])"
3800 [(set (match_dup 4) (const_int 0))]
3801 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3804 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
3805 (zero_extend:DI (match_operand:SI 1 "nonimmediate_gr_operand")))]
3806 "!TARGET_64BIT && reload_completed
3807 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3808 [(set (match_dup 3) (match_dup 1))
3809 (set (match_dup 4) (const_int 0))]
3810 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3812 (define_mode_attr kmov_isa
3813 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
3815 (define_insn "zero_extend<mode>di2"
3816 [(set (match_operand:DI 0 "register_operand" "=r,*r")
3818 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
3821 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
3822 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
3823 [(set_attr "isa" "*,<kmov_isa>")
3824 (set_attr "type" "imovx,mskmov")
3825 (set_attr "mode" "SI")])
3827 (define_expand "zero_extend<mode>si2"
3828 [(set (match_operand:SI 0 "register_operand")
3829 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3832 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3834 operands[1] = force_reg (<MODE>mode, operands[1]);
3835 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3840 (define_insn_and_split "zero_extend<mode>si2_and"
3841 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3843 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3844 (clobber (reg:CC FLAGS_REG))]
3845 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3847 "&& reload_completed"
3848 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3849 (clobber (reg:CC FLAGS_REG))])]
3851 if (!REG_P (operands[1])
3852 || REGNO (operands[0]) != REGNO (operands[1]))
3854 ix86_expand_clear (operands[0]);
3856 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3857 emit_insn (gen_movstrict<mode>
3858 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3862 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3864 [(set_attr "type" "alu1")
3865 (set_attr "mode" "SI")])
3867 (define_insn "*zero_extend<mode>si2"
3868 [(set (match_operand:SI 0 "register_operand" "=r,*r")
3870 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
3871 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3873 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
3874 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
3875 [(set_attr "isa" "*,<kmov_isa>")
3876 (set_attr "type" "imovx,mskmov")
3877 (set_attr "mode" "SI,<MODE>")])
3879 (define_expand "zero_extendqihi2"
3880 [(set (match_operand:HI 0 "register_operand")
3881 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3884 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3886 operands[1] = force_reg (QImode, operands[1]);
3887 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3892 (define_insn_and_split "zero_extendqihi2_and"
3893 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3894 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3895 (clobber (reg:CC FLAGS_REG))]
3896 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3898 "&& reload_completed"
3899 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3900 (clobber (reg:CC FLAGS_REG))])]
3902 if (!REG_P (operands[1])
3903 || REGNO (operands[0]) != REGNO (operands[1]))
3905 ix86_expand_clear (operands[0]);
3907 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3908 emit_insn (gen_movstrictqi
3909 (gen_lowpart (QImode, operands[0]), operands[1]));
3913 operands[0] = gen_lowpart (SImode, operands[0]);
3915 [(set_attr "type" "alu1")
3916 (set_attr "mode" "SI")])
3918 ; zero extend to SImode to avoid partial register stalls
3919 (define_insn "*zero_extendqihi2"
3920 [(set (match_operand:HI 0 "register_operand" "=r,*r")
3921 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k")))]
3922 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3924 movz{bl|x}\t{%1, %k0|%k0, %1}
3925 kmovb\t{%1, %k0|%k0, %1}"
3926 [(set_attr "type" "imovx,mskmov")
3927 (set_attr "isa" "*,avx512dq")
3928 (set_attr "mode" "SI,QI")])
3930 (define_insn_and_split "*zext<mode>_doubleword_and"
3931 [(set (match_operand:DI 0 "register_operand" "=&<r>")
3932 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3933 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
3934 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3936 "&& reload_completed && GENERAL_REG_P (operands[0])"
3937 [(set (match_dup 2) (const_int 0))]
3939 split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);
3941 emit_move_insn (operands[0], const0_rtx);
3943 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3944 emit_insn (gen_movstrict<mode>
3945 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3948 (define_insn_and_split "*zext<mode>_doubleword"
3949 [(set (match_operand:DI 0 "register_operand" "=r")
3950 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3951 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
3952 && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3954 "&& reload_completed && GENERAL_REG_P (operands[0])"
3955 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
3956 (set (match_dup 2) (const_int 0))]
3957 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
3959 (define_insn_and_split "*zextsi_doubleword"
3960 [(set (match_operand:DI 0 "register_operand" "=r")
3961 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3962 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
3964 "&& reload_completed && GENERAL_REG_P (operands[0])"
3965 [(set (match_dup 0) (match_dup 1))
3966 (set (match_dup 2) (const_int 0))]
3967 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
3969 ;; Sign extension instructions
3971 (define_expand "extendsidi2"
3972 [(set (match_operand:DI 0 "register_operand")
3973 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3978 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3983 (define_insn "*extendsidi2_rex64"
3984 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3985 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3989 movs{lq|x}\t{%1, %0|%0, %1}"
3990 [(set_attr "type" "imovx")
3991 (set_attr "mode" "DI")
3992 (set_attr "prefix_0f" "0")
3993 (set_attr "modrm" "0,1")])
3995 (define_insn "extendsidi2_1"
3996 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3997 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3998 (clobber (reg:CC FLAGS_REG))
3999 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4003 ;; Split the memory case. If the source register doesn't die, it will stay
4004 ;; this way, if it does die, following peephole2s take care of it.
4006 [(set (match_operand:DI 0 "memory_operand")
4007 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4008 (clobber (reg:CC FLAGS_REG))
4009 (clobber (match_operand:SI 2 "register_operand"))]
4013 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4015 emit_move_insn (operands[3], operands[1]);
4017 /* Generate a cltd if possible and doing so it profitable. */
4018 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4019 && REGNO (operands[1]) == AX_REG
4020 && REGNO (operands[2]) == DX_REG)
4022 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4026 emit_move_insn (operands[2], operands[1]);
4027 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4029 emit_move_insn (operands[4], operands[2]);
4033 ;; Peepholes for the case where the source register does die, after
4034 ;; being split with the above splitter.
4036 [(set (match_operand:SI 0 "memory_operand")
4037 (match_operand:SI 1 "general_reg_operand"))
4038 (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4039 (parallel [(set (match_dup 2)
4040 (ashiftrt:SI (match_dup 2) (const_int 31)))
4041 (clobber (reg:CC FLAGS_REG))])
4042 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4043 "REGNO (operands[1]) != REGNO (operands[2])
4044 && peep2_reg_dead_p (2, operands[1])
4045 && peep2_reg_dead_p (4, operands[2])
4046 && !reg_mentioned_p (operands[2], operands[3])"
4047 [(set (match_dup 0) (match_dup 1))
4048 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4049 (clobber (reg:CC FLAGS_REG))])
4050 (set (match_dup 3) (match_dup 1))])
4053 [(set (match_operand:SI 0 "memory_operand")
4054 (match_operand:SI 1 "general_reg_operand"))
4055 (parallel [(set (match_operand:SI 2 "general_reg_operand")
4056 (ashiftrt:SI (match_dup 1) (const_int 31)))
4057 (clobber (reg:CC FLAGS_REG))])
4058 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4059 "/* cltd is shorter than sarl $31, %eax */
4060 !optimize_function_for_size_p (cfun)
4061 && REGNO (operands[1]) == AX_REG
4062 && REGNO (operands[2]) == DX_REG
4063 && peep2_reg_dead_p (2, operands[1])
4064 && peep2_reg_dead_p (3, operands[2])
4065 && !reg_mentioned_p (operands[2], operands[3])"
4066 [(set (match_dup 0) (match_dup 1))
4067 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4068 (clobber (reg:CC FLAGS_REG))])
4069 (set (match_dup 3) (match_dup 1))])
4071 ;; Extend to register case. Optimize case where source and destination
4072 ;; registers match and cases where we can use cltd.
4074 [(set (match_operand:DI 0 "register_operand")
4075 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4076 (clobber (reg:CC FLAGS_REG))
4077 (clobber (match_scratch:SI 2))]
4081 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4083 if (REGNO (operands[3]) != REGNO (operands[1]))
4084 emit_move_insn (operands[3], operands[1]);
4086 /* Generate a cltd if possible and doing so it profitable. */
4087 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4088 && REGNO (operands[3]) == AX_REG
4089 && REGNO (operands[4]) == DX_REG)
4091 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4095 if (REGNO (operands[4]) != REGNO (operands[1]))
4096 emit_move_insn (operands[4], operands[1]);
4098 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4102 (define_insn "extend<mode>di2"
4103 [(set (match_operand:DI 0 "register_operand" "=r")
4105 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4107 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4108 [(set_attr "type" "imovx")
4109 (set_attr "mode" "DI")])
4111 (define_insn "extendhisi2"
4112 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4113 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4116 switch (get_attr_prefix_0f (insn))
4119 return "{cwtl|cwde}";
4121 return "movs{wl|x}\t{%1, %0|%0, %1}";
4124 [(set_attr "type" "imovx")
4125 (set_attr "mode" "SI")
4126 (set (attr "prefix_0f")
4127 ;; movsx is short decodable while cwtl is vector decoded.
4128 (if_then_else (and (eq_attr "cpu" "!k6")
4129 (eq_attr "alternative" "0"))
4131 (const_string "1")))
4132 (set (attr "znver1_decode")
4133 (if_then_else (eq_attr "prefix_0f" "0")
4134 (const_string "double")
4135 (const_string "direct")))
4137 (if_then_else (eq_attr "prefix_0f" "0")
4139 (const_string "1")))])
4141 (define_insn "*extendhisi2_zext"
4142 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4145 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4148 switch (get_attr_prefix_0f (insn))
4151 return "{cwtl|cwde}";
4153 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4156 [(set_attr "type" "imovx")
4157 (set_attr "mode" "SI")
4158 (set (attr "prefix_0f")
4159 ;; movsx is short decodable while cwtl is vector decoded.
4160 (if_then_else (and (eq_attr "cpu" "!k6")
4161 (eq_attr "alternative" "0"))
4163 (const_string "1")))
4165 (if_then_else (eq_attr "prefix_0f" "0")
4167 (const_string "1")))])
4169 (define_insn "extendqisi2"
4170 [(set (match_operand:SI 0 "register_operand" "=r")
4171 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4173 "movs{bl|x}\t{%1, %0|%0, %1}"
4174 [(set_attr "type" "imovx")
4175 (set_attr "mode" "SI")])
4177 (define_insn "*extendqisi2_zext"
4178 [(set (match_operand:DI 0 "register_operand" "=r")
4180 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4182 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4183 [(set_attr "type" "imovx")
4184 (set_attr "mode" "SI")])
4186 (define_insn "extendqihi2"
4187 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4188 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4191 switch (get_attr_prefix_0f (insn))
4194 return "{cbtw|cbw}";
4196 return "movs{bw|x}\t{%1, %0|%0, %1}";
4199 [(set_attr "type" "imovx")
4200 (set_attr "mode" "HI")
4201 (set (attr "prefix_0f")
4202 ;; movsx is short decodable while cwtl is vector decoded.
4203 (if_then_else (and (eq_attr "cpu" "!k6")
4204 (eq_attr "alternative" "0"))
4206 (const_string "1")))
4208 (if_then_else (eq_attr "prefix_0f" "0")
4210 (const_string "1")))])
4212 ;; Conversions between float and double.
4214 ;; These are all no-ops in the model used for the 80387.
4215 ;; So just emit moves.
4217 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4219 [(set (match_operand:DF 0 "push_operand")
4220 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4222 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4223 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4226 [(set (match_operand:XF 0 "push_operand")
4227 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4229 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4230 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4231 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4233 (define_expand "extendsfdf2"
4234 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4235 (float_extend:DF (match_operand:SF 1 "general_operand")))]
4236 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4238 /* ??? Needed for compress_float_constant since all fp constants
4239 are TARGET_LEGITIMATE_CONSTANT_P. */
4240 if (CONST_DOUBLE_P (operands[1]))
4242 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4243 && standard_80387_constant_p (operands[1]) > 0)
4245 operands[1] = simplify_const_unary_operation
4246 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4247 emit_move_insn_1 (operands[0], operands[1]);
4250 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4254 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4256 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4258 We do the conversion post reload to avoid producing of 128bit spills
4259 that might lead to ICE on 32bit target. The sequence unlikely combine
4262 [(set (match_operand:DF 0 "sse_reg_operand")
4264 (match_operand:SF 1 "nonimmediate_operand")))]
4265 "TARGET_USE_VECTOR_FP_CONVERTS
4266 && optimize_insn_for_speed_p ()
4268 && (!EXT_REX_SSE_REG_P (operands[0])
4269 || TARGET_AVX512VL)"
4274 (parallel [(const_int 0) (const_int 1)]))))]
4276 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4277 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4278 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4279 Try to avoid move when unpacking can be done in source. */
4280 if (REG_P (operands[1]))
4282 /* If it is unsafe to overwrite upper half of source, we need
4283 to move to destination and unpack there. */
4284 if (REGNO (operands[0]) != REGNO (operands[1])
4285 || (EXT_REX_SSE_REG_P (operands[1])
4286 && !TARGET_AVX512VL))
4288 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4289 emit_move_insn (tmp, operands[1]);
4292 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4293 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4294 =v, v, then vbroadcastss will be only needed for AVX512F without
4296 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4297 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4301 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4302 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4306 emit_insn (gen_vec_setv4sf_0 (operands[3],
4307 CONST0_RTX (V4SFmode), operands[1]));
4310 ;; It's more profitable to split and then extend in the same register.
4312 [(set (match_operand:DF 0 "sse_reg_operand")
4314 (match_operand:SF 1 "memory_operand")))]
4315 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4316 && optimize_insn_for_speed_p ()"
4317 [(set (match_dup 2) (match_dup 1))
4318 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4319 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4321 (define_insn "*extendsfdf2"
4322 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v")
4324 (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4325 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4327 switch (which_alternative)
4331 return output_387_reg_move (insn, operands);
4334 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4340 [(set_attr "type" "fmov,fmov,ssecvt")
4341 (set_attr "prefix" "orig,orig,maybe_vex")
4342 (set_attr "mode" "SF,XF,DF")
4343 (set (attr "enabled")
4345 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4347 (eq_attr "alternative" "0,1")
4348 (symbol_ref "TARGET_MIX_SSE_I387")
4349 (symbol_ref "true"))
4351 (eq_attr "alternative" "0,1")
4353 (symbol_ref "false"))))])
4355 (define_expand "extend<mode>xf2"
4356 [(set (match_operand:XF 0 "nonimmediate_operand")
4357 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4360 /* ??? Needed for compress_float_constant since all fp constants
4361 are TARGET_LEGITIMATE_CONSTANT_P. */
4362 if (CONST_DOUBLE_P (operands[1]))
4364 if (standard_80387_constant_p (operands[1]) > 0)
4366 operands[1] = simplify_const_unary_operation
4367 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4368 emit_move_insn_1 (operands[0], operands[1]);
4371 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4375 (define_insn "*extend<mode>xf2_i387"
4376 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4378 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4380 "* return output_387_reg_move (insn, operands);"
4381 [(set_attr "type" "fmov")
4382 (set_attr "mode" "<MODE>,XF")])
4384 ;; %%% This seems like bad news.
4385 ;; This cannot output into an f-reg because there is no way to be sure
4386 ;; of truncating in that case. Otherwise this is just like a simple move
4387 ;; insn. So we pretend we can output to a reg in order to get better
4388 ;; register preferencing, but we really use a stack slot.
4390 ;; Conversion from DFmode to SFmode.
4392 (define_expand "truncdfsf2"
4393 [(set (match_operand:SF 0 "nonimmediate_operand")
4395 (match_operand:DF 1 "nonimmediate_operand")))]
4396 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4398 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4400 else if (flag_unsafe_math_optimizations)
4404 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4405 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4410 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4412 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4414 We do the conversion post reload to avoid producing of 128bit spills
4415 that might lead to ICE on 32bit target. The sequence unlikely combine
4418 [(set (match_operand:SF 0 "sse_reg_operand")
4420 (match_operand:DF 1 "nonimmediate_operand")))]
4421 "TARGET_USE_VECTOR_FP_CONVERTS
4422 && optimize_insn_for_speed_p ()
4424 && (!EXT_REX_SSE_REG_P (operands[0])
4425 || TARGET_AVX512VL)"
4428 (float_truncate:V2SF
4432 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4433 operands[3] = CONST0_RTX (V2SFmode);
4434 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4435 /* Use movsd for loading from memory, unpcklpd for registers.
4436 Try to avoid move when unpacking can be done in source, or SSE3
4437 movddup is available. */
4438 if (REG_P (operands[1]))
4441 && REGNO (operands[0]) != REGNO (operands[1]))
4443 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4444 emit_move_insn (tmp, operands[1]);
4447 else if (!TARGET_SSE3)
4448 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4449 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4452 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4453 CONST0_RTX (DFmode)));
4456 ;; It's more profitable to split and then extend in the same register.
4458 [(set (match_operand:SF 0 "sse_reg_operand")
4460 (match_operand:DF 1 "memory_operand")))]
4461 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4462 && optimize_insn_for_speed_p ()"
4463 [(set (match_dup 2) (match_dup 1))
4464 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4465 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4467 (define_expand "truncdfsf2_with_temp"
4468 [(parallel [(set (match_operand:SF 0)
4469 (float_truncate:SF (match_operand:DF 1)))
4470 (clobber (match_operand:SF 2))])])
4472 ;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
4473 ;; because nothing we do there is unsafe.
4474 (define_insn "*truncdfsf_fast_mixed"
4475 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,v")
4477 (match_operand:DF 1 "nonimmediate_operand" "f ,vm")))]
4478 "TARGET_SSE2 && TARGET_SSE_MATH"
4480 switch (which_alternative)
4483 return output_387_reg_move (insn, operands);
4485 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4490 [(set_attr "type" "fmov,ssecvt")
4491 (set_attr "prefix" "orig,maybe_vex")
4492 (set_attr "mode" "SF")
4493 (set (attr "enabled")
4494 (cond [(eq_attr "alternative" "0")
4495 (symbol_ref "TARGET_MIX_SSE_I387
4496 && flag_unsafe_math_optimizations")
4498 (symbol_ref "true")))])
4500 (define_insn "*truncdfsf_fast_i387"
4501 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4503 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4504 "TARGET_80387 && flag_unsafe_math_optimizations"
4505 "* return output_387_reg_move (insn, operands);"
4506 [(set_attr "type" "fmov")
4507 (set_attr "mode" "SF")])
4509 (define_insn "*truncdfsf_mixed"
4510 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,v ,?f,?v,?*r")
4512 (match_operand:DF 1 "nonimmediate_operand" "f ,vm,f ,f ,f")))
4513 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4514 "TARGET_MIX_SSE_I387"
4516 switch (which_alternative)
4519 return output_387_reg_move (insn, operands);
4521 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4527 [(set_attr "isa" "*,sse2,*,*,*")
4528 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4529 (set_attr "unit" "*,*,i387,i387,i387")
4530 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4531 (set_attr "mode" "SF")])
4533 (define_insn "*truncdfsf_i387"
4534 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4536 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4537 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4540 switch (which_alternative)
4543 return output_387_reg_move (insn, operands);
4549 [(set_attr "type" "fmov,multi,multi,multi")
4550 (set_attr "unit" "*,i387,i387,i387")
4551 (set_attr "mode" "SF")])
4553 (define_insn "*truncdfsf2_i387_1"
4554 [(set (match_operand:SF 0 "memory_operand" "=m")
4556 (match_operand:DF 1 "register_operand" "f")))]
4558 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4559 && !TARGET_MIX_SSE_I387"
4560 "* return output_387_reg_move (insn, operands);"
4561 [(set_attr "type" "fmov")
4562 (set_attr "mode" "SF")])
4565 [(set (match_operand:SF 0 "register_operand")
4567 (match_operand:DF 1 "fp_register_operand")))
4568 (clobber (match_operand 2))]
4570 [(set (match_dup 2) (match_dup 1))
4571 (set (match_dup 0) (match_dup 2))]
4572 "operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));")
4574 ;; Conversion from XFmode to {SF,DF}mode
4576 (define_expand "truncxf<mode>2"
4577 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4578 (float_truncate:MODEF
4579 (match_operand:XF 1 "register_operand")))
4580 (clobber (match_dup 2))])]
4583 if (flag_unsafe_math_optimizations)
4585 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4586 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4587 if (reg != operands[0])
4588 emit_move_insn (operands[0], reg);
4592 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4595 (define_insn "*truncxfsf2_mixed"
4596 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4598 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4599 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4602 gcc_assert (!which_alternative);
4603 return output_387_reg_move (insn, operands);
4605 [(set_attr "type" "fmov,multi,multi,multi")
4606 (set_attr "unit" "*,i387,i387,i387")
4607 (set_attr "mode" "SF")])
4609 (define_insn "*truncxfdf2_mixed"
4610 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4612 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4613 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4616 gcc_assert (!which_alternative);
4617 return output_387_reg_move (insn, operands);
4619 [(set_attr "isa" "*,*,sse2,*")
4620 (set_attr "type" "fmov,multi,multi,multi")
4621 (set_attr "unit" "*,i387,i387,i387")
4622 (set_attr "mode" "DF")])
4624 (define_insn "truncxf<mode>2_i387_noop"
4625 [(set (match_operand:MODEF 0 "register_operand" "=f")
4626 (float_truncate:MODEF
4627 (match_operand:XF 1 "register_operand" "f")))]
4628 "TARGET_80387 && flag_unsafe_math_optimizations"
4629 "* return output_387_reg_move (insn, operands);"
4630 [(set_attr "type" "fmov")
4631 (set_attr "mode" "<MODE>")])
4633 (define_insn "*truncxf<mode>2_i387"
4634 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4635 (float_truncate:MODEF
4636 (match_operand:XF 1 "register_operand" "f")))]
4638 "* return output_387_reg_move (insn, operands);"
4639 [(set_attr "type" "fmov")
4640 (set_attr "mode" "<MODE>")])
4643 [(set (match_operand:MODEF 0 "register_operand")
4644 (float_truncate:MODEF
4645 (match_operand:XF 1 "register_operand")))
4646 (clobber (match_operand:MODEF 2 "memory_operand"))]
4647 "TARGET_80387 && reload_completed"
4648 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4649 (set (match_dup 0) (match_dup 2))])
4652 [(set (match_operand:MODEF 0 "memory_operand")
4653 (float_truncate:MODEF
4654 (match_operand:XF 1 "register_operand")))
4655 (clobber (match_operand:MODEF 2 "memory_operand"))]
4657 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4659 ;; Signed conversion to DImode.
4661 (define_expand "fix_truncxfdi2"
4662 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4663 (fix:DI (match_operand:XF 1 "register_operand")))
4664 (clobber (reg:CC FLAGS_REG))])]
4669 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4674 (define_expand "fix_trunc<mode>di2"
4675 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4676 (fix:DI (match_operand:MODEF 1 "register_operand")))
4677 (clobber (reg:CC FLAGS_REG))])]
4678 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4681 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4683 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4686 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4688 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4689 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4690 if (out != operands[0])
4691 emit_move_insn (operands[0], out);
4696 ;; Signed conversion to SImode.
4698 (define_expand "fix_truncxfsi2"
4699 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4700 (fix:SI (match_operand:XF 1 "register_operand")))
4701 (clobber (reg:CC FLAGS_REG))])]
4706 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4711 (define_expand "fix_trunc<mode>si2"
4712 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4713 (fix:SI (match_operand:MODEF 1 "register_operand")))
4714 (clobber (reg:CC FLAGS_REG))])]
4715 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4718 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4720 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4723 if (SSE_FLOAT_MODE_P (<MODE>mode))
4725 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4726 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4727 if (out != operands[0])
4728 emit_move_insn (operands[0], out);
4733 ;; Signed conversion to HImode.
4735 (define_expand "fix_trunc<mode>hi2"
4736 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4737 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4738 (clobber (reg:CC FLAGS_REG))])]
4740 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4744 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4749 ;; Unsigned conversion to SImode.
4751 (define_expand "fixuns_trunc<mode>si2"
4753 [(set (match_operand:SI 0 "register_operand")
4755 (match_operand:MODEF 1 "nonimmediate_operand")))
4757 (clobber (match_scratch:<ssevecmode> 3))
4758 (clobber (match_scratch:<ssevecmode> 4))])]
4759 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4761 machine_mode mode = <MODE>mode;
4762 machine_mode vecmode = <ssevecmode>mode;
4763 REAL_VALUE_TYPE TWO31r;
4766 if (optimize_insn_for_size_p ())
4769 real_ldexp (&TWO31r, &dconst1, 31);
4770 two31 = const_double_from_real_value (TWO31r, mode);
4771 two31 = ix86_build_const_vector (vecmode, true, two31);
4772 operands[2] = force_reg (vecmode, two31);
4775 (define_insn_and_split "*fixuns_trunc<mode>_1"
4776 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4778 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4779 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4780 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4781 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4782 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4783 && optimize_function_for_speed_p (cfun)"
4785 "&& reload_completed"
4788 ix86_split_convert_uns_si_sse (operands);
4792 ;; Unsigned conversion to HImode.
4793 ;; Without these patterns, we'll try the unsigned SI conversion which
4794 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4796 (define_expand "fixuns_trunc<mode>hi2"
4798 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4799 (set (match_operand:HI 0 "nonimmediate_operand")
4800 (subreg:HI (match_dup 2) 0))]
4801 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4802 "operands[2] = gen_reg_rtx (SImode);")
4804 ;; When SSE is available, it is always faster to use it!
4805 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4806 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4807 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
4808 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4809 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4810 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4811 [(set_attr "type" "sseicvt")
4812 (set_attr "prefix" "maybe_vex")
4813 (set (attr "prefix_rex")
4815 (match_test "<SWI48:MODE>mode == DImode")
4817 (const_string "*")))
4818 (set_attr "mode" "<MODEF:MODE>")
4819 (set_attr "athlon_decode" "double,vector")
4820 (set_attr "amdfam10_decode" "double,double")
4821 (set_attr "bdver1_decode" "double,double")])
4823 ;; Avoid vector decoded forms of the instruction.
4825 [(match_scratch:MODEF 2 "x")
4826 (set (match_operand:SWI48 0 "register_operand")
4827 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4828 "TARGET_AVOID_VECTOR_DECODE
4829 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4830 && optimize_insn_for_speed_p ()"
4831 [(set (match_dup 2) (match_dup 1))
4832 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4834 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4835 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4836 (fix:SWI248x (match_operand 1 "register_operand")))]
4837 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4839 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4840 && (TARGET_64BIT || <MODE>mode != DImode))
4842 && can_create_pseudo_p ()"
4847 if (memory_operand (operands[0], VOIDmode))
4848 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4851 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4852 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4858 [(set_attr "type" "fisttp")
4859 (set_attr "mode" "<MODE>")])
4861 (define_insn "fix_trunc<mode>_i387_fisttp"
4862 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4863 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4864 (clobber (match_scratch:XF 2 "=&1f"))]
4865 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4867 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4868 && (TARGET_64BIT || <MODE>mode != DImode))
4869 && TARGET_SSE_MATH)"
4870 "* return output_fix_trunc (insn, operands, true);"
4871 [(set_attr "type" "fisttp")
4872 (set_attr "mode" "<MODE>")])
4874 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4875 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4876 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4877 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4878 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4879 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4881 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4882 && (TARGET_64BIT || <MODE>mode != DImode))
4883 && TARGET_SSE_MATH)"
4885 [(set_attr "type" "fisttp")
4886 (set_attr "mode" "<MODE>")])
4889 [(set (match_operand:SWI248x 0 "register_operand")
4890 (fix:SWI248x (match_operand 1 "register_operand")))
4891 (clobber (match_operand:SWI248x 2 "memory_operand"))
4892 (clobber (match_scratch 3))]
4894 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4895 (clobber (match_dup 3))])
4896 (set (match_dup 0) (match_dup 2))])
4899 [(set (match_operand:SWI248x 0 "memory_operand")
4900 (fix:SWI248x (match_operand 1 "register_operand")))
4901 (clobber (match_operand:SWI248x 2 "memory_operand"))
4902 (clobber (match_scratch 3))]
4904 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4905 (clobber (match_dup 3))])])
4907 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4908 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4909 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4910 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4911 ;; function in i386.c.
4912 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4913 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4914 (fix:SWI248x (match_operand 1 "register_operand")))
4915 (clobber (reg:CC FLAGS_REG))]
4916 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4918 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4919 && (TARGET_64BIT || <MODE>mode != DImode))
4920 && can_create_pseudo_p ()"
4925 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4927 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4928 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4929 if (memory_operand (operands[0], VOIDmode))
4930 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4931 operands[2], operands[3]));
4934 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4935 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4936 operands[2], operands[3],
4941 [(set_attr "type" "fistp")
4942 (set_attr "i387_cw" "trunc")
4943 (set_attr "mode" "<MODE>")])
4945 (define_insn "fix_truncdi_i387"
4946 [(set (match_operand:DI 0 "memory_operand" "=m")
4947 (fix:DI (match_operand 1 "register_operand" "f")))
4948 (use (match_operand:HI 2 "memory_operand" "m"))
4949 (use (match_operand:HI 3 "memory_operand" "m"))
4950 (clobber (match_scratch:XF 4 "=&1f"))]
4951 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4953 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4954 "* return output_fix_trunc (insn, operands, false);"
4955 [(set_attr "type" "fistp")
4956 (set_attr "i387_cw" "trunc")
4957 (set_attr "mode" "DI")])
4959 (define_insn "fix_truncdi_i387_with_temp"
4960 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4961 (fix:DI (match_operand 1 "register_operand" "f,f")))
4962 (use (match_operand:HI 2 "memory_operand" "m,m"))
4963 (use (match_operand:HI 3 "memory_operand" "m,m"))
4964 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4965 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4966 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4968 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4970 [(set_attr "type" "fistp")
4971 (set_attr "i387_cw" "trunc")
4972 (set_attr "mode" "DI")])
4975 [(set (match_operand:DI 0 "register_operand")
4976 (fix:DI (match_operand 1 "register_operand")))
4977 (use (match_operand:HI 2 "memory_operand"))
4978 (use (match_operand:HI 3 "memory_operand"))
4979 (clobber (match_operand:DI 4 "memory_operand"))
4980 (clobber (match_scratch 5))]
4982 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4985 (clobber (match_dup 5))])
4986 (set (match_dup 0) (match_dup 4))])
4989 [(set (match_operand:DI 0 "memory_operand")
4990 (fix:DI (match_operand 1 "register_operand")))
4991 (use (match_operand:HI 2 "memory_operand"))
4992 (use (match_operand:HI 3 "memory_operand"))
4993 (clobber (match_operand:DI 4 "memory_operand"))
4994 (clobber (match_scratch 5))]
4996 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4999 (clobber (match_dup 5))])])
5001 (define_insn "fix_trunc<mode>_i387"
5002 [(set (match_operand:SWI24 0 "memory_operand" "=m")
5003 (fix:SWI24 (match_operand 1 "register_operand" "f")))
5004 (use (match_operand:HI 2 "memory_operand" "m"))
5005 (use (match_operand:HI 3 "memory_operand" "m"))]
5006 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5008 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5009 "* return output_fix_trunc (insn, operands, false);"
5010 [(set_attr "type" "fistp")
5011 (set_attr "i387_cw" "trunc")
5012 (set_attr "mode" "<MODE>")])
5014 (define_insn "fix_trunc<mode>_i387_with_temp"
5015 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
5016 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
5017 (use (match_operand:HI 2 "memory_operand" "m,m"))
5018 (use (match_operand:HI 3 "memory_operand" "m,m"))
5019 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
5020 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5022 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5024 [(set_attr "type" "fistp")
5025 (set_attr "i387_cw" "trunc")
5026 (set_attr "mode" "<MODE>")])
5029 [(set (match_operand:SWI24 0 "register_operand")
5030 (fix:SWI24 (match_operand 1 "register_operand")))
5031 (use (match_operand:HI 2 "memory_operand"))
5032 (use (match_operand:HI 3 "memory_operand"))
5033 (clobber (match_operand:SWI24 4 "memory_operand"))]
5035 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
5037 (use (match_dup 3))])
5038 (set (match_dup 0) (match_dup 4))])
5041 [(set (match_operand:SWI24 0 "memory_operand")
5042 (fix:SWI24 (match_operand 1 "register_operand")))
5043 (use (match_operand:HI 2 "memory_operand"))
5044 (use (match_operand:HI 3 "memory_operand"))
5045 (clobber (match_operand:SWI24 4 "memory_operand"))]
5047 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
5049 (use (match_dup 3))])])
5051 (define_insn "x86_fnstcw_1"
5052 [(set (match_operand:HI 0 "memory_operand" "=m")
5053 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5056 [(set (attr "length")
5057 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5058 (set_attr "mode" "HI")
5059 (set_attr "unit" "i387")
5060 (set_attr "bdver1_decode" "vector")])
5062 (define_insn "x86_fldcw_1"
5063 [(set (reg:HI FPCR_REG)
5064 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5067 [(set (attr "length")
5068 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5069 (set_attr "mode" "HI")
5070 (set_attr "unit" "i387")
5071 (set_attr "athlon_decode" "vector")
5072 (set_attr "amdfam10_decode" "vector")
5073 (set_attr "bdver1_decode" "vector")])
5075 ;; Conversion between fixed point and floating point.
5077 ;; Even though we only accept memory inputs, the backend _really_
5078 ;; wants to be able to do this between registers. Thankfully, LRA
5079 ;; will fix this up for us during register allocation.
5081 (define_insn "floathi<mode>2"
5082 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5083 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5085 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5086 || TARGET_MIX_SSE_I387)"
5088 [(set_attr "type" "fmov")
5089 (set_attr "mode" "<MODE>")
5090 (set_attr "znver1_decode" "double")
5091 (set_attr "fp_int_src" "true")])
5093 (define_insn "float<SWI48x:mode>xf2"
5094 [(set (match_operand:XF 0 "register_operand" "=f")
5095 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5098 [(set_attr "type" "fmov")
5099 (set_attr "mode" "XF")
5100 (set_attr "znver1_decode" "double")
5101 (set_attr "fp_int_src" "true")])
5103 (define_expand "float<SWI48:mode><MODEF:mode>2"
5104 [(set (match_operand:MODEF 0 "register_operand")
5105 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5106 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5108 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
5109 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5111 rtx reg = gen_reg_rtx (XFmode);
5112 rtx (*insn)(rtx, rtx);
5114 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
5116 if (<MODEF:MODE>mode == SFmode)
5117 insn = gen_truncxfsf2;
5118 else if (<MODEF:MODE>mode == DFmode)
5119 insn = gen_truncxfdf2;
5123 emit_insn (insn (operands[0], reg));
5128 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed"
5129 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5131 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5132 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5135 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5136 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5137 [(set_attr "type" "fmov,sseicvt,sseicvt")
5138 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5139 (set_attr "mode" "<MODEF:MODE>")
5140 (set (attr "prefix_rex")
5142 (and (eq_attr "prefix" "maybe_vex")
5143 (match_test "<SWI48:MODE>mode == DImode"))
5145 (const_string "*")))
5146 (set_attr "unit" "i387,*,*")
5147 (set_attr "athlon_decode" "*,double,direct")
5148 (set_attr "amdfam10_decode" "*,vector,double")
5149 (set_attr "bdver1_decode" "*,double,direct")
5150 (set_attr "znver1_decode" "double,*,*")
5151 (set_attr "fp_int_src" "true")
5152 (set (attr "enabled")
5153 (cond [(eq_attr "alternative" "0")
5154 (symbol_ref "TARGET_MIX_SSE_I387
5155 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5158 (symbol_ref "true")))
5159 (set (attr "preferred_for_speed")
5160 (cond [(eq_attr "alternative" "1")
5161 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5162 (symbol_ref "true")))])
5164 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
5165 [(set (match_operand:MODEF 0 "register_operand" "=f")
5166 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5167 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
5169 [(set_attr "type" "fmov")
5170 (set_attr "mode" "<MODEF:MODE>")
5171 (set_attr "znver1_decode" "double")
5172 (set_attr "fp_int_src" "true")])
5174 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5175 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5176 ;; alternative in sse2_loadld.
5178 [(set (match_operand:MODEF 0 "sse_reg_operand")
5179 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5180 "TARGET_USE_VECTOR_CONVERTS
5181 && optimize_function_for_speed_p (cfun)
5183 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5184 && (!EXT_REX_SSE_REG_P (operands[0])
5185 || TARGET_AVX512VL)"
5188 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5189 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5191 emit_insn (gen_sse2_loadld (operands[4],
5192 CONST0_RTX (V4SImode), operands[1]));
5194 if (<ssevecmode>mode == V4SFmode)
5195 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5197 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5201 ;; Avoid partial SSE register dependency stalls. This splitter should split
5202 ;; late in the pass sequence (after register rename pass), so allocated
5203 ;; registers won't change anymore
5206 [(set (match_operand:MODEF 0 "sse_reg_operand")
5207 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5208 "TARGET_SSE_PARTIAL_REG_DEPENDENCY
5209 && optimize_function_for_speed_p (cfun)
5210 && epilogue_completed
5211 && (!EXT_REX_SSE_REG_P (operands[0])
5212 || TARGET_AVX512VL)"
5214 (vec_merge:<MODEF:ssevecmode>
5215 (vec_duplicate:<MODEF:ssevecmode>
5221 const machine_mode vmode = <MODEF:ssevecmode>mode;
5223 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5224 emit_move_insn (operands[0], CONST0_RTX (vmode));
5227 ;; Break partial reg stall for cvtsd2ss. This splitter should split
5228 ;; late in the pass sequence (after register rename pass),
5229 ;; so allocated registers won't change anymore.
5232 [(set (match_operand:SF 0 "sse_reg_operand")
5234 (match_operand:DF 1 "nonimmediate_operand")))]
5235 "TARGET_SSE_PARTIAL_REG_DEPENDENCY
5236 && optimize_function_for_speed_p (cfun)
5237 && epilogue_completed
5238 && (!REG_P (operands[1])
5239 || REGNO (operands[0]) != REGNO (operands[1]))
5240 && (!EXT_REX_SSE_REG_P (operands[0])
5241 || TARGET_AVX512VL)"
5250 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5251 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5254 ;; Break partial reg stall for cvtss2sd. This splitter should split
5255 ;; late in the pass sequence (after register rename pass),
5256 ;; so allocated registers won't change anymore.
5259 [(set (match_operand:DF 0 "sse_reg_operand")
5261 (match_operand:SF 1 "nonimmediate_operand")))]
5262 "TARGET_SSE_PARTIAL_REG_DEPENDENCY
5263 && optimize_function_for_speed_p (cfun)
5264 && epilogue_completed
5265 && (!REG_P (operands[1])
5266 || REGNO (operands[0]) != REGNO (operands[1]))
5267 && (!EXT_REX_SSE_REG_P (operands[0])
5268 || TARGET_AVX512VL)"
5277 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5278 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5281 ;; Avoid store forwarding (partial memory) stall penalty
5282 ;; by passing DImode value through XMM registers. */
5284 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5285 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5287 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5288 (clobber (match_scratch:V4SI 3 "=X,x"))
5289 (clobber (match_scratch:V4SI 4 "=X,x"))
5290 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5291 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5292 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5293 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5295 [(set_attr "type" "multi")
5296 (set_attr "mode" "<X87MODEF:MODE>")
5297 (set_attr "unit" "i387")
5298 (set_attr "fp_int_src" "true")])
5301 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5302 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5303 (clobber (match_scratch:V4SI 3))
5304 (clobber (match_scratch:V4SI 4))
5305 (clobber (match_operand:DI 2 "memory_operand"))]
5306 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5307 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5308 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5309 && reload_completed"
5310 [(set (match_dup 2) (match_dup 3))
5311 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5313 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5314 Assemble the 64-bit DImode value in an xmm register. */
5315 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5316 gen_lowpart (SImode, operands[1])));
5317 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5318 gen_highpart (SImode, operands[1])));
5319 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5322 operands[3] = gen_lowpart (DImode, operands[3]);
5326 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5327 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5328 (clobber (match_scratch:V4SI 3))
5329 (clobber (match_scratch:V4SI 4))
5330 (clobber (match_operand:DI 2 "memory_operand"))]
5331 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5332 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5333 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5334 && reload_completed"
5335 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5337 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5338 [(set (match_operand:MODEF 0 "register_operand")
5339 (unsigned_float:MODEF
5340 (match_operand:SWI12 1 "nonimmediate_operand")))]
5342 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5344 operands[1] = convert_to_mode (SImode, operands[1], 1);
5345 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5349 ;; Avoid store forwarding (partial memory) stall penalty by extending
5350 ;; SImode value to DImode through XMM register instead of pushing two
5351 ;; SImode values to stack. Also note that fild loads from memory only.
5353 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5354 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5355 (unsigned_float:X87MODEF
5356 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5357 (clobber (match_scratch:DI 3 "=x"))
5358 (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5360 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5361 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5363 "&& reload_completed"
5364 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5365 (set (match_dup 2) (match_dup 3))
5367 (float:X87MODEF (match_dup 2)))]
5369 [(set_attr "type" "multi")
5370 (set_attr "mode" "<MODE>")])
5372 (define_expand "floatunssi<mode>2"
5374 [(set (match_operand:X87MODEF 0 "register_operand")
5375 (unsigned_float:X87MODEF
5376 (match_operand:SI 1 "nonimmediate_operand")))
5377 (clobber (match_scratch:DI 3))
5378 (clobber (match_dup 2))])]
5380 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5381 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5382 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5384 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5386 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5390 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5393 (define_expand "floatunsdisf2"
5394 [(use (match_operand:SF 0 "register_operand"))
5395 (use (match_operand:DI 1 "nonimmediate_operand"))]
5396 "TARGET_64BIT && TARGET_SSE_MATH"
5397 "x86_emit_floatuns (operands); DONE;")
5399 (define_expand "floatunsdidf2"
5400 [(use (match_operand:DF 0 "register_operand"))
5401 (use (match_operand:DI 1 "nonimmediate_operand"))]
5402 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5403 && TARGET_SSE2 && TARGET_SSE_MATH"
5406 x86_emit_floatuns (operands);
5408 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5412 ;; Load effective address instructions
5414 (define_insn_and_split "*lea<mode>"
5415 [(set (match_operand:SWI48 0 "register_operand" "=r")
5416 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5419 if (SImode_address_operand (operands[1], VOIDmode))
5421 gcc_assert (TARGET_64BIT);
5422 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5425 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5427 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5430 machine_mode mode = <MODE>mode;
5433 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5434 change operands[] array behind our back. */
5435 pat = PATTERN (curr_insn);
5437 operands[0] = SET_DEST (pat);
5438 operands[1] = SET_SRC (pat);
5440 /* Emit all operations in SImode for zero-extended addresses. */
5441 if (SImode_address_operand (operands[1], VOIDmode))
5444 ix86_split_lea_for_addr (curr_insn, operands, mode);
5446 /* Zero-extend return register to DImode for zero-extended addresses. */
5447 if (mode != <MODE>mode)
5448 emit_insn (gen_zero_extendsidi2
5449 (operands[0], gen_lowpart (mode, operands[0])));
5453 [(set_attr "type" "lea")
5456 (match_operand 1 "SImode_address_operand")
5458 (const_string "<MODE>")))])
5462 (define_expand "add<mode>3"
5463 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5464 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5465 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5467 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5469 (define_insn_and_split "*add<dwi>3_doubleword"
5470 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5472 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5473 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
5475 (clobber (reg:CC FLAGS_REG))]
5476 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5479 [(parallel [(set (reg:CCC FLAGS_REG)
5481 (plus:DWIH (match_dup 1) (match_dup 2))
5484 (plus:DWIH (match_dup 1) (match_dup 2)))])
5485 (parallel [(set (match_dup 3)
5488 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5491 (clobber (reg:CC FLAGS_REG))])]
5493 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5494 if (operands[2] == const0_rtx)
5496 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5501 (define_insn "*add<mode>_1"
5502 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5504 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5505 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5506 (clobber (reg:CC FLAGS_REG))]
5507 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5509 switch (get_attr_type (insn))
5515 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5516 if (operands[2] == const1_rtx)
5517 return "inc{<imodesuffix>}\t%0";
5520 gcc_assert (operands[2] == constm1_rtx);
5521 return "dec{<imodesuffix>}\t%0";
5525 /* For most processors, ADD is faster than LEA. This alternative
5526 was added to use ADD as much as possible. */
5527 if (which_alternative == 2)
5528 std::swap (operands[1], operands[2]);
5530 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5531 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5532 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5534 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5538 (cond [(eq_attr "alternative" "3")
5539 (const_string "lea")
5540 (match_operand:SWI48 2 "incdec_operand")
5541 (const_string "incdec")
5543 (const_string "alu")))
5544 (set (attr "length_immediate")
5546 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5548 (const_string "*")))
5549 (set_attr "mode" "<MODE>")])
5551 ;; It may seem that nonimmediate operand is proper one for operand 1.
5552 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5553 ;; we take care in ix86_binary_operator_ok to not allow two memory
5554 ;; operands so proper swapping will be done in reload. This allow
5555 ;; patterns constructed from addsi_1 to match.
5557 (define_insn "addsi_1_zext"
5558 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5560 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5561 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5562 (clobber (reg:CC FLAGS_REG))]
5563 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5565 switch (get_attr_type (insn))
5571 if (operands[2] == const1_rtx)
5572 return "inc{l}\t%k0";
5575 gcc_assert (operands[2] == constm1_rtx);
5576 return "dec{l}\t%k0";
5580 /* For most processors, ADD is faster than LEA. This alternative
5581 was added to use ADD as much as possible. */
5582 if (which_alternative == 1)
5583 std::swap (operands[1], operands[2]);
5585 if (x86_maybe_negate_const_int (&operands[2], SImode))
5586 return "sub{l}\t{%2, %k0|%k0, %2}";
5588 return "add{l}\t{%2, %k0|%k0, %2}";
5592 (cond [(eq_attr "alternative" "2")
5593 (const_string "lea")
5594 (match_operand:SI 2 "incdec_operand")
5595 (const_string "incdec")
5597 (const_string "alu")))
5598 (set (attr "length_immediate")
5600 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5602 (const_string "*")))
5603 (set_attr "mode" "SI")])
5605 (define_insn "*addhi_1"
5606 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5607 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5608 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5609 (clobber (reg:CC FLAGS_REG))]
5610 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5612 switch (get_attr_type (insn))
5618 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5619 if (operands[2] == const1_rtx)
5620 return "inc{w}\t%0";
5623 gcc_assert (operands[2] == constm1_rtx);
5624 return "dec{w}\t%0";
5628 /* For most processors, ADD is faster than LEA. This alternative
5629 was added to use ADD as much as possible. */
5630 if (which_alternative == 2)
5631 std::swap (operands[1], operands[2]);
5633 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5634 if (x86_maybe_negate_const_int (&operands[2], HImode))
5635 return "sub{w}\t{%2, %0|%0, %2}";
5637 return "add{w}\t{%2, %0|%0, %2}";
5641 (cond [(eq_attr "alternative" "3")
5642 (const_string "lea")
5643 (match_operand:HI 2 "incdec_operand")
5644 (const_string "incdec")
5646 (const_string "alu")))
5647 (set (attr "length_immediate")
5649 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5651 (const_string "*")))
5652 (set_attr "mode" "HI,HI,HI,SI")])
5654 (define_insn "*addqi_1"
5655 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5656 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5657 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5658 (clobber (reg:CC FLAGS_REG))]
5659 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5661 bool widen = (get_attr_mode (insn) != MODE_QI);
5663 switch (get_attr_type (insn))
5669 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5670 if (operands[2] == const1_rtx)
5671 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5674 gcc_assert (operands[2] == constm1_rtx);
5675 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5679 /* For most processors, ADD is faster than LEA. These alternatives
5680 were added to use ADD as much as possible. */
5681 if (which_alternative == 2 || which_alternative == 4)
5682 std::swap (operands[1], operands[2]);
5684 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5685 if (x86_maybe_negate_const_int (&operands[2], QImode))
5688 return "sub{l}\t{%2, %k0|%k0, %2}";
5690 return "sub{b}\t{%2, %0|%0, %2}";
5693 return "add{l}\t{%k2, %k0|%k0, %k2}";
5695 return "add{b}\t{%2, %0|%0, %2}";
5699 (cond [(eq_attr "alternative" "5")
5700 (const_string "lea")
5701 (match_operand:QI 2 "incdec_operand")
5702 (const_string "incdec")
5704 (const_string "alu")))
5705 (set (attr "length_immediate")
5707 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5709 (const_string "*")))
5710 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
5711 ;; Potential partial reg stall on alternatives 3 and 4.
5712 (set (attr "preferred_for_speed")
5713 (cond [(eq_attr "alternative" "3,4")
5714 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
5715 (symbol_ref "true")))])
5717 (define_insn "*addqi_1_slp"
5718 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5719 (plus:QI (match_dup 0)
5720 (match_operand:QI 1 "general_operand" "qn,qm")))
5721 (clobber (reg:CC FLAGS_REG))]
5722 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5723 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5725 switch (get_attr_type (insn))
5728 if (operands[1] == const1_rtx)
5729 return "inc{b}\t%0";
5732 gcc_assert (operands[1] == constm1_rtx);
5733 return "dec{b}\t%0";
5737 if (x86_maybe_negate_const_int (&operands[1], QImode))
5738 return "sub{b}\t{%1, %0|%0, %1}";
5740 return "add{b}\t{%1, %0|%0, %1}";
5744 (if_then_else (match_operand:QI 1 "incdec_operand")
5745 (const_string "incdec")
5746 (const_string "alu1")))
5747 (set (attr "memory")
5748 (if_then_else (match_operand 1 "memory_operand")
5749 (const_string "load")
5750 (const_string "none")))
5751 (set_attr "mode" "QI")])
5753 ;; Split non destructive adds if we cannot use lea.
5755 [(set (match_operand:SWI48 0 "register_operand")
5756 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5757 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5758 (clobber (reg:CC FLAGS_REG))]
5759 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5760 [(set (match_dup 0) (match_dup 1))
5761 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5762 (clobber (reg:CC FLAGS_REG))])])
5764 ;; Split non destructive adds if we cannot use lea.
5766 [(set (match_operand:DI 0 "register_operand")
5768 (plus:SI (match_operand:SI 1 "register_operand")
5769 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5770 (clobber (reg:CC FLAGS_REG))]
5772 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5773 [(set (match_dup 3) (match_dup 1))
5774 (parallel [(set (match_dup 0)
5775 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5776 (clobber (reg:CC FLAGS_REG))])]
5777 "operands[3] = gen_lowpart (SImode, operands[0]);")
5779 ;; Convert add to the lea pattern to avoid flags dependency.
5781 [(set (match_operand:SWI 0 "register_operand")
5782 (plus:SWI (match_operand:SWI 1 "register_operand")
5783 (match_operand:SWI 2 "<nonmemory_operand>")))
5784 (clobber (reg:CC FLAGS_REG))]
5785 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5787 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
5789 if (<MODE>mode != <LEAMODE>mode)
5791 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
5792 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
5793 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
5797 ;; Convert add to the lea pattern to avoid flags dependency.
5799 [(set (match_operand:DI 0 "register_operand")
5801 (plus:SI (match_operand:SI 1 "register_operand")
5802 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5803 (clobber (reg:CC FLAGS_REG))]
5804 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5806 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5808 (define_insn "*add<mode>_2"
5809 [(set (reg FLAGS_REG)
5812 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5813 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5815 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5816 (plus:SWI (match_dup 1) (match_dup 2)))]
5817 "ix86_match_ccmode (insn, CCGOCmode)
5818 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5820 switch (get_attr_type (insn))
5823 if (operands[2] == const1_rtx)
5824 return "inc{<imodesuffix>}\t%0";
5827 gcc_assert (operands[2] == constm1_rtx);
5828 return "dec{<imodesuffix>}\t%0";
5832 if (which_alternative == 2)
5833 std::swap (operands[1], operands[2]);
5835 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5836 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5837 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5839 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5843 (if_then_else (match_operand:SWI 2 "incdec_operand")
5844 (const_string "incdec")
5845 (const_string "alu")))
5846 (set (attr "length_immediate")
5848 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5850 (const_string "*")))
5851 (set_attr "mode" "<MODE>")])
5853 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5854 (define_insn "*addsi_2_zext"
5855 [(set (reg FLAGS_REG)
5857 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5858 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5860 (set (match_operand:DI 0 "register_operand" "=r,r")
5861 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5862 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5863 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5865 switch (get_attr_type (insn))
5868 if (operands[2] == const1_rtx)
5869 return "inc{l}\t%k0";
5872 gcc_assert (operands[2] == constm1_rtx);
5873 return "dec{l}\t%k0";
5877 if (which_alternative == 1)
5878 std::swap (operands[1], operands[2]);
5880 if (x86_maybe_negate_const_int (&operands[2], SImode))
5881 return "sub{l}\t{%2, %k0|%k0, %2}";
5883 return "add{l}\t{%2, %k0|%k0, %2}";
5887 (if_then_else (match_operand:SI 2 "incdec_operand")
5888 (const_string "incdec")
5889 (const_string "alu")))
5890 (set (attr "length_immediate")
5892 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5894 (const_string "*")))
5895 (set_attr "mode" "SI")])
5897 (define_insn "*add<mode>_3"
5898 [(set (reg FLAGS_REG)
5900 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5901 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5902 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5903 "ix86_match_ccmode (insn, CCZmode)
5904 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5906 switch (get_attr_type (insn))
5909 if (operands[2] == const1_rtx)
5910 return "inc{<imodesuffix>}\t%0";
5913 gcc_assert (operands[2] == constm1_rtx);
5914 return "dec{<imodesuffix>}\t%0";
5918 if (which_alternative == 1)
5919 std::swap (operands[1], operands[2]);
5921 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5922 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5923 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5925 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5929 (if_then_else (match_operand:SWI 2 "incdec_operand")
5930 (const_string "incdec")
5931 (const_string "alu")))
5932 (set (attr "length_immediate")
5934 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5936 (const_string "*")))
5937 (set_attr "mode" "<MODE>")])
5939 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5940 (define_insn "*addsi_3_zext"
5941 [(set (reg FLAGS_REG)
5943 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5944 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5945 (set (match_operand:DI 0 "register_operand" "=r,r")
5946 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5947 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5948 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5950 switch (get_attr_type (insn))
5953 if (operands[2] == const1_rtx)
5954 return "inc{l}\t%k0";
5957 gcc_assert (operands[2] == constm1_rtx);
5958 return "dec{l}\t%k0";
5962 if (which_alternative == 1)
5963 std::swap (operands[1], operands[2]);
5965 if (x86_maybe_negate_const_int (&operands[2], SImode))
5966 return "sub{l}\t{%2, %k0|%k0, %2}";
5968 return "add{l}\t{%2, %k0|%k0, %2}";
5972 (if_then_else (match_operand:SI 2 "incdec_operand")
5973 (const_string "incdec")
5974 (const_string "alu")))
5975 (set (attr "length_immediate")
5977 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5979 (const_string "*")))
5980 (set_attr "mode" "SI")])
5982 ; For comparisons against 1, -1 and 128, we may generate better code
5983 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5984 ; is matched then. We can't accept general immediate, because for
5985 ; case of overflows, the result is messed up.
5986 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5987 ; only for comparisons not depending on it.
5989 (define_insn "*adddi_4"
5990 [(set (reg FLAGS_REG)
5992 (match_operand:DI 1 "nonimmediate_operand" "0")
5993 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5994 (clobber (match_scratch:DI 0 "=rm"))]
5996 && ix86_match_ccmode (insn, CCGCmode)"
5998 switch (get_attr_type (insn))
6001 if (operands[2] == constm1_rtx)
6002 return "inc{q}\t%0";
6005 gcc_assert (operands[2] == const1_rtx);
6006 return "dec{q}\t%0";
6010 if (x86_maybe_negate_const_int (&operands[2], DImode))
6011 return "add{q}\t{%2, %0|%0, %2}";
6013 return "sub{q}\t{%2, %0|%0, %2}";
6017 (if_then_else (match_operand:DI 2 "incdec_operand")
6018 (const_string "incdec")
6019 (const_string "alu")))
6020 (set (attr "length_immediate")
6022 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6024 (const_string "*")))
6025 (set_attr "mode" "DI")])
6027 ; For comparisons against 1, -1 and 128, we may generate better code
6028 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6029 ; is matched then. We can't accept general immediate, because for
6030 ; case of overflows, the result is messed up.
6031 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6032 ; only for comparisons not depending on it.
6034 (define_insn "*add<mode>_4"
6035 [(set (reg FLAGS_REG)
6037 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6038 (match_operand:SWI124 2 "const_int_operand" "n")))
6039 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6040 "ix86_match_ccmode (insn, CCGCmode)"
6042 switch (get_attr_type (insn))
6045 if (operands[2] == constm1_rtx)
6046 return "inc{<imodesuffix>}\t%0";
6049 gcc_assert (operands[2] == const1_rtx);
6050 return "dec{<imodesuffix>}\t%0";
6054 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6055 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6057 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6061 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6062 (const_string "incdec")
6063 (const_string "alu")))
6064 (set (attr "length_immediate")
6066 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6068 (const_string "*")))
6069 (set_attr "mode" "<MODE>")])
6071 (define_insn "*add<mode>_5"
6072 [(set (reg FLAGS_REG)
6075 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6076 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6078 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6079 "ix86_match_ccmode (insn, CCGOCmode)
6080 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6082 switch (get_attr_type (insn))
6085 if (operands[2] == const1_rtx)
6086 return "inc{<imodesuffix>}\t%0";
6089 gcc_assert (operands[2] == constm1_rtx);
6090 return "dec{<imodesuffix>}\t%0";
6094 if (which_alternative == 1)
6095 std::swap (operands[1], operands[2]);
6097 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6098 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6099 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6101 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6105 (if_then_else (match_operand:SWI 2 "incdec_operand")
6106 (const_string "incdec")
6107 (const_string "alu")))
6108 (set (attr "length_immediate")
6110 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6112 (const_string "*")))
6113 (set_attr "mode" "<MODE>")])
6115 (define_insn "addqi_ext_1"
6116 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
6121 (match_operand 1 "ext_register_operand" "0,0")
6124 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
6125 (clobber (reg:CC FLAGS_REG))]
6128 switch (get_attr_type (insn))
6131 if (operands[2] == const1_rtx)
6132 return "inc{b}\t%h0";
6135 gcc_assert (operands[2] == constm1_rtx);
6136 return "dec{b}\t%h0";
6140 return "add{b}\t{%2, %h0|%h0, %2}";
6143 [(set_attr "isa" "*,nox64")
6145 (if_then_else (match_operand:QI 2 "incdec_operand")
6146 (const_string "incdec")
6147 (const_string "alu")))
6148 (set_attr "modrm" "1")
6149 (set_attr "mode" "QI")])
6151 (define_insn "*addqi_ext_2"
6152 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6157 (match_operand 1 "ext_register_operand" "%0")
6161 (match_operand 2 "ext_register_operand" "Q")
6164 (clobber (reg:CC FLAGS_REG))]
6166 "add{b}\t{%h2, %h0|%h0, %h2}"
6167 [(set_attr "type" "alu")
6168 (set_attr "mode" "QI")])
6170 ;; Add with jump on overflow.
6171 (define_expand "addv<mode>4"
6172 [(parallel [(set (reg:CCO FLAGS_REG)
6175 (match_operand:SWI 1 "nonimmediate_operand"))
6178 (plus:SWI (match_dup 1)
6179 (match_operand:SWI 2
6180 "<general_operand>")))))
6181 (set (match_operand:SWI 0 "register_operand")
6182 (plus:SWI (match_dup 1) (match_dup 2)))])
6183 (set (pc) (if_then_else
6184 (eq (reg:CCO FLAGS_REG) (const_int 0))
6185 (label_ref (match_operand 3))
6189 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6190 if (CONST_INT_P (operands[2]))
6191 operands[4] = operands[2];
6193 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6196 (define_insn "*addv<mode>4"
6197 [(set (reg:CCO FLAGS_REG)
6200 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6202 (match_operand:SWI 2 "<general_sext_operand>"
6205 (plus:SWI (match_dup 1) (match_dup 2)))))
6206 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6207 (plus:SWI (match_dup 1) (match_dup 2)))]
6208 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6209 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6210 [(set_attr "type" "alu")
6211 (set_attr "mode" "<MODE>")])
6213 (define_insn "*addv<mode>4_1"
6214 [(set (reg:CCO FLAGS_REG)
6217 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6218 (match_operand:<DWI> 3 "const_int_operand" "i"))
6220 (plus:SWI (match_dup 1)
6221 (match_operand:SWI 2 "x86_64_immediate_operand"
6223 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6224 (plus:SWI (match_dup 1) (match_dup 2)))]
6225 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6226 && CONST_INT_P (operands[2])
6227 && INTVAL (operands[2]) == INTVAL (operands[3])"
6228 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6229 [(set_attr "type" "alu")
6230 (set_attr "mode" "<MODE>")
6231 (set (attr "length_immediate")
6232 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6234 (match_test "<MODE_SIZE> == 8")
6236 (const_string "<MODE_SIZE>")))])
6238 (define_expand "uaddv<mode>4"
6239 [(parallel [(set (reg:CCC FLAGS_REG)
6242 (match_operand:SWI 1 "nonimmediate_operand")
6243 (match_operand:SWI 2 "<general_operand>"))
6245 (set (match_operand:SWI 0 "register_operand")
6246 (plus:SWI (match_dup 1) (match_dup 2)))])
6247 (set (pc) (if_then_else
6248 (ltu (reg:CCC FLAGS_REG) (const_int 0))
6249 (label_ref (match_operand 3))
6252 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6254 ;; The lea patterns for modes less than 32 bits need to be matched by
6255 ;; several insns converted to real lea by splitters.
6257 (define_insn_and_split "*lea<mode>_general_1"
6258 [(set (match_operand:SWI12 0 "register_operand" "=r")
6260 (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6261 (match_operand:SWI12 2 "register_operand" "r"))
6262 (match_operand:SWI12 3 "immediate_operand" "i")))]
6263 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6265 "&& reload_completed"
6268 (plus:SI (match_dup 1) (match_dup 2))
6271 operands[0] = gen_lowpart (SImode, operands[0]);
6272 operands[1] = gen_lowpart (SImode, operands[1]);
6273 operands[2] = gen_lowpart (SImode, operands[2]);
6274 operands[3] = gen_lowpart (SImode, operands[3]);
6276 [(set_attr "type" "lea")
6277 (set_attr "mode" "SI")])
6279 (define_insn_and_split "*lea<mode>_general_2"
6280 [(set (match_operand:SWI12 0 "register_operand" "=r")
6282 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6283 (match_operand 2 "const248_operand" "n"))
6284 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6285 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6287 "&& reload_completed"
6290 (mult:SI (match_dup 1) (match_dup 2))
6293 operands[0] = gen_lowpart (SImode, operands[0]);
6294 operands[1] = gen_lowpart (SImode, operands[1]);
6295 operands[3] = gen_lowpart (SImode, operands[3]);
6297 [(set_attr "type" "lea")
6298 (set_attr "mode" "SI")])
6300 (define_insn_and_split "*lea<mode>_general_3"
6301 [(set (match_operand:SWI12 0 "register_operand" "=r")
6304 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6305 (match_operand 2 "const248_operand" "n"))
6306 (match_operand:SWI12 3 "register_operand" "r"))
6307 (match_operand:SWI12 4 "immediate_operand" "i")))]
6308 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6310 "&& reload_completed"
6314 (mult:SI (match_dup 1) (match_dup 2))
6318 operands[0] = gen_lowpart (SImode, operands[0]);
6319 operands[1] = gen_lowpart (SImode, operands[1]);
6320 operands[3] = gen_lowpart (SImode, operands[3]);
6321 operands[4] = gen_lowpart (SImode, operands[4]);
6323 [(set_attr "type" "lea")
6324 (set_attr "mode" "SI")])
6326 (define_insn_and_split "*lea<mode>_general_4"
6327 [(set (match_operand:SWI12 0 "register_operand" "=r")
6330 (match_operand:SWI12 1 "index_register_operand" "l")
6331 (match_operand 2 "const_0_to_3_operand" "n"))
6332 (match_operand 3 "const_int_operand" "n")))]
6333 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6334 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6335 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6337 "&& reload_completed"
6340 (mult:SI (match_dup 1) (match_dup 2))
6343 operands[0] = gen_lowpart (SImode, operands[0]);
6344 operands[1] = gen_lowpart (SImode, operands[1]);
6345 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6347 [(set_attr "type" "lea")
6348 (set_attr "mode" "SI")])
6350 (define_insn_and_split "*lea<mode>_general_4"
6351 [(set (match_operand:SWI48 0 "register_operand" "=r")
6354 (match_operand:SWI48 1 "index_register_operand" "l")
6355 (match_operand 2 "const_0_to_3_operand" "n"))
6356 (match_operand 3 "const_int_operand" "n")))]
6357 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6358 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6360 "&& reload_completed"
6363 (mult:SWI48 (match_dup 1) (match_dup 2))
6365 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6366 [(set_attr "type" "lea")
6367 (set_attr "mode" "<MODE>")])
6369 ;; Subtract instructions
6371 (define_expand "sub<mode>3"
6372 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6373 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6374 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6376 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6378 (define_insn_and_split "*sub<dwi>3_doubleword"
6379 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6381 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6382 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
6384 (clobber (reg:CC FLAGS_REG))]
6385 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6388 [(parallel [(set (reg:CC FLAGS_REG)
6389 (compare:CC (match_dup 1) (match_dup 2)))
6391 (minus:DWIH (match_dup 1) (match_dup 2)))])
6392 (parallel [(set (match_dup 3)
6396 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6398 (clobber (reg:CC FLAGS_REG))])]
6400 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6401 if (operands[2] == const0_rtx)
6403 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6408 (define_insn "*sub<mode>_1"
6409 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6411 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6412 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6413 (clobber (reg:CC FLAGS_REG))]
6414 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6415 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6416 [(set_attr "type" "alu")
6417 (set_attr "mode" "<MODE>")])
6419 (define_insn "*subsi_1_zext"
6420 [(set (match_operand:DI 0 "register_operand" "=r")
6422 (minus:SI (match_operand:SI 1 "register_operand" "0")
6423 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6424 (clobber (reg:CC FLAGS_REG))]
6425 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6426 "sub{l}\t{%2, %k0|%k0, %2}"
6427 [(set_attr "type" "alu")
6428 (set_attr "mode" "SI")])
6430 (define_insn "*subqi_1_slp"
6431 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6432 (minus:QI (match_dup 0)
6433 (match_operand:QI 1 "general_operand" "qn,qm")))
6434 (clobber (reg:CC FLAGS_REG))]
6435 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6436 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6437 "sub{b}\t{%1, %0|%0, %1}"
6438 [(set_attr "type" "alu1")
6439 (set_attr "mode" "QI")])
6441 (define_insn "*sub<mode>_2"
6442 [(set (reg FLAGS_REG)
6445 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6446 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6448 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6449 (minus:SWI (match_dup 1) (match_dup 2)))]
6450 "ix86_match_ccmode (insn, CCGOCmode)
6451 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6452 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6453 [(set_attr "type" "alu")
6454 (set_attr "mode" "<MODE>")])
6456 (define_insn "*subsi_2_zext"
6457 [(set (reg FLAGS_REG)
6459 (minus:SI (match_operand:SI 1 "register_operand" "0")
6460 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6462 (set (match_operand:DI 0 "register_operand" "=r")
6464 (minus:SI (match_dup 1)
6466 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6467 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6468 "sub{l}\t{%2, %k0|%k0, %2}"
6469 [(set_attr "type" "alu")
6470 (set_attr "mode" "SI")])
6472 ;; Subtract with jump on overflow.
6473 (define_expand "subv<mode>4"
6474 [(parallel [(set (reg:CCO FLAGS_REG)
6475 (eq:CCO (minus:<DWI>
6477 (match_operand:SWI 1 "nonimmediate_operand"))
6480 (minus:SWI (match_dup 1)
6481 (match_operand:SWI 2
6482 "<general_operand>")))))
6483 (set (match_operand:SWI 0 "register_operand")
6484 (minus:SWI (match_dup 1) (match_dup 2)))])
6485 (set (pc) (if_then_else
6486 (eq (reg:CCO FLAGS_REG) (const_int 0))
6487 (label_ref (match_operand 3))
6491 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6492 if (CONST_INT_P (operands[2]))
6493 operands[4] = operands[2];
6495 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6498 (define_insn "*subv<mode>4"
6499 [(set (reg:CCO FLAGS_REG)
6500 (eq:CCO (minus:<DWI>
6502 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6504 (match_operand:SWI 2 "<general_sext_operand>"
6507 (minus:SWI (match_dup 1) (match_dup 2)))))
6508 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6509 (minus:SWI (match_dup 1) (match_dup 2)))]
6510 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6511 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6512 [(set_attr "type" "alu")
6513 (set_attr "mode" "<MODE>")])
6515 (define_insn "*subv<mode>4_1"
6516 [(set (reg:CCO FLAGS_REG)
6517 (eq:CCO (minus:<DWI>
6519 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6520 (match_operand:<DWI> 3 "const_int_operand" "i"))
6522 (minus:SWI (match_dup 1)
6523 (match_operand:SWI 2 "x86_64_immediate_operand"
6525 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6526 (minus:SWI (match_dup 1) (match_dup 2)))]
6527 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6528 && CONST_INT_P (operands[2])
6529 && INTVAL (operands[2]) == INTVAL (operands[3])"
6530 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6531 [(set_attr "type" "alu")
6532 (set_attr "mode" "<MODE>")
6533 (set (attr "length_immediate")
6534 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6536 (match_test "<MODE_SIZE> == 8")
6538 (const_string "<MODE_SIZE>")))])
6540 (define_expand "usubv<mode>4"
6541 [(parallel [(set (reg:CC FLAGS_REG)
6543 (match_operand:SWI 1 "nonimmediate_operand")
6544 (match_operand:SWI 2 "<general_operand>")))
6545 (set (match_operand:SWI 0 "register_operand")
6546 (minus:SWI (match_dup 1) (match_dup 2)))])
6547 (set (pc) (if_then_else
6548 (ltu (reg:CC FLAGS_REG) (const_int 0))
6549 (label_ref (match_operand 3))
6552 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6554 (define_insn "*sub<mode>_3"
6555 [(set (reg FLAGS_REG)
6556 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6557 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6558 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6559 (minus:SWI (match_dup 1) (match_dup 2)))]
6560 "ix86_match_ccmode (insn, CCmode)
6561 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6562 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6563 [(set_attr "type" "alu")
6564 (set_attr "mode" "<MODE>")])
6566 (define_insn "*subsi_3_zext"
6567 [(set (reg FLAGS_REG)
6568 (compare (match_operand:SI 1 "register_operand" "0")
6569 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6570 (set (match_operand:DI 0 "register_operand" "=r")
6572 (minus:SI (match_dup 1)
6574 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6575 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6576 "sub{l}\t{%2, %1|%1, %2}"
6577 [(set_attr "type" "alu")
6578 (set_attr "mode" "SI")])
6580 ;; Add with carry and subtract with borrow
6582 (define_insn "add<mode>3_carry"
6583 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6586 (match_operator:SWI 4 "ix86_carry_flag_operator"
6587 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6588 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6589 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6590 (clobber (reg:CC FLAGS_REG))]
6591 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6592 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6593 [(set_attr "type" "alu")
6594 (set_attr "use_carry" "1")
6595 (set_attr "pent_pair" "pu")
6596 (set_attr "mode" "<MODE>")])
6598 (define_insn "*addsi3_carry_zext"
6599 [(set (match_operand:DI 0 "register_operand" "=r")
6602 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6603 [(reg FLAGS_REG) (const_int 0)])
6604 (match_operand:SI 1 "register_operand" "%0"))
6605 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6606 (clobber (reg:CC FLAGS_REG))]
6607 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6608 "adc{l}\t{%2, %k0|%k0, %2}"
6609 [(set_attr "type" "alu")
6610 (set_attr "use_carry" "1")
6611 (set_attr "pent_pair" "pu")
6612 (set_attr "mode" "SI")])
6614 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6616 (define_insn "addcarry<mode>"
6617 [(set (reg:CCC FLAGS_REG)
6621 (match_operator:SWI48 4 "ix86_carry_flag_operator"
6622 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6623 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6624 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))
6626 (set (match_operand:SWI48 0 "register_operand" "=r")
6627 (plus:SWI48 (plus:SWI48 (match_op_dup 4
6628 [(match_dup 3) (const_int 0)])
6631 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6632 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6633 [(set_attr "type" "alu")
6634 (set_attr "use_carry" "1")
6635 (set_attr "pent_pair" "pu")
6636 (set_attr "mode" "<MODE>")])
6638 (define_insn "sub<mode>3_carry"
6639 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6642 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6643 (match_operator:SWI 4 "ix86_carry_flag_operator"
6644 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6645 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6646 (clobber (reg:CC FLAGS_REG))]
6647 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6648 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6649 [(set_attr "type" "alu")
6650 (set_attr "use_carry" "1")
6651 (set_attr "pent_pair" "pu")
6652 (set_attr "mode" "<MODE>")])
6654 (define_insn "*subsi3_carry_zext"
6655 [(set (match_operand:DI 0 "register_operand" "=r")
6659 (match_operand:SI 1 "register_operand" "0")
6660 (match_operator:SI 3 "ix86_carry_flag_operator"
6661 [(reg FLAGS_REG) (const_int 0)]))
6662 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6663 (clobber (reg:CC FLAGS_REG))]
6664 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6665 "sbb{l}\t{%2, %k0|%k0, %2}"
6666 [(set_attr "type" "alu")
6667 (set_attr "use_carry" "1")
6668 (set_attr "pent_pair" "pu")
6669 (set_attr "mode" "SI")])
6671 (define_insn "subborrow<mode>"
6672 [(set (reg:CCC FLAGS_REG)
6674 (match_operand:SWI48 1 "nonimmediate_operand" "0")
6676 (match_operator:SWI48 4 "ix86_carry_flag_operator"
6677 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6678 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
6679 (set (match_operand:SWI48 0 "register_operand" "=r")
6680 (minus:SWI48 (minus:SWI48 (match_dup 1)
6682 [(match_dup 3) (const_int 0)]))
6684 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6685 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6686 [(set_attr "type" "alu")
6687 (set_attr "use_carry" "1")
6688 (set_attr "pent_pair" "pu")
6689 (set_attr "mode" "<MODE>")])
6691 ;; Overflow setting add instructions
6693 (define_expand "addqi3_cconly_overflow"
6695 [(set (reg:CCC FLAGS_REG)
6698 (match_operand:QI 0 "nonimmediate_operand")
6699 (match_operand:QI 1 "general_operand"))
6701 (clobber (match_scratch:QI 2))])]
6702 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
6704 (define_insn "*add<mode>3_cconly_overflow_1"
6705 [(set (reg:CCC FLAGS_REG)
6708 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6709 (match_operand:SWI 2 "<general_operand>" "<g>"))
6711 (clobber (match_scratch:SWI 0 "=<r>"))]
6712 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6713 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6714 [(set_attr "type" "alu")
6715 (set_attr "mode" "<MODE>")])
6717 (define_insn "*add<mode>3_cconly_overflow_2"
6718 [(set (reg:CCC FLAGS_REG)
6721 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6722 (match_operand:SWI 2 "<general_operand>" "<g>"))
6724 (clobber (match_scratch:SWI 0 "=<r>"))]
6725 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6726 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6727 [(set_attr "type" "alu")
6728 (set_attr "mode" "<MODE>")])
6730 (define_insn "*add<mode>3_cc_overflow_1"
6731 [(set (reg:CCC FLAGS_REG)
6734 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6735 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6737 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6738 (plus:SWI (match_dup 1) (match_dup 2)))]
6739 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6740 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6741 [(set_attr "type" "alu")
6742 (set_attr "mode" "<MODE>")])
6744 (define_insn "*add<mode>3_cc_overflow_2"
6745 [(set (reg:CCC FLAGS_REG)
6748 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6749 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6751 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6752 (plus:SWI (match_dup 1) (match_dup 2)))]
6753 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6754 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6755 [(set_attr "type" "alu")
6756 (set_attr "mode" "<MODE>")])
6758 (define_insn "*addsi3_zext_cc_overflow_1"
6759 [(set (reg:CCC FLAGS_REG)
6762 (match_operand:SI 1 "nonimmediate_operand" "%0")
6763 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6765 (set (match_operand:DI 0 "register_operand" "=r")
6766 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6767 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6768 "add{l}\t{%2, %k0|%k0, %2}"
6769 [(set_attr "type" "alu")
6770 (set_attr "mode" "SI")])
6772 (define_insn "*addsi3_zext_cc_overflow_2"
6773 [(set (reg:CCC FLAGS_REG)
6776 (match_operand:SI 1 "nonimmediate_operand" "%0")
6777 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6779 (set (match_operand:DI 0 "register_operand" "=r")
6780 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6781 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6782 "add{l}\t{%2, %k0|%k0, %2}"
6783 [(set_attr "type" "alu")
6784 (set_attr "mode" "SI")])
6786 ;; The patterns that match these are at the end of this file.
6788 (define_expand "<plusminus_insn>xf3"
6789 [(set (match_operand:XF 0 "register_operand")
6791 (match_operand:XF 1 "register_operand")
6792 (match_operand:XF 2 "register_operand")))]
6795 (define_expand "<plusminus_insn><mode>3"
6796 [(set (match_operand:MODEF 0 "register_operand")
6798 (match_operand:MODEF 1 "register_operand")
6799 (match_operand:MODEF 2 "nonimmediate_operand")))]
6800 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6801 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6803 ;; Multiply instructions
6805 (define_expand "mul<mode>3"
6806 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6808 (match_operand:SWIM248 1 "register_operand")
6809 (match_operand:SWIM248 2 "<general_operand>")))
6810 (clobber (reg:CC FLAGS_REG))])])
6812 (define_expand "mulqi3"
6813 [(parallel [(set (match_operand:QI 0 "register_operand")
6815 (match_operand:QI 1 "register_operand")
6816 (match_operand:QI 2 "nonimmediate_operand")))
6817 (clobber (reg:CC FLAGS_REG))])]
6818 "TARGET_QIMODE_MATH")
6821 ;; IMUL reg32/64, reg32/64, imm8 Direct
6822 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6823 ;; IMUL reg32/64, reg32/64, imm32 Direct
6824 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6825 ;; IMUL reg32/64, reg32/64 Direct
6826 ;; IMUL reg32/64, mem32/64 Direct
6828 ;; On BDVER1, all above IMULs use DirectPath
6831 ;; IMUL reg16, reg16, imm8 VectorPath
6832 ;; IMUL reg16, mem16, imm8 VectorPath
6833 ;; IMUL reg16, reg16, imm16 VectorPath
6834 ;; IMUL reg16, mem16, imm16 VectorPath
6835 ;; IMUL reg16, reg16 Direct
6836 ;; IMUL reg16, mem16 Direct
6838 ;; On BDVER1, all HI MULs use DoublePath
6840 (define_insn "*mul<mode>3_1"
6841 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
6843 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
6844 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
6845 (clobber (reg:CC FLAGS_REG))]
6846 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6848 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6849 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6850 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6851 [(set_attr "type" "imul")
6852 (set_attr "prefix_0f" "0,0,1")
6853 (set (attr "athlon_decode")
6854 (cond [(eq_attr "cpu" "athlon")
6855 (const_string "vector")
6856 (eq_attr "alternative" "1")
6857 (const_string "vector")
6858 (and (eq_attr "alternative" "2")
6859 (ior (match_test "<MODE>mode == HImode")
6860 (match_operand 1 "memory_operand")))
6861 (const_string "vector")]
6862 (const_string "direct")))
6863 (set (attr "amdfam10_decode")
6864 (cond [(and (eq_attr "alternative" "0,1")
6865 (ior (match_test "<MODE>mode == HImode")
6866 (match_operand 1 "memory_operand")))
6867 (const_string "vector")]
6868 (const_string "direct")))
6869 (set (attr "bdver1_decode")
6871 (match_test "<MODE>mode == HImode")
6872 (const_string "double")
6873 (const_string "direct")))
6874 (set_attr "mode" "<MODE>")])
6876 (define_insn "*mulsi3_1_zext"
6877 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6879 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6880 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6881 (clobber (reg:CC FLAGS_REG))]
6883 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6885 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6886 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6887 imul{l}\t{%2, %k0|%k0, %2}"
6888 [(set_attr "type" "imul")
6889 (set_attr "prefix_0f" "0,0,1")
6890 (set (attr "athlon_decode")
6891 (cond [(eq_attr "cpu" "athlon")
6892 (const_string "vector")
6893 (eq_attr "alternative" "1")
6894 (const_string "vector")
6895 (and (eq_attr "alternative" "2")
6896 (match_operand 1 "memory_operand"))
6897 (const_string "vector")]
6898 (const_string "direct")))
6899 (set (attr "amdfam10_decode")
6900 (cond [(and (eq_attr "alternative" "0,1")
6901 (match_operand 1 "memory_operand"))
6902 (const_string "vector")]
6903 (const_string "direct")))
6904 (set_attr "bdver1_decode" "direct")
6905 (set_attr "mode" "SI")])
6907 ;;On AMDFAM10 and BDVER1
6911 (define_insn "*mulqi3_1"
6912 [(set (match_operand:QI 0 "register_operand" "=a")
6913 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6914 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6915 (clobber (reg:CC FLAGS_REG))]
6917 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6919 [(set_attr "type" "imul")
6920 (set_attr "length_immediate" "0")
6921 (set (attr "athlon_decode")
6922 (if_then_else (eq_attr "cpu" "athlon")
6923 (const_string "vector")
6924 (const_string "direct")))
6925 (set_attr "amdfam10_decode" "direct")
6926 (set_attr "bdver1_decode" "direct")
6927 (set_attr "mode" "QI")])
6929 ;; Multiply with jump on overflow.
6930 (define_expand "mulv<mode>4"
6931 [(parallel [(set (reg:CCO FLAGS_REG)
6934 (match_operand:SWI248 1 "register_operand"))
6937 (mult:SWI248 (match_dup 1)
6938 (match_operand:SWI248 2
6939 "<general_operand>")))))
6940 (set (match_operand:SWI248 0 "register_operand")
6941 (mult:SWI248 (match_dup 1) (match_dup 2)))])
6942 (set (pc) (if_then_else
6943 (eq (reg:CCO FLAGS_REG) (const_int 0))
6944 (label_ref (match_operand 3))
6948 if (CONST_INT_P (operands[2]))
6949 operands[4] = operands[2];
6951 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6954 (define_insn "*mulv<mode>4"
6955 [(set (reg:CCO FLAGS_REG)
6958 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6960 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
6962 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6963 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6964 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6965 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6967 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6968 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6969 [(set_attr "type" "imul")
6970 (set_attr "prefix_0f" "0,1")
6971 (set (attr "athlon_decode")
6972 (cond [(eq_attr "cpu" "athlon")
6973 (const_string "vector")
6974 (eq_attr "alternative" "0")
6975 (const_string "vector")
6976 (and (eq_attr "alternative" "1")
6977 (match_operand 1 "memory_operand"))
6978 (const_string "vector")]
6979 (const_string "direct")))
6980 (set (attr "amdfam10_decode")
6981 (cond [(and (eq_attr "alternative" "1")
6982 (match_operand 1 "memory_operand"))
6983 (const_string "vector")]
6984 (const_string "direct")))
6985 (set_attr "bdver1_decode" "direct")
6986 (set_attr "mode" "<MODE>")])
6988 (define_insn "*mulvhi4"
6989 [(set (reg:CCO FLAGS_REG)
6992 (match_operand:HI 1 "nonimmediate_operand" "%0"))
6994 (match_operand:HI 2 "nonimmediate_operand" "mr")))
6996 (mult:HI (match_dup 1) (match_dup 2)))))
6997 (set (match_operand:HI 0 "register_operand" "=r")
6998 (mult:HI (match_dup 1) (match_dup 2)))]
6999 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7000 "imul{w}\t{%2, %0|%0, %2}"
7001 [(set_attr "type" "imul")
7002 (set_attr "prefix_0f" "1")
7003 (set_attr "athlon_decode" "vector")
7004 (set_attr "amdfam10_decode" "direct")
7005 (set_attr "bdver1_decode" "double")
7006 (set_attr "mode" "HI")])
7008 (define_insn "*mulv<mode>4_1"
7009 [(set (reg:CCO FLAGS_REG)
7012 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7013 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7015 (mult:SWI248 (match_dup 1)
7016 (match_operand:SWI248 2
7017 "<immediate_operand>" "K,<i>")))))
7018 (set (match_operand:SWI248 0 "register_operand" "=r,r")
7019 (mult:SWI248 (match_dup 1) (match_dup 2)))]
7020 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7021 && CONST_INT_P (operands[2])
7022 && INTVAL (operands[2]) == INTVAL (operands[3])"
7023 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7024 [(set_attr "type" "imul")
7025 (set (attr "prefix_0f")
7027 (match_test "<MODE>mode == HImode")
7029 (const_string "*")))
7030 (set (attr "athlon_decode")
7031 (cond [(eq_attr "cpu" "athlon")
7032 (const_string "vector")
7033 (eq_attr "alternative" "1")
7034 (const_string "vector")]
7035 (const_string "direct")))
7036 (set (attr "amdfam10_decode")
7037 (cond [(ior (match_test "<MODE>mode == HImode")
7038 (match_operand 1 "memory_operand"))
7039 (const_string "vector")]
7040 (const_string "direct")))
7041 (set (attr "bdver1_decode")
7043 (match_test "<MODE>mode == HImode")
7044 (const_string "double")
7045 (const_string "direct")))
7046 (set_attr "mode" "<MODE>")
7047 (set (attr "length_immediate")
7048 (cond [(eq_attr "alternative" "0")
7050 (match_test "<MODE_SIZE> == 8")
7052 (const_string "<MODE_SIZE>")))])
7054 (define_expand "umulv<mode>4"
7055 [(parallel [(set (reg:CCO FLAGS_REG)
7058 (match_operand:SWI248 1
7059 "nonimmediate_operand"))
7061 (match_operand:SWI248 2
7062 "nonimmediate_operand")))
7064 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7065 (set (match_operand:SWI248 0 "register_operand")
7066 (mult:SWI248 (match_dup 1) (match_dup 2)))
7067 (clobber (match_scratch:SWI248 4))])
7068 (set (pc) (if_then_else
7069 (eq (reg:CCO FLAGS_REG) (const_int 0))
7070 (label_ref (match_operand 3))
7074 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7075 operands[1] = force_reg (<MODE>mode, operands[1]);
7078 (define_insn "*umulv<mode>4"
7079 [(set (reg:CCO FLAGS_REG)
7082 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7084 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7086 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7087 (set (match_operand:SWI248 0 "register_operand" "=a")
7088 (mult:SWI248 (match_dup 1) (match_dup 2)))
7089 (clobber (match_scratch:SWI248 3 "=d"))]
7090 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7091 "mul{<imodesuffix>}\t%2"
7092 [(set_attr "type" "imul")
7093 (set_attr "length_immediate" "0")
7094 (set (attr "athlon_decode")
7095 (if_then_else (eq_attr "cpu" "athlon")
7096 (const_string "vector")
7097 (const_string "double")))
7098 (set_attr "amdfam10_decode" "double")
7099 (set_attr "bdver1_decode" "direct")
7100 (set_attr "mode" "<MODE>")])
7102 (define_expand "<u>mulvqi4"
7103 [(parallel [(set (reg:CCO FLAGS_REG)
7106 (match_operand:QI 1 "nonimmediate_operand"))
7108 (match_operand:QI 2 "nonimmediate_operand")))
7110 (mult:QI (match_dup 1) (match_dup 2)))))
7111 (set (match_operand:QI 0 "register_operand")
7112 (mult:QI (match_dup 1) (match_dup 2)))])
7113 (set (pc) (if_then_else
7114 (eq (reg:CCO FLAGS_REG) (const_int 0))
7115 (label_ref (match_operand 3))
7117 "TARGET_QIMODE_MATH"
7119 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7120 operands[1] = force_reg (QImode, operands[1]);
7123 (define_insn "*<u>mulvqi4"
7124 [(set (reg:CCO FLAGS_REG)
7127 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7129 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7131 (mult:QI (match_dup 1) (match_dup 2)))))
7132 (set (match_operand:QI 0 "register_operand" "=a")
7133 (mult:QI (match_dup 1) (match_dup 2)))]
7135 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7136 "<sgnprefix>mul{b}\t%2"
7137 [(set_attr "type" "imul")
7138 (set_attr "length_immediate" "0")
7139 (set (attr "athlon_decode")
7140 (if_then_else (eq_attr "cpu" "athlon")
7141 (const_string "vector")
7142 (const_string "direct")))
7143 (set_attr "amdfam10_decode" "direct")
7144 (set_attr "bdver1_decode" "direct")
7145 (set_attr "mode" "QI")])
7147 (define_expand "<u>mul<mode><dwi>3"
7148 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7151 (match_operand:DWIH 1 "nonimmediate_operand"))
7153 (match_operand:DWIH 2 "register_operand"))))
7154 (clobber (reg:CC FLAGS_REG))])])
7156 (define_expand "<u>mulqihi3"
7157 [(parallel [(set (match_operand:HI 0 "register_operand")
7160 (match_operand:QI 1 "nonimmediate_operand"))
7162 (match_operand:QI 2 "register_operand"))))
7163 (clobber (reg:CC FLAGS_REG))])]
7164 "TARGET_QIMODE_MATH")
7166 (define_insn "*bmi2_umul<mode><dwi>3_1"
7167 [(set (match_operand:DWIH 0 "register_operand" "=r")
7169 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7170 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7171 (set (match_operand:DWIH 1 "register_operand" "=r")
7174 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7175 (zero_extend:<DWI> (match_dup 3)))
7176 (match_operand:QI 4 "const_int_operand" "n"))))]
7177 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7178 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7179 "mulx\t{%3, %0, %1|%1, %0, %3}"
7180 [(set_attr "type" "imulx")
7181 (set_attr "prefix" "vex")
7182 (set_attr "mode" "<MODE>")])
7184 (define_insn "*umul<mode><dwi>3_1"
7185 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7188 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7190 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7191 (clobber (reg:CC FLAGS_REG))]
7192 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7195 mul{<imodesuffix>}\t%2"
7196 [(set_attr "isa" "bmi2,*")
7197 (set_attr "type" "imulx,imul")
7198 (set_attr "length_immediate" "*,0")
7199 (set (attr "athlon_decode")
7200 (cond [(eq_attr "alternative" "1")
7201 (if_then_else (eq_attr "cpu" "athlon")
7202 (const_string "vector")
7203 (const_string "double"))]
7204 (const_string "*")))
7205 (set_attr "amdfam10_decode" "*,double")
7206 (set_attr "bdver1_decode" "*,direct")
7207 (set_attr "prefix" "vex,orig")
7208 (set_attr "mode" "<MODE>")])
7210 ;; Convert mul to the mulx pattern to avoid flags dependency.
7212 [(set (match_operand:<DWI> 0 "register_operand")
7215 (match_operand:DWIH 1 "register_operand"))
7217 (match_operand:DWIH 2 "nonimmediate_operand"))))
7218 (clobber (reg:CC FLAGS_REG))]
7219 "TARGET_BMI2 && reload_completed
7220 && REGNO (operands[1]) == DX_REG"
7221 [(parallel [(set (match_dup 3)
7222 (mult:DWIH (match_dup 1) (match_dup 2)))
7226 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7227 (zero_extend:<DWI> (match_dup 2)))
7230 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7232 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7235 (define_insn "*mul<mode><dwi>3_1"
7236 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7239 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7241 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7242 (clobber (reg:CC FLAGS_REG))]
7243 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7244 "imul{<imodesuffix>}\t%2"
7245 [(set_attr "type" "imul")
7246 (set_attr "length_immediate" "0")
7247 (set (attr "athlon_decode")
7248 (if_then_else (eq_attr "cpu" "athlon")
7249 (const_string "vector")
7250 (const_string "double")))
7251 (set_attr "amdfam10_decode" "double")
7252 (set_attr "bdver1_decode" "direct")
7253 (set_attr "mode" "<MODE>")])
7255 (define_insn "*<u>mulqihi3_1"
7256 [(set (match_operand:HI 0 "register_operand" "=a")
7259 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7261 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7262 (clobber (reg:CC FLAGS_REG))]
7264 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7265 "<sgnprefix>mul{b}\t%2"
7266 [(set_attr "type" "imul")
7267 (set_attr "length_immediate" "0")
7268 (set (attr "athlon_decode")
7269 (if_then_else (eq_attr "cpu" "athlon")
7270 (const_string "vector")
7271 (const_string "direct")))
7272 (set_attr "amdfam10_decode" "direct")
7273 (set_attr "bdver1_decode" "direct")
7274 (set_attr "mode" "QI")])
7276 (define_expand "<s>mul<mode>3_highpart"
7277 [(parallel [(set (match_operand:SWI48 0 "register_operand")
7282 (match_operand:SWI48 1 "nonimmediate_operand"))
7284 (match_operand:SWI48 2 "register_operand")))
7286 (clobber (match_scratch:SWI48 3))
7287 (clobber (reg:CC FLAGS_REG))])]
7289 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7291 (define_insn "*<s>muldi3_highpart_1"
7292 [(set (match_operand:DI 0 "register_operand" "=d")
7297 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7299 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7301 (clobber (match_scratch:DI 3 "=1"))
7302 (clobber (reg:CC FLAGS_REG))]
7304 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7305 "<sgnprefix>mul{q}\t%2"
7306 [(set_attr "type" "imul")
7307 (set_attr "length_immediate" "0")
7308 (set (attr "athlon_decode")
7309 (if_then_else (eq_attr "cpu" "athlon")
7310 (const_string "vector")
7311 (const_string "double")))
7312 (set_attr "amdfam10_decode" "double")
7313 (set_attr "bdver1_decode" "direct")
7314 (set_attr "mode" "DI")])
7316 (define_insn "*<s>mulsi3_highpart_1"
7317 [(set (match_operand:SI 0 "register_operand" "=d")
7322 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7324 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7326 (clobber (match_scratch:SI 3 "=1"))
7327 (clobber (reg:CC FLAGS_REG))]
7328 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7329 "<sgnprefix>mul{l}\t%2"
7330 [(set_attr "type" "imul")
7331 (set_attr "length_immediate" "0")
7332 (set (attr "athlon_decode")
7333 (if_then_else (eq_attr "cpu" "athlon")
7334 (const_string "vector")
7335 (const_string "double")))
7336 (set_attr "amdfam10_decode" "double")
7337 (set_attr "bdver1_decode" "direct")
7338 (set_attr "mode" "SI")])
7340 (define_insn "*<s>mulsi3_highpart_zext"
7341 [(set (match_operand:DI 0 "register_operand" "=d")
7342 (zero_extend:DI (truncate:SI
7344 (mult:DI (any_extend:DI
7345 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7347 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7349 (clobber (match_scratch:SI 3 "=1"))
7350 (clobber (reg:CC FLAGS_REG))]
7352 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7353 "<sgnprefix>mul{l}\t%2"
7354 [(set_attr "type" "imul")
7355 (set_attr "length_immediate" "0")
7356 (set (attr "athlon_decode")
7357 (if_then_else (eq_attr "cpu" "athlon")
7358 (const_string "vector")
7359 (const_string "double")))
7360 (set_attr "amdfam10_decode" "double")
7361 (set_attr "bdver1_decode" "direct")
7362 (set_attr "mode" "SI")])
7364 ;; The patterns that match these are at the end of this file.
7366 (define_expand "mulxf3"
7367 [(set (match_operand:XF 0 "register_operand")
7368 (mult:XF (match_operand:XF 1 "register_operand")
7369 (match_operand:XF 2 "register_operand")))]
7372 (define_expand "mul<mode>3"
7373 [(set (match_operand:MODEF 0 "register_operand")
7374 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7375 (match_operand:MODEF 2 "nonimmediate_operand")))]
7376 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7377 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7379 ;; Divide instructions
7381 ;; The patterns that match these are at the end of this file.
7383 (define_expand "divxf3"
7384 [(set (match_operand:XF 0 "register_operand")
7385 (div:XF (match_operand:XF 1 "register_operand")
7386 (match_operand:XF 2 "register_operand")))]
7389 (define_expand "divdf3"
7390 [(set (match_operand:DF 0 "register_operand")
7391 (div:DF (match_operand:DF 1 "register_operand")
7392 (match_operand:DF 2 "nonimmediate_operand")))]
7393 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7394 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7396 (define_expand "divsf3"
7397 [(set (match_operand:SF 0 "register_operand")
7398 (div:SF (match_operand:SF 1 "register_operand")
7399 (match_operand:SF 2 "nonimmediate_operand")))]
7400 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7405 && optimize_insn_for_speed_p ()
7406 && flag_finite_math_only && !flag_trapping_math
7407 && flag_unsafe_math_optimizations)
7409 ix86_emit_swdivsf (operands[0], operands[1],
7410 operands[2], SFmode);
7415 ;; Divmod instructions.
7417 (define_expand "divmod<mode>4"
7418 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7420 (match_operand:SWIM248 1 "register_operand")
7421 (match_operand:SWIM248 2 "nonimmediate_operand")))
7422 (set (match_operand:SWIM248 3 "register_operand")
7423 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7424 (clobber (reg:CC FLAGS_REG))])])
7426 ;; Split with 8bit unsigned divide:
7427 ;; if (dividend an divisor are in [0-255])
7428 ;; use 8bit unsigned integer divide
7430 ;; use original integer divide
7432 [(set (match_operand:SWI48 0 "register_operand")
7433 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7434 (match_operand:SWI48 3 "nonimmediate_operand")))
7435 (set (match_operand:SWI48 1 "register_operand")
7436 (mod:SWI48 (match_dup 2) (match_dup 3)))
7437 (clobber (reg:CC FLAGS_REG))]
7438 "TARGET_USE_8BIT_IDIV
7439 && TARGET_QIMODE_MATH
7440 && can_create_pseudo_p ()
7441 && !optimize_insn_for_size_p ()"
7443 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7445 (define_insn_and_split "divmod<mode>4_1"
7446 [(set (match_operand:SWI48 0 "register_operand" "=a")
7447 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7448 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7449 (set (match_operand:SWI48 1 "register_operand" "=&d")
7450 (mod:SWI48 (match_dup 2) (match_dup 3)))
7451 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7452 (clobber (reg:CC FLAGS_REG))]
7456 [(parallel [(set (match_dup 1)
7457 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7458 (clobber (reg:CC FLAGS_REG))])
7459 (parallel [(set (match_dup 0)
7460 (div:SWI48 (match_dup 2) (match_dup 3)))
7462 (mod:SWI48 (match_dup 2) (match_dup 3)))
7464 (clobber (reg:CC FLAGS_REG))])]
7466 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7468 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7469 operands[4] = operands[2];
7472 /* Avoid use of cltd in favor of a mov+shift. */
7473 emit_move_insn (operands[1], operands[2]);
7474 operands[4] = operands[1];
7477 [(set_attr "type" "multi")
7478 (set_attr "mode" "<MODE>")])
7480 (define_insn_and_split "*divmod<mode>4"
7481 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7482 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7483 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7484 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7485 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7486 (clobber (reg:CC FLAGS_REG))]
7490 [(parallel [(set (match_dup 1)
7491 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7492 (clobber (reg:CC FLAGS_REG))])
7493 (parallel [(set (match_dup 0)
7494 (div:SWIM248 (match_dup 2) (match_dup 3)))
7496 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7498 (clobber (reg:CC FLAGS_REG))])]
7500 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7502 if (<MODE>mode != HImode
7503 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7504 operands[4] = operands[2];
7507 /* Avoid use of cltd in favor of a mov+shift. */
7508 emit_move_insn (operands[1], operands[2]);
7509 operands[4] = operands[1];
7512 [(set_attr "type" "multi")
7513 (set_attr "mode" "<MODE>")])
7515 (define_insn "*divmod<mode>4_noext"
7516 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7517 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7518 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7519 (set (match_operand:SWIM248 1 "register_operand" "=d")
7520 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7521 (use (match_operand:SWIM248 4 "register_operand" "1"))
7522 (clobber (reg:CC FLAGS_REG))]
7524 "idiv{<imodesuffix>}\t%3"
7525 [(set_attr "type" "idiv")
7526 (set_attr "mode" "<MODE>")])
7528 (define_expand "divmodqi4"
7529 [(parallel [(set (match_operand:QI 0 "register_operand")
7531 (match_operand:QI 1 "register_operand")
7532 (match_operand:QI 2 "nonimmediate_operand")))
7533 (set (match_operand:QI 3 "register_operand")
7534 (mod:QI (match_dup 1) (match_dup 2)))
7535 (clobber (reg:CC FLAGS_REG))])]
7536 "TARGET_QIMODE_MATH"
7541 tmp0 = gen_reg_rtx (HImode);
7542 tmp1 = gen_reg_rtx (HImode);
7544 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7546 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7547 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7549 /* Extract remainder from AH. */
7550 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7551 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7553 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7554 set_unique_reg_note (insn, REG_EQUAL, mod);
7556 /* Extract quotient from AL. */
7557 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7559 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7560 set_unique_reg_note (insn, REG_EQUAL, div);
7565 ;; Divide AX by r/m8, with result stored in
7568 ;; Change div/mod to HImode and extend the second argument to HImode
7569 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7570 ;; combine may fail.
7571 (define_insn "divmodhiqi3"
7572 [(set (match_operand:HI 0 "register_operand" "=a")
7577 (mod:HI (match_operand:HI 1 "register_operand" "0")
7579 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7583 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7584 (clobber (reg:CC FLAGS_REG))]
7585 "TARGET_QIMODE_MATH"
7587 [(set_attr "type" "idiv")
7588 (set_attr "mode" "QI")])
7590 (define_expand "udivmod<mode>4"
7591 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7593 (match_operand:SWIM248 1 "register_operand")
7594 (match_operand:SWIM248 2 "nonimmediate_operand")))
7595 (set (match_operand:SWIM248 3 "register_operand")
7596 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7597 (clobber (reg:CC FLAGS_REG))])])
7599 ;; Split with 8bit unsigned divide:
7600 ;; if (dividend an divisor are in [0-255])
7601 ;; use 8bit unsigned integer divide
7603 ;; use original integer divide
7605 [(set (match_operand:SWI48 0 "register_operand")
7606 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7607 (match_operand:SWI48 3 "nonimmediate_operand")))
7608 (set (match_operand:SWI48 1 "register_operand")
7609 (umod:SWI48 (match_dup 2) (match_dup 3)))
7610 (clobber (reg:CC FLAGS_REG))]
7611 "TARGET_USE_8BIT_IDIV
7612 && TARGET_QIMODE_MATH
7613 && can_create_pseudo_p ()
7614 && !optimize_insn_for_size_p ()"
7616 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7618 (define_insn_and_split "udivmod<mode>4_1"
7619 [(set (match_operand:SWI48 0 "register_operand" "=a")
7620 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7621 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7622 (set (match_operand:SWI48 1 "register_operand" "=&d")
7623 (umod:SWI48 (match_dup 2) (match_dup 3)))
7624 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7625 (clobber (reg:CC FLAGS_REG))]
7629 [(set (match_dup 1) (const_int 0))
7630 (parallel [(set (match_dup 0)
7631 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7633 (umod:SWI48 (match_dup 2) (match_dup 3)))
7635 (clobber (reg:CC FLAGS_REG))])]
7637 [(set_attr "type" "multi")
7638 (set_attr "mode" "<MODE>")])
7640 (define_insn_and_split "*udivmod<mode>4"
7641 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7642 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7643 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7644 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7645 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7646 (clobber (reg:CC FLAGS_REG))]
7650 [(set (match_dup 1) (const_int 0))
7651 (parallel [(set (match_dup 0)
7652 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7654 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7656 (clobber (reg:CC FLAGS_REG))])]
7658 [(set_attr "type" "multi")
7659 (set_attr "mode" "<MODE>")])
7661 ;; Optimize division or modulo by constant power of 2, if the constant
7662 ;; materializes only after expansion.
7663 (define_insn_and_split "*udivmod<mode>4_pow2"
7664 [(set (match_operand:SWI48 0 "register_operand" "=r")
7665 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7666 (match_operand:SWI48 3 "const_int_operand" "n")))
7667 (set (match_operand:SWI48 1 "register_operand" "=r")
7668 (umod:SWI48 (match_dup 2) (match_dup 3)))
7669 (clobber (reg:CC FLAGS_REG))]
7670 "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
7671 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
7674 [(set (match_dup 1) (match_dup 2))
7675 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7676 (clobber (reg:CC FLAGS_REG))])
7677 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7678 (clobber (reg:CC FLAGS_REG))])]
7680 int v = exact_log2 (UINTVAL (operands[3]));
7681 operands[4] = GEN_INT (v);
7682 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7684 [(set_attr "type" "multi")
7685 (set_attr "mode" "<MODE>")])
7687 (define_insn "*udivmod<mode>4_noext"
7688 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7689 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7690 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7691 (set (match_operand:SWIM248 1 "register_operand" "=d")
7692 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7693 (use (match_operand:SWIM248 4 "register_operand" "1"))
7694 (clobber (reg:CC FLAGS_REG))]
7696 "div{<imodesuffix>}\t%3"
7697 [(set_attr "type" "idiv")
7698 (set_attr "mode" "<MODE>")])
7700 (define_expand "udivmodqi4"
7701 [(parallel [(set (match_operand:QI 0 "register_operand")
7703 (match_operand:QI 1 "register_operand")
7704 (match_operand:QI 2 "nonimmediate_operand")))
7705 (set (match_operand:QI 3 "register_operand")
7706 (umod:QI (match_dup 1) (match_dup 2)))
7707 (clobber (reg:CC FLAGS_REG))])]
7708 "TARGET_QIMODE_MATH"
7713 tmp0 = gen_reg_rtx (HImode);
7714 tmp1 = gen_reg_rtx (HImode);
7716 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
7717 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7718 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7720 /* Extract remainder from AH. */
7721 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7722 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
7723 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7725 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7726 set_unique_reg_note (insn, REG_EQUAL, mod);
7728 /* Extract quotient from AL. */
7729 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7731 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7732 set_unique_reg_note (insn, REG_EQUAL, div);
7737 (define_insn "udivmodhiqi3"
7738 [(set (match_operand:HI 0 "register_operand" "=a")
7743 (mod:HI (match_operand:HI 1 "register_operand" "0")
7745 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7749 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7750 (clobber (reg:CC FLAGS_REG))]
7751 "TARGET_QIMODE_MATH"
7753 [(set_attr "type" "idiv")
7754 (set_attr "mode" "QI")])
7756 ;; We cannot use div/idiv for double division, because it causes
7757 ;; "division by zero" on the overflow and that's not what we expect
7758 ;; from truncate. Because true (non truncating) double division is
7759 ;; never generated, we can't create this insn anyway.
7762 ; [(set (match_operand:SI 0 "register_operand" "=a")
7764 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7766 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7767 ; (set (match_operand:SI 3 "register_operand" "=d")
7769 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7770 ; (clobber (reg:CC FLAGS_REG))]
7772 ; "div{l}\t{%2, %0|%0, %2}"
7773 ; [(set_attr "type" "idiv")])
7775 ;;- Logical AND instructions
7777 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7778 ;; Note that this excludes ah.
7780 (define_expand "testsi_ccno_1"
7781 [(set (reg:CCNO FLAGS_REG)
7783 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7784 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7787 (define_expand "testqi_ccz_1"
7788 [(set (reg:CCZ FLAGS_REG)
7789 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7790 (match_operand:QI 1 "nonmemory_operand"))
7793 (define_expand "testdi_ccno_1"
7794 [(set (reg:CCNO FLAGS_REG)
7796 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7797 (match_operand:DI 1 "x86_64_szext_general_operand"))
7799 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7801 (define_insn "*testdi_1"
7802 [(set (reg FLAGS_REG)
7805 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7806 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7808 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7809 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7811 test{l}\t{%k1, %k0|%k0, %k1}
7812 test{l}\t{%k1, %k0|%k0, %k1}
7813 test{q}\t{%1, %0|%0, %1}
7814 test{q}\t{%1, %0|%0, %1}
7815 test{q}\t{%1, %0|%0, %1}"
7816 [(set_attr "type" "test")
7817 (set_attr "modrm" "0,1,0,1,1")
7818 (set_attr "mode" "SI,SI,DI,DI,DI")])
7820 (define_insn "*testqi_1_maybe_si"
7821 [(set (reg FLAGS_REG)
7824 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7825 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7827 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7828 && ix86_match_ccmode (insn,
7829 CONST_INT_P (operands[1])
7830 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7832 if (which_alternative == 3)
7834 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7835 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7836 return "test{l}\t{%1, %k0|%k0, %1}";
7838 return "test{b}\t{%1, %0|%0, %1}";
7840 [(set_attr "type" "test")
7841 (set_attr "modrm" "0,1,1,1")
7842 (set_attr "mode" "QI,QI,QI,SI")
7843 (set_attr "pent_pair" "uv,np,uv,np")])
7845 (define_insn "*test<mode>_1"
7846 [(set (reg FLAGS_REG)
7849 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7850 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7852 "ix86_match_ccmode (insn, CCNOmode)
7853 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7854 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7855 [(set_attr "type" "test")
7856 (set_attr "modrm" "0,1,1")
7857 (set_attr "mode" "<MODE>")
7858 (set_attr "pent_pair" "uv,np,uv")])
7860 (define_expand "testqi_ext_ccno_0"
7861 [(set (reg:CCNO FLAGS_REG)
7865 (match_operand 0 "ext_register_operand")
7868 (match_operand 1 "const_int_operand"))
7871 (define_insn "*testqi_ext_0"
7872 [(set (reg FLAGS_REG)
7876 (match_operand 0 "ext_register_operand" "Q")
7879 (match_operand 1 "const_int_operand" "n"))
7881 "ix86_match_ccmode (insn, CCNOmode)"
7882 "test{b}\t{%1, %h0|%h0, %1}"
7883 [(set_attr "type" "test")
7884 (set_attr "mode" "QI")
7885 (set_attr "length_immediate" "1")
7886 (set_attr "modrm" "1")
7887 (set_attr "pent_pair" "np")])
7889 (define_insn "*testqi_ext_1"
7890 [(set (reg FLAGS_REG)
7894 (match_operand 0 "ext_register_operand" "Q,Q")
7898 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7900 "ix86_match_ccmode (insn, CCNOmode)"
7901 "test{b}\t{%1, %h0|%h0, %1}"
7902 [(set_attr "isa" "*,nox64")
7903 (set_attr "type" "test")
7904 (set_attr "mode" "QI")])
7906 (define_insn "*testqi_ext_2"
7907 [(set (reg FLAGS_REG)
7911 (match_operand 0 "ext_register_operand" "Q")
7915 (match_operand 1 "ext_register_operand" "Q")
7919 "ix86_match_ccmode (insn, CCNOmode)"
7920 "test{b}\t{%h1, %h0|%h0, %h1}"
7921 [(set_attr "type" "test")
7922 (set_attr "mode" "QI")])
7924 ;; Combine likes to form bit extractions for some tests. Humor it.
7925 (define_insn "*testqi_ext_3"
7926 [(set (reg FLAGS_REG)
7927 (compare (zero_extract:SWI248
7928 (match_operand 0 "nonimmediate_operand" "rm")
7929 (match_operand 1 "const_int_operand" "n")
7930 (match_operand 2 "const_int_operand" "n"))
7932 "ix86_match_ccmode (insn, CCNOmode)
7933 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7934 || GET_MODE (operands[0]) == SImode
7935 || GET_MODE (operands[0]) == HImode
7936 || GET_MODE (operands[0]) == QImode)
7937 /* Ensure that resulting mask is zero or sign extended operand. */
7938 && INTVAL (operands[2]) >= 0
7939 && ((INTVAL (operands[1]) > 0
7940 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7941 || (<MODE>mode == DImode
7942 && INTVAL (operands[1]) > 32
7943 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7947 [(set (match_operand 0 "flags_reg_operand")
7948 (match_operator 1 "compare_operator"
7950 (match_operand 2 "nonimmediate_operand")
7951 (match_operand 3 "const_int_operand")
7952 (match_operand 4 "const_int_operand"))
7954 "ix86_match_ccmode (insn, CCNOmode)"
7955 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7957 rtx val = operands[2];
7958 HOST_WIDE_INT len = INTVAL (operands[3]);
7959 HOST_WIDE_INT pos = INTVAL (operands[4]);
7961 machine_mode mode, submode;
7963 mode = GET_MODE (val);
7966 /* ??? Combine likes to put non-volatile mem extractions in QImode
7967 no matter the size of the test. So find a mode that works. */
7968 if (! MEM_VOLATILE_P (val))
7970 mode = smallest_mode_for_size (pos + len, MODE_INT);
7971 val = adjust_address (val, mode, 0);
7974 else if (SUBREG_P (val)
7975 && (submode = GET_MODE (SUBREG_REG (val)),
7976 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7977 && pos + len <= GET_MODE_BITSIZE (submode)
7978 && GET_MODE_CLASS (submode) == MODE_INT)
7980 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7982 val = SUBREG_REG (val);
7984 else if (mode == HImode && pos + len <= 8)
7986 /* Small HImode tests can be converted to QImode. */
7988 val = gen_lowpart (QImode, val);
7991 if (len == HOST_BITS_PER_WIDE_INT)
7994 mask = (HOST_WIDE_INT_1 << len) - 1;
7997 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8000 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8001 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8002 ;; this is relatively important trick.
8003 ;; Do the conversion only post-reload to avoid limiting of the register class
8006 [(set (match_operand 0 "flags_reg_operand")
8007 (match_operator 1 "compare_operator"
8008 [(and (match_operand 2 "QIreg_operand")
8009 (match_operand 3 "const_int_operand"))
8012 && GET_MODE (operands[2]) != QImode
8013 && ((ix86_match_ccmode (insn, CCZmode)
8014 && !(INTVAL (operands[3]) & ~(255 << 8)))
8015 || (ix86_match_ccmode (insn, CCNOmode)
8016 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8019 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8023 operands[2] = gen_lowpart (SImode, operands[2]);
8024 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
8028 [(set (match_operand 0 "flags_reg_operand")
8029 (match_operator 1 "compare_operator"
8030 [(and (match_operand 2 "nonimmediate_operand")
8031 (match_operand 3 "const_int_operand"))
8034 && GET_MODE (operands[2]) != QImode
8035 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8036 && ((ix86_match_ccmode (insn, CCZmode)
8037 && !(INTVAL (operands[3]) & ~255))
8038 || (ix86_match_ccmode (insn, CCNOmode)
8039 && !(INTVAL (operands[3]) & ~127)))"
8041 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8044 operands[2] = gen_lowpart (QImode, operands[2]);
8045 operands[3] = gen_lowpart (QImode, operands[3]);
8049 [(set (match_operand:SWI1248x 0 "mask_reg_operand")
8050 (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
8051 (match_operand:SWI1248x 2 "mask_reg_operand")))
8052 (clobber (reg:CC FLAGS_REG))]
8053 "TARGET_AVX512F && reload_completed"
8055 (any_logic:SWI1248x (match_dup 1)
8058 (define_mode_iterator SWI1248_AVX512BW
8059 [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
8061 (define_insn "*k<logic><mode>"
8062 [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
8063 (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
8064 (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
8067 if (!TARGET_AVX512DQ && <MODE>mode == QImode)
8068 return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
8070 return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
8072 [(set_attr "mode" "<MODE>")
8073 (set_attr "type" "msklog")
8074 (set_attr "prefix" "vex")])
8076 ;; %%% This used to optimize known byte-wide and operations to memory,
8077 ;; and sometimes to QImode registers. If this is considered useful,
8078 ;; it should be done with splitters.
8080 (define_expand "and<mode>3"
8081 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8082 (and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8083 (match_operand:SWIM1248x 2 "<general_szext_operand>")))]
8086 machine_mode mode = <MODE>mode;
8087 rtx (*insn) (rtx, rtx);
8089 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
8091 HOST_WIDE_INT ival = INTVAL (operands[2]);
8093 if (ival == (HOST_WIDE_INT) 0xffffffff)
8095 else if (ival == 0xffff)
8097 else if (ival == 0xff)
8101 if (mode == <MODE>mode)
8103 ix86_expand_binary_operator (AND, <MODE>mode, operands);
8107 if (<MODE>mode == DImode)
8108 insn = (mode == SImode)
8109 ? gen_zero_extendsidi2
8111 ? gen_zero_extendhidi2
8112 : gen_zero_extendqidi2;
8113 else if (<MODE>mode == SImode)
8114 insn = (mode == HImode)
8115 ? gen_zero_extendhisi2
8116 : gen_zero_extendqisi2;
8117 else if (<MODE>mode == HImode)
8118 insn = gen_zero_extendqihi2;
8122 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8126 (define_insn "*anddi_1"
8127 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
8129 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
8130 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
8131 (clobber (reg:CC FLAGS_REG))]
8132 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8134 switch (get_attr_type (insn))
8140 return "kandq\t{%2, %1, %0|%0, %1, %2}";
8143 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8144 if (get_attr_mode (insn) == MODE_SI)
8145 return "and{l}\t{%k2, %k0|%k0, %k2}";
8147 return "and{q}\t{%2, %0|%0, %2}";
8150 [(set_attr "type" "alu,alu,alu,imovx,msklog")
8151 (set_attr "length_immediate" "*,*,*,0,0")
8152 (set (attr "prefix_rex")
8154 (and (eq_attr "type" "imovx")
8155 (and (match_test "INTVAL (operands[2]) == 0xff")
8156 (match_operand 1 "ext_QIreg_operand")))
8158 (const_string "*")))
8159 (set_attr "mode" "SI,DI,DI,SI,DI")])
8161 (define_insn_and_split "*anddi3_doubleword"
8162 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8164 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8165 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8166 (clobber (reg:CC FLAGS_REG))]
8167 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8168 && ix86_binary_operator_ok (AND, DImode, operands)"
8170 "&& reload_completed"
8173 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8174 if (operands[2] == const0_rtx)
8176 operands[1] = const0_rtx;
8177 ix86_expand_move (SImode, &operands[0]);
8179 else if (operands[2] != constm1_rtx)
8180 ix86_expand_binary_operator (AND, SImode, &operands[0]);
8181 else if (operands[5] == constm1_rtx)
8182 emit_note (NOTE_INSN_DELETED);
8183 if (operands[5] == const0_rtx)
8185 operands[4] = const0_rtx;
8186 ix86_expand_move (SImode, &operands[3]);
8188 else if (operands[5] != constm1_rtx)
8189 ix86_expand_binary_operator (AND, SImode, &operands[3]);
8193 (define_insn "*andsi_1"
8194 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
8195 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
8196 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
8197 (clobber (reg:CC FLAGS_REG))]
8198 "ix86_binary_operator_ok (AND, SImode, operands)"
8200 switch (get_attr_type (insn))
8206 return "kandd\t{%2, %1, %0|%0, %1, %2}";
8209 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8210 return "and{l}\t{%2, %0|%0, %2}";
8213 [(set_attr "type" "alu,alu,imovx,msklog")
8214 (set (attr "prefix_rex")
8216 (and (eq_attr "type" "imovx")
8217 (and (match_test "INTVAL (operands[2]) == 0xff")
8218 (match_operand 1 "ext_QIreg_operand")))
8220 (const_string "*")))
8221 (set_attr "length_immediate" "*,*,0,0")
8222 (set_attr "mode" "SI")])
8224 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8225 (define_insn "*andsi_1_zext"
8226 [(set (match_operand:DI 0 "register_operand" "=r")
8228 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8229 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8230 (clobber (reg:CC FLAGS_REG))]
8231 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8232 "and{l}\t{%2, %k0|%k0, %2}"
8233 [(set_attr "type" "alu")
8234 (set_attr "mode" "SI")])
8236 (define_insn "*andhi_1"
8237 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
8238 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
8239 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
8240 (clobber (reg:CC FLAGS_REG))]
8241 "ix86_binary_operator_ok (AND, HImode, operands)"
8243 switch (get_attr_type (insn))
8249 return "kandw\t{%2, %1, %0|%0, %1, %2}";
8252 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8253 return "and{w}\t{%2, %0|%0, %2}";
8256 [(set_attr "type" "alu,alu,imovx,msklog")
8257 (set_attr "length_immediate" "*,*,0,*")
8258 (set (attr "prefix_rex")
8260 (and (eq_attr "type" "imovx")
8261 (match_operand 1 "ext_QIreg_operand"))
8263 (const_string "*")))
8264 (set_attr "mode" "HI,HI,SI,HI")])
8266 (define_insn "*andqi_1"
8267 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
8268 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8269 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
8270 (clobber (reg:CC FLAGS_REG))]
8271 "ix86_binary_operator_ok (AND, QImode, operands)"
8273 switch (which_alternative)
8277 return "and{b}\t{%2, %0|%0, %2}";
8279 return "and{l}\t{%k2, %k0|%k0, %k2}";
8281 return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
8282 : "kandw\t{%2, %1, %0|%0, %1, %2}";
8287 [(set_attr "type" "alu,alu,alu,msklog")
8288 (set_attr "mode" "QI,QI,SI,HI")
8289 ;; Potential partial reg stall on alternative 2.
8290 (set (attr "preferred_for_speed")
8291 (cond [(eq_attr "alternative" "2")
8292 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8293 (symbol_ref "true")))])
8295 (define_insn "*andqi_1_slp"
8296 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8297 (and:QI (match_dup 0)
8298 (match_operand:QI 1 "general_operand" "qn,qmn")))
8299 (clobber (reg:CC FLAGS_REG))]
8300 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8301 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8302 "and{b}\t{%1, %0|%0, %1}"
8303 [(set_attr "type" "alu1")
8304 (set_attr "mode" "QI")])
8306 (define_insn "kandn<mode>"
8307 [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
8310 (match_operand:SWI12 1 "register_operand" "r,0,k"))
8311 (match_operand:SWI12 2 "register_operand" "r,r,k")))
8312 (clobber (reg:CC FLAGS_REG))]
8315 switch (which_alternative)
8318 return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
8322 if (TARGET_AVX512DQ && <MODE>mode == QImode)
8323 return "kandnb\t{%2, %1, %0|%0, %1, %2}";
8325 return "kandnw\t{%2, %1, %0|%0, %1, %2}";
8330 [(set_attr "isa" "bmi,*,avx512f")
8331 (set_attr "type" "bitmanip,*,msklog")
8332 (set_attr "prefix" "*,*,vex")
8333 (set_attr "btver2_decode" "direct,*,*")
8334 (set_attr "mode" "<MODE>")])
8337 [(set (match_operand:SWI12 0 "general_reg_operand")
8341 (match_operand:SWI12 1 "general_reg_operand")))
8342 (clobber (reg:CC FLAGS_REG))]
8343 "TARGET_AVX512F && !TARGET_BMI && reload_completed"
8345 (not:SWI12 (match_dup 0)))
8346 (parallel [(set (match_dup 0)
8347 (and:SWI12 (match_dup 0)
8349 (clobber (reg:CC FLAGS_REG))])])
8351 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8353 [(set (match_operand:DI 0 "register_operand")
8354 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8355 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8356 (clobber (reg:CC FLAGS_REG))]
8358 [(parallel [(set (match_dup 0)
8359 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8360 (clobber (reg:CC FLAGS_REG))])]
8361 "operands[2] = gen_lowpart (SImode, operands[2]);")
8364 [(set (match_operand:SWI248 0 "register_operand")
8365 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8366 (match_operand:SWI248 2 "const_int_operand")))
8367 (clobber (reg:CC FLAGS_REG))]
8369 && (!REG_P (operands[1])
8370 || REGNO (operands[0]) != REGNO (operands[1]))"
8373 HOST_WIDE_INT ival = INTVAL (operands[2]);
8375 rtx (*insn) (rtx, rtx);
8377 if (ival == (HOST_WIDE_INT) 0xffffffff)
8379 else if (ival == 0xffff)
8383 gcc_assert (ival == 0xff);
8387 if (<MODE>mode == DImode)
8388 insn = (mode == SImode)
8389 ? gen_zero_extendsidi2
8391 ? gen_zero_extendhidi2
8392 : gen_zero_extendqidi2;
8395 if (<MODE>mode != SImode)
8396 /* Zero extend to SImode to avoid partial register stalls. */
8397 operands[0] = gen_lowpart (SImode, operands[0]);
8399 insn = (mode == HImode)
8400 ? gen_zero_extendhisi2
8401 : gen_zero_extendqisi2;
8403 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8408 [(set (match_operand:SWI48 0 "register_operand")
8409 (and:SWI48 (match_dup 0)
8410 (const_int -65536)))
8411 (clobber (reg:CC FLAGS_REG))]
8412 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8413 || optimize_function_for_size_p (cfun)"
8414 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8415 "operands[1] = gen_lowpart (HImode, operands[0]);")
8418 [(set (match_operand:SWI248 0 "any_QIreg_operand")
8419 (and:SWI248 (match_dup 0)
8421 (clobber (reg:CC FLAGS_REG))]
8422 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8423 && reload_completed"
8424 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8425 "operands[1] = gen_lowpart (QImode, operands[0]);")
8428 [(set (match_operand:SWI248 0 "QIreg_operand")
8429 (and:SWI248 (match_dup 0)
8430 (const_int -65281)))
8431 (clobber (reg:CC FLAGS_REG))]
8432 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8433 && reload_completed"
8434 [(parallel [(set (zero_extract:SI (match_dup 0)
8438 (zero_extract:SI (match_dup 0)
8441 (zero_extract:SI (match_dup 0)
8444 (clobber (reg:CC FLAGS_REG))])]
8445 "operands[0] = gen_lowpart (SImode, operands[0]);")
8447 (define_insn "*anddi_2"
8448 [(set (reg FLAGS_REG)
8451 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8452 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8454 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8455 (and:DI (match_dup 1) (match_dup 2)))]
8457 && ix86_match_ccmode
8459 /* If we are going to emit andl instead of andq, and the operands[2]
8460 constant might have the SImode sign bit set, make sure the sign
8461 flag isn't tested, because the instruction will set the sign flag
8462 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8463 conservatively assume it might have bit 31 set. */
8464 (satisfies_constraint_Z (operands[2])
8465 && (!CONST_INT_P (operands[2])
8466 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8467 ? CCZmode : CCNOmode)
8468 && ix86_binary_operator_ok (AND, DImode, operands)"
8470 and{l}\t{%k2, %k0|%k0, %k2}
8471 and{q}\t{%2, %0|%0, %2}
8472 and{q}\t{%2, %0|%0, %2}"
8473 [(set_attr "type" "alu")
8474 (set_attr "mode" "SI,DI,DI")])
8476 (define_insn "*andqi_2_maybe_si"
8477 [(set (reg FLAGS_REG)
8479 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8480 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8482 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8483 (and:QI (match_dup 1) (match_dup 2)))]
8484 "ix86_binary_operator_ok (AND, QImode, operands)
8485 && ix86_match_ccmode (insn,
8486 CONST_INT_P (operands[2])
8487 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8489 if (which_alternative == 2)
8491 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8492 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8493 return "and{l}\t{%2, %k0|%k0, %2}";
8495 return "and{b}\t{%2, %0|%0, %2}";
8497 [(set_attr "type" "alu")
8498 (set_attr "mode" "QI,QI,SI")])
8500 (define_insn "*and<mode>_2"
8501 [(set (reg FLAGS_REG)
8502 (compare (and:SWI124
8503 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8504 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8506 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8507 (and:SWI124 (match_dup 1) (match_dup 2)))]
8508 "ix86_match_ccmode (insn, CCNOmode)
8509 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8510 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8511 [(set_attr "type" "alu")
8512 (set_attr "mode" "<MODE>")])
8514 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8515 (define_insn "*andsi_2_zext"
8516 [(set (reg FLAGS_REG)
8518 (match_operand:SI 1 "nonimmediate_operand" "%0")
8519 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8521 (set (match_operand:DI 0 "register_operand" "=r")
8522 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8523 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8524 && ix86_binary_operator_ok (AND, SImode, operands)"
8525 "and{l}\t{%2, %k0|%k0, %2}"
8526 [(set_attr "type" "alu")
8527 (set_attr "mode" "SI")])
8529 (define_insn "*andqi_2_slp"
8530 [(set (reg FLAGS_REG)
8532 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8533 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8535 (set (strict_low_part (match_dup 0))
8536 (and:QI (match_dup 0) (match_dup 1)))]
8537 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8538 && ix86_match_ccmode (insn, CCNOmode)
8539 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8540 "and{b}\t{%1, %0|%0, %1}"
8541 [(set_attr "type" "alu1")
8542 (set_attr "mode" "QI")])
8544 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8545 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8546 ;; for a QImode operand, which of course failed.
8547 (define_insn "andqi_ext_0"
8548 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8553 (match_operand 1 "ext_register_operand" "0")
8556 (match_operand 2 "const_int_operand" "n")))
8557 (clobber (reg:CC FLAGS_REG))]
8559 "and{b}\t{%2, %h0|%h0, %2}"
8560 [(set_attr "type" "alu")
8561 (set_attr "length_immediate" "1")
8562 (set_attr "modrm" "1")
8563 (set_attr "mode" "QI")])
8565 ;; Generated by peephole translating test to and. This shows up
8566 ;; often in fp comparisons.
8567 (define_insn "*andqi_ext_0_cc"
8568 [(set (reg FLAGS_REG)
8572 (match_operand 1 "ext_register_operand" "0")
8575 (match_operand 2 "const_int_operand" "n"))
8577 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8586 "ix86_match_ccmode (insn, CCNOmode)"
8587 "and{b}\t{%2, %h0|%h0, %2}"
8588 [(set_attr "type" "alu")
8589 (set_attr "length_immediate" "1")
8590 (set_attr "modrm" "1")
8591 (set_attr "mode" "QI")])
8593 (define_insn "*andqi_ext_1"
8594 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8599 (match_operand 1 "ext_register_operand" "0,0")
8603 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8604 (clobber (reg:CC FLAGS_REG))]
8606 "and{b}\t{%2, %h0|%h0, %2}"
8607 [(set_attr "isa" "*,nox64")
8608 (set_attr "type" "alu")
8609 (set_attr "length_immediate" "0")
8610 (set_attr "mode" "QI")])
8612 (define_insn "*andqi_ext_2"
8613 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8618 (match_operand 1 "ext_register_operand" "%0")
8622 (match_operand 2 "ext_register_operand" "Q")
8625 (clobber (reg:CC FLAGS_REG))]
8627 "and{b}\t{%h2, %h0|%h0, %h2}"
8628 [(set_attr "type" "alu")
8629 (set_attr "length_immediate" "0")
8630 (set_attr "mode" "QI")])
8632 ;; Convert wide AND instructions with immediate operand to shorter QImode
8633 ;; equivalents when possible.
8634 ;; Don't do the splitting with memory operands, since it introduces risk
8635 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8636 ;; for size, but that can (should?) be handled by generic code instead.
8638 [(set (match_operand 0 "QIreg_operand")
8639 (and (match_operand 1 "register_operand")
8640 (match_operand 2 "const_int_operand")))
8641 (clobber (reg:CC FLAGS_REG))]
8643 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8644 && !(~INTVAL (operands[2]) & ~(255 << 8))
8645 && GET_MODE (operands[0]) != QImode"
8646 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8647 (and:SI (zero_extract:SI (match_dup 1)
8648 (const_int 8) (const_int 8))
8650 (clobber (reg:CC FLAGS_REG))])]
8652 operands[0] = gen_lowpart (SImode, operands[0]);
8653 operands[1] = gen_lowpart (SImode, operands[1]);
8654 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8657 ;; Since AND can be encoded with sign extended immediate, this is only
8658 ;; profitable when 7th bit is not set.
8660 [(set (match_operand 0 "any_QIreg_operand")
8661 (and (match_operand 1 "general_operand")
8662 (match_operand 2 "const_int_operand")))
8663 (clobber (reg:CC FLAGS_REG))]
8665 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8666 && !(~INTVAL (operands[2]) & ~255)
8667 && !(INTVAL (operands[2]) & 128)
8668 && GET_MODE (operands[0]) != QImode"
8669 [(parallel [(set (strict_low_part (match_dup 0))
8670 (and:QI (match_dup 1)
8672 (clobber (reg:CC FLAGS_REG))])]
8674 operands[0] = gen_lowpart (QImode, operands[0]);
8675 operands[1] = gen_lowpart (QImode, operands[1]);
8676 operands[2] = gen_lowpart (QImode, operands[2]);
8679 ;; Logical inclusive and exclusive OR instructions
8681 ;; %%% This used to optimize known byte-wide and operations to memory.
8682 ;; If this is considered useful, it should be done with splitters.
8684 (define_expand "<code><mode>3"
8685 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8686 (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8687 (match_operand:SWIM1248x 2 "<general_operand>")))]
8689 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8691 (define_insn "*<code><mode>_1"
8692 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8694 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8695 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8696 (clobber (reg:CC FLAGS_REG))]
8697 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8699 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8700 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8701 k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8702 [(set_attr "type" "alu,alu,msklog")
8703 (set_attr "mode" "<MODE>")])
8705 (define_insn_and_split "*<code>di3_doubleword"
8706 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8708 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8709 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8710 (clobber (reg:CC FLAGS_REG))]
8711 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8712 && ix86_binary_operator_ok (<CODE>, DImode, operands)"
8714 "&& reload_completed"
8717 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8718 if (operands[2] == constm1_rtx)
8722 operands[1] = constm1_rtx;
8723 ix86_expand_move (SImode, &operands[0]);
8726 ix86_expand_unary_operator (NOT, SImode, &operands[0]);
8728 else if (operands[2] != const0_rtx)
8729 ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
8730 else if (operands[5] == const0_rtx)
8731 emit_note (NOTE_INSN_DELETED);
8732 if (operands[5] == constm1_rtx)
8736 operands[4] = constm1_rtx;
8737 ix86_expand_move (SImode, &operands[3]);
8740 ix86_expand_unary_operator (NOT, SImode, &operands[3]);
8742 else if (operands[5] != const0_rtx)
8743 ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
8747 (define_insn_and_split "*andndi3_doubleword"
8748 [(set (match_operand:DI 0 "register_operand" "=r")
8750 (not:DI (match_operand:DI 1 "register_operand" "r"))
8751 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8752 (clobber (reg:CC FLAGS_REG))]
8753 "TARGET_BMI && !TARGET_64BIT && TARGET_STV && TARGET_SSE"
8755 "&& reload_completed"
8756 [(parallel [(set (match_dup 0)
8757 (and:SI (not:SI (match_dup 1)) (match_dup 2)))
8758 (clobber (reg:CC FLAGS_REG))])
8759 (parallel [(set (match_dup 3)
8760 (and:SI (not:SI (match_dup 4)) (match_dup 5)))
8761 (clobber (reg:CC FLAGS_REG))])]
8762 "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
8764 (define_insn "*<code>hi_1"
8765 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8767 (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8768 (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8769 (clobber (reg:CC FLAGS_REG))]
8770 "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8772 <logic>{w}\t{%2, %0|%0, %2}
8773 <logic>{w}\t{%2, %0|%0, %2}
8774 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8775 [(set_attr "type" "alu,alu,msklog")
8776 (set_attr "mode" "HI")])
8778 (define_insn "*<code>qi_1"
8779 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8780 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8781 (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8782 (clobber (reg:CC FLAGS_REG))]
8783 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8785 <logic>{b}\t{%2, %0|%0, %2}
8786 <logic>{b}\t{%2, %0|%0, %2}
8787 <logic>{l}\t{%k2, %k0|%k0, %k2}
8788 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8789 [(set_attr "type" "alu,alu,alu,msklog")
8790 (set_attr "mode" "QI,QI,SI,HI")
8791 ;; Potential partial reg stall on alternative 2.
8792 (set (attr "preferred_for_speed")
8793 (cond [(eq_attr "alternative" "2")
8794 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8795 (symbol_ref "true")))])
8797 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8798 (define_insn "*<code>si_1_zext"
8799 [(set (match_operand:DI 0 "register_operand" "=r")
8801 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8802 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8803 (clobber (reg:CC FLAGS_REG))]
8804 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8805 "<logic>{l}\t{%2, %k0|%k0, %2}"
8806 [(set_attr "type" "alu")
8807 (set_attr "mode" "SI")])
8809 (define_insn "*<code>si_1_zext_imm"
8810 [(set (match_operand:DI 0 "register_operand" "=r")
8812 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8813 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8814 (clobber (reg:CC FLAGS_REG))]
8815 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8816 "<logic>{l}\t{%2, %k0|%k0, %2}"
8817 [(set_attr "type" "alu")
8818 (set_attr "mode" "SI")])
8820 (define_insn "*<code>qi_1_slp"
8821 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8822 (any_or:QI (match_dup 0)
8823 (match_operand:QI 1 "general_operand" "qmn,qn")))
8824 (clobber (reg:CC FLAGS_REG))]
8825 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8826 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8827 "<logic>{b}\t{%1, %0|%0, %1}"
8828 [(set_attr "type" "alu1")
8829 (set_attr "mode" "QI")])
8831 (define_insn "*<code><mode>_2"
8832 [(set (reg FLAGS_REG)
8833 (compare (any_or:SWI
8834 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8835 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8837 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8838 (any_or:SWI (match_dup 1) (match_dup 2)))]
8839 "ix86_match_ccmode (insn, CCNOmode)
8840 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8841 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8842 [(set_attr "type" "alu")
8843 (set_attr "mode" "<MODE>")])
8845 (define_insn "kxnor<mode>"
8846 [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8849 (match_operand:SWI12 1 "register_operand" "0,k")
8850 (match_operand:SWI12 2 "register_operand" "r,k"))))
8851 (clobber (reg:CC FLAGS_REG))]
8854 if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8855 return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8856 return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8858 [(set_attr "type" "*,msklog")
8859 (set_attr "prefix" "*,vex")
8860 (set_attr "mode" "<MODE>")])
8862 (define_insn "kxnor<mode>"
8863 [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8866 (match_operand:SWI48x 1 "register_operand" "0,k")
8867 (match_operand:SWI48x 2 "register_operand" "r,k"))))
8868 (clobber (reg:CC FLAGS_REG))]
8872 kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8873 [(set_attr "type" "*,msklog")
8874 (set_attr "prefix" "*,vex")
8875 (set_attr "mode" "<MODE>")])
8878 [(set (match_operand:SWI1248x 0 "general_reg_operand")
8882 (match_operand:SWI1248x 1 "general_reg_operand"))))
8883 (clobber (reg:CC FLAGS_REG))]
8884 "TARGET_AVX512F && reload_completed"
8885 [(parallel [(set (match_dup 0)
8886 (xor:SWI1248x (match_dup 0)
8888 (clobber (reg:CC FLAGS_REG))])
8890 (not:SWI1248x (match_dup 0)))])
8892 ;;There are kortrest[bdq] but no intrinsics for them.
8893 ;;We probably don't need to implement them.
8894 (define_insn "kortestzhi"
8895 [(set (reg:CCZ FLAGS_REG)
8898 (match_operand:HI 0 "register_operand" "k")
8899 (match_operand:HI 1 "register_operand" "k"))
8901 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8902 "kortestw\t{%1, %0|%0, %1}"
8903 [(set_attr "mode" "HI")
8904 (set_attr "type" "msklog")
8905 (set_attr "prefix" "vex")])
8907 (define_insn "kortestchi"
8908 [(set (reg:CCC FLAGS_REG)
8911 (match_operand:HI 0 "register_operand" "k")
8912 (match_operand:HI 1 "register_operand" "k"))
8914 "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8915 "kortestw\t{%1, %0|%0, %1}"
8916 [(set_attr "mode" "HI")
8917 (set_attr "type" "msklog")
8918 (set_attr "prefix" "vex")])
8920 (define_insn "kunpckhi"
8921 [(set (match_operand:HI 0 "register_operand" "=k")
8924 (zero_extend:HI (match_operand:QI 1 "register_operand" "k"))
8926 (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8928 "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8929 [(set_attr "mode" "HI")
8930 (set_attr "type" "msklog")
8931 (set_attr "prefix" "vex")])
8933 (define_insn "kunpcksi"
8934 [(set (match_operand:SI 0 "register_operand" "=k")
8937 (zero_extend:SI (match_operand:HI 1 "register_operand" "k"))
8939 (zero_extend:SI (match_operand:HI 2 "register_operand" "k"))))]
8941 "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8942 [(set_attr "mode" "SI")])
8944 (define_insn "kunpckdi"
8945 [(set (match_operand:DI 0 "register_operand" "=k")
8948 (zero_extend:DI (match_operand:SI 1 "register_operand" "k"))
8950 (zero_extend:DI (match_operand:SI 2 "register_operand" "k"))))]
8952 "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8953 [(set_attr "mode" "DI")])
8955 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8956 ;; ??? Special case for immediate operand is missing - it is tricky.
8957 (define_insn "*<code>si_2_zext"
8958 [(set (reg FLAGS_REG)
8959 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8960 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8962 (set (match_operand:DI 0 "register_operand" "=r")
8963 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8964 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8965 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8966 "<logic>{l}\t{%2, %k0|%k0, %2}"
8967 [(set_attr "type" "alu")
8968 (set_attr "mode" "SI")])
8970 (define_insn "*<code>si_2_zext_imm"
8971 [(set (reg FLAGS_REG)
8973 (match_operand:SI 1 "nonimmediate_operand" "%0")
8974 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8976 (set (match_operand:DI 0 "register_operand" "=r")
8977 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8978 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8979 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8980 "<logic>{l}\t{%2, %k0|%k0, %2}"
8981 [(set_attr "type" "alu")
8982 (set_attr "mode" "SI")])
8984 (define_insn "*<code>qi_2_slp"
8985 [(set (reg FLAGS_REG)
8986 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8987 (match_operand:QI 1 "general_operand" "qmn,qn"))
8989 (set (strict_low_part (match_dup 0))
8990 (any_or:QI (match_dup 0) (match_dup 1)))]
8991 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8992 && ix86_match_ccmode (insn, CCNOmode)
8993 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8994 "<logic>{b}\t{%1, %0|%0, %1}"
8995 [(set_attr "type" "alu1")
8996 (set_attr "mode" "QI")])
8998 (define_insn "*<code><mode>_3"
8999 [(set (reg FLAGS_REG)
9000 (compare (any_or:SWI
9001 (match_operand:SWI 1 "nonimmediate_operand" "%0")
9002 (match_operand:SWI 2 "<general_operand>" "<g>"))
9004 (clobber (match_scratch:SWI 0 "=<r>"))]
9005 "ix86_match_ccmode (insn, CCNOmode)
9006 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9007 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9008 [(set_attr "type" "alu")
9009 (set_attr "mode" "<MODE>")])
9011 (define_insn "*<code>qi_ext_0"
9012 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9017 (match_operand 1 "ext_register_operand" "0")
9020 (match_operand 2 "const_int_operand" "n")))
9021 (clobber (reg:CC FLAGS_REG))]
9022 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9023 "<logic>{b}\t{%2, %h0|%h0, %2}"
9024 [(set_attr "type" "alu")
9025 (set_attr "length_immediate" "1")
9026 (set_attr "modrm" "1")
9027 (set_attr "mode" "QI")])
9029 (define_insn "*<code>qi_ext_1"
9030 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
9035 (match_operand 1 "ext_register_operand" "0,0")
9039 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
9040 (clobber (reg:CC FLAGS_REG))]
9041 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9042 "<logic>{b}\t{%2, %h0|%h0, %2}"
9043 [(set_attr "isa" "*,nox64")
9044 (set_attr "type" "alu")
9045 (set_attr "length_immediate" "0")
9046 (set_attr "mode" "QI")])
9048 (define_insn "*<code>qi_ext_2"
9049 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9053 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9056 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9059 (clobber (reg:CC FLAGS_REG))]
9060 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9061 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9062 [(set_attr "type" "alu")
9063 (set_attr "length_immediate" "0")
9064 (set_attr "mode" "QI")])
9067 [(set (match_operand 0 "QIreg_operand")
9068 (any_or (match_operand 1 "register_operand")
9069 (match_operand 2 "const_int_operand")))
9070 (clobber (reg:CC FLAGS_REG))]
9072 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9073 && !(INTVAL (operands[2]) & ~(255 << 8))
9074 && GET_MODE (operands[0]) != QImode"
9075 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9076 (any_or:SI (zero_extract:SI (match_dup 1)
9077 (const_int 8) (const_int 8))
9079 (clobber (reg:CC FLAGS_REG))])]
9081 operands[0] = gen_lowpart (SImode, operands[0]);
9082 operands[1] = gen_lowpart (SImode, operands[1]);
9083 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
9086 ;; Since OR can be encoded with sign extended immediate, this is only
9087 ;; profitable when 7th bit is set.
9089 [(set (match_operand 0 "any_QIreg_operand")
9090 (any_or (match_operand 1 "general_operand")
9091 (match_operand 2 "const_int_operand")))
9092 (clobber (reg:CC FLAGS_REG))]
9094 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9095 && !(INTVAL (operands[2]) & ~255)
9096 && (INTVAL (operands[2]) & 128)
9097 && GET_MODE (operands[0]) != QImode"
9098 [(parallel [(set (strict_low_part (match_dup 0))
9099 (any_or:QI (match_dup 1)
9101 (clobber (reg:CC FLAGS_REG))])]
9103 operands[0] = gen_lowpart (QImode, operands[0]);
9104 operands[1] = gen_lowpart (QImode, operands[1]);
9105 operands[2] = gen_lowpart (QImode, operands[2]);
9108 (define_expand "xorqi_cc_ext_1"
9110 (set (reg:CCNO FLAGS_REG)
9114 (match_operand 1 "ext_register_operand")
9117 (match_operand:QI 2 "const_int_operand"))
9119 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9129 (define_insn "*xorqi_cc_ext_1"
9130 [(set (reg FLAGS_REG)
9134 (match_operand 1 "ext_register_operand" "0,0")
9137 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
9139 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
9148 "ix86_match_ccmode (insn, CCNOmode)"
9149 "xor{b}\t{%2, %h0|%h0, %2}"
9150 [(set_attr "isa" "*,nox64")
9151 (set_attr "type" "alu")
9152 (set_attr "modrm" "1")
9153 (set_attr "mode" "QI")])
9155 ;; Negation instructions
9157 (define_expand "neg<mode>2"
9158 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
9159 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
9161 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9163 (define_insn_and_split "*neg<dwi>2_doubleword"
9164 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9165 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9166 (clobber (reg:CC FLAGS_REG))]
9167 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9171 [(set (reg:CCZ FLAGS_REG)
9172 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9173 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9176 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9179 (clobber (reg:CC FLAGS_REG))])
9182 (neg:DWIH (match_dup 2)))
9183 (clobber (reg:CC FLAGS_REG))])]
9184 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
9186 (define_insn "*neg<mode>2_1"
9187 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9188 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9189 (clobber (reg:CC FLAGS_REG))]
9190 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9191 "neg{<imodesuffix>}\t%0"
9192 [(set_attr "type" "negnot")
9193 (set_attr "mode" "<MODE>")])
9195 ;; Combine is quite creative about this pattern.
9196 (define_insn "*negsi2_1_zext"
9197 [(set (match_operand:DI 0 "register_operand" "=r")
9199 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9202 (clobber (reg:CC FLAGS_REG))]
9203 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9205 [(set_attr "type" "negnot")
9206 (set_attr "mode" "SI")])
9208 ;; The problem with neg is that it does not perform (compare x 0),
9209 ;; it really performs (compare 0 x), which leaves us with the zero
9210 ;; flag being the only useful item.
9212 (define_insn "*neg<mode>2_cmpz"
9213 [(set (reg:CCZ FLAGS_REG)
9215 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9217 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9218 (neg:SWI (match_dup 1)))]
9219 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9220 "neg{<imodesuffix>}\t%0"
9221 [(set_attr "type" "negnot")
9222 (set_attr "mode" "<MODE>")])
9224 (define_insn "*negsi2_cmpz_zext"
9225 [(set (reg:CCZ FLAGS_REG)
9229 (match_operand:DI 1 "register_operand" "0")
9233 (set (match_operand:DI 0 "register_operand" "=r")
9234 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9237 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9239 [(set_attr "type" "negnot")
9240 (set_attr "mode" "SI")])
9242 ;; Negate with jump on overflow.
9243 (define_expand "negv<mode>3"
9244 [(parallel [(set (reg:CCO FLAGS_REG)
9245 (ne:CCO (match_operand:SWI 1 "register_operand")
9247 (set (match_operand:SWI 0 "register_operand")
9248 (neg:SWI (match_dup 1)))])
9249 (set (pc) (if_then_else
9250 (eq (reg:CCO FLAGS_REG) (const_int 0))
9251 (label_ref (match_operand 2))
9256 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
9260 (define_insn "*negv<mode>3"
9261 [(set (reg:CCO FLAGS_REG)
9262 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
9263 (match_operand:SWI 2 "const_int_operand")))
9264 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9265 (neg:SWI (match_dup 1)))]
9266 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
9267 && mode_signbit_p (<MODE>mode, operands[2])"
9268 "neg{<imodesuffix>}\t%0"
9269 [(set_attr "type" "negnot")
9270 (set_attr "mode" "<MODE>")])
9272 ;; Changing of sign for FP values is doable using integer unit too.
9274 (define_expand "<code><mode>2"
9275 [(set (match_operand:X87MODEF 0 "register_operand")
9276 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
9277 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9278 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9280 (define_insn "*absneg<mode>2"
9281 [(set (match_operand:MODEF 0 "register_operand" "=Yv,Yv,f,!r")
9282 (match_operator:MODEF 3 "absneg_operator"
9283 [(match_operand:MODEF 1 "register_operand" "0,Yv,0,0")]))
9284 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "Yvm,0,X,X"))
9285 (clobber (reg:CC FLAGS_REG))]
9286 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9288 [(set (attr "enabled")
9290 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
9292 (eq_attr "alternative" "2")
9293 (symbol_ref "TARGET_MIX_SSE_I387")
9294 (symbol_ref "true"))
9296 (eq_attr "alternative" "2,3")
9298 (symbol_ref "false"))))])
9300 (define_insn "*absnegxf2_i387"
9301 [(set (match_operand:XF 0 "register_operand" "=f,!r")
9302 (match_operator:XF 3 "absneg_operator"
9303 [(match_operand:XF 1 "register_operand" "0,0")]))
9304 (use (match_operand 2))
9305 (clobber (reg:CC FLAGS_REG))]
9309 (define_expand "<code>tf2"
9310 [(set (match_operand:TF 0 "register_operand")
9311 (absneg:TF (match_operand:TF 1 "register_operand")))]
9313 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9315 (define_insn "*absnegtf2_sse"
9316 [(set (match_operand:TF 0 "register_operand" "=Yv,Yv")
9317 (match_operator:TF 3 "absneg_operator"
9318 [(match_operand:TF 1 "register_operand" "0,Yv")]))
9319 (use (match_operand:TF 2 "nonimmediate_operand" "Yvm,0"))
9320 (clobber (reg:CC FLAGS_REG))]
9324 ;; Splitters for fp abs and neg.
9327 [(set (match_operand 0 "fp_register_operand")
9328 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9329 (use (match_operand 2))
9330 (clobber (reg:CC FLAGS_REG))]
9332 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9335 [(set (match_operand 0 "sse_reg_operand")
9336 (match_operator 3 "absneg_operator"
9337 [(match_operand 1 "register_operand")]))
9338 (use (match_operand 2 "nonimmediate_operand"))
9339 (clobber (reg:CC FLAGS_REG))]
9341 [(set (match_dup 0) (match_dup 3))]
9343 machine_mode mode = GET_MODE (operands[0]);
9344 machine_mode vmode = GET_MODE (operands[2]);
9347 operands[0] = lowpart_subreg (vmode, operands[0], mode);
9348 operands[1] = lowpart_subreg (vmode, operands[1], mode);
9349 if (operands_match_p (operands[0], operands[2]))
9350 std::swap (operands[1], operands[2]);
9351 if (GET_CODE (operands[3]) == ABS)
9352 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9354 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9359 [(set (match_operand:SF 0 "general_reg_operand")
9360 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9361 (use (match_operand:V4SF 2))
9362 (clobber (reg:CC FLAGS_REG))]
9364 [(parallel [(set (match_dup 0) (match_dup 1))
9365 (clobber (reg:CC FLAGS_REG))])]
9368 operands[0] = gen_lowpart (SImode, operands[0]);
9369 if (GET_CODE (operands[1]) == ABS)
9371 tmp = gen_int_mode (0x7fffffff, SImode);
9372 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9376 tmp = gen_int_mode (0x80000000, SImode);
9377 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9383 [(set (match_operand:DF 0 "general_reg_operand")
9384 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9385 (use (match_operand 2))
9386 (clobber (reg:CC FLAGS_REG))]
9388 [(parallel [(set (match_dup 0) (match_dup 1))
9389 (clobber (reg:CC FLAGS_REG))])]
9394 tmp = gen_lowpart (DImode, operands[0]);
9395 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9398 if (GET_CODE (operands[1]) == ABS)
9401 tmp = gen_rtx_NOT (DImode, tmp);
9405 operands[0] = gen_highpart (SImode, operands[0]);
9406 if (GET_CODE (operands[1]) == ABS)
9408 tmp = gen_int_mode (0x7fffffff, SImode);
9409 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9413 tmp = gen_int_mode (0x80000000, SImode);
9414 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9421 [(set (match_operand:XF 0 "general_reg_operand")
9422 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9423 (use (match_operand 2))
9424 (clobber (reg:CC FLAGS_REG))]
9426 [(parallel [(set (match_dup 0) (match_dup 1))
9427 (clobber (reg:CC FLAGS_REG))])]
9430 operands[0] = gen_rtx_REG (SImode,
9431 REGNO (operands[0]) + (TARGET_64BIT ? 1 : 2));
9432 if (GET_CODE (operands[1]) == ABS)
9434 tmp = GEN_INT (0x7fff);
9435 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9439 tmp = GEN_INT (0x8000);
9440 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9445 ;; Conditionalize these after reload. If they match before reload, we
9446 ;; lose the clobber and ability to use integer instructions.
9448 (define_insn "*<code><mode>2_1"
9449 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9450 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9452 && (reload_completed
9453 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9454 "f<absneg_mnemonic>"
9455 [(set_attr "type" "fsgn")
9456 (set_attr "mode" "<MODE>")])
9458 (define_insn "*<code>extendsfdf2"
9459 [(set (match_operand:DF 0 "register_operand" "=f")
9460 (absneg:DF (float_extend:DF
9461 (match_operand:SF 1 "register_operand" "0"))))]
9462 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9463 "f<absneg_mnemonic>"
9464 [(set_attr "type" "fsgn")
9465 (set_attr "mode" "DF")])
9467 (define_insn "*<code>extendsfxf2"
9468 [(set (match_operand:XF 0 "register_operand" "=f")
9469 (absneg:XF (float_extend:XF
9470 (match_operand:SF 1 "register_operand" "0"))))]
9472 "f<absneg_mnemonic>"
9473 [(set_attr "type" "fsgn")
9474 (set_attr "mode" "XF")])
9476 (define_insn "*<code>extenddfxf2"
9477 [(set (match_operand:XF 0 "register_operand" "=f")
9478 (absneg:XF (float_extend:XF
9479 (match_operand:DF 1 "register_operand" "0"))))]
9481 "f<absneg_mnemonic>"
9482 [(set_attr "type" "fsgn")
9483 (set_attr "mode" "XF")])
9485 ;; Copysign instructions
9487 (define_mode_iterator CSGNMODE [SF DF TF])
9488 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9490 (define_expand "copysign<mode>3"
9491 [(match_operand:CSGNMODE 0 "register_operand")
9492 (match_operand:CSGNMODE 1 "nonmemory_operand")
9493 (match_operand:CSGNMODE 2 "register_operand")]
9494 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9495 || (TARGET_SSE && (<MODE>mode == TFmode))"
9496 "ix86_expand_copysign (operands); DONE;")
9498 (define_insn_and_split "copysign<mode>3_const"
9499 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv")
9501 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "YvmC")
9502 (match_operand:CSGNMODE 2 "register_operand" "0")
9503 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "Yvm")]
9505 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9506 || (TARGET_SSE && (<MODE>mode == TFmode))"
9508 "&& reload_completed"
9510 "ix86_split_copysign_const (operands); DONE;")
9512 (define_insn "copysign<mode>3_var"
9513 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
9515 [(match_operand:CSGNMODE 2 "register_operand" "Yv,0,0,Yv,Yv")
9516 (match_operand:CSGNMODE 3 "register_operand" "1,1,Yv,1,Yv")
9517 (match_operand:<CSGNVMODE> 4
9518 "nonimmediate_operand" "X,Yvm,Yvm,0,0")
9519 (match_operand:<CSGNVMODE> 5
9520 "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
9522 (clobber (match_scratch:<CSGNVMODE> 1 "=Yv,Yv,Yv,Yv,Yv"))]
9523 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9524 || (TARGET_SSE && (<MODE>mode == TFmode))"
9528 [(set (match_operand:CSGNMODE 0 "register_operand")
9530 [(match_operand:CSGNMODE 2 "register_operand")
9531 (match_operand:CSGNMODE 3 "register_operand")
9532 (match_operand:<CSGNVMODE> 4)
9533 (match_operand:<CSGNVMODE> 5)]
9535 (clobber (match_scratch:<CSGNVMODE> 1))]
9536 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9537 || (TARGET_SSE && (<MODE>mode == TFmode)))
9538 && reload_completed"
9540 "ix86_split_copysign_var (operands); DONE;")
9542 ;; One complement instructions
9544 (define_expand "one_cmpl<mode>2"
9545 [(set (match_operand:SWIM 0 "nonimmediate_operand")
9546 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9548 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9550 (define_insn "*one_cmpl<mode>2_1"
9551 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
9552 (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
9553 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9555 not{<imodesuffix>}\t%0
9556 knot<mskmodesuffix>\t{%1, %0|%0, %1}"
9557 [(set_attr "isa" "*,avx512bw")
9558 (set_attr "type" "negnot,msklog")
9559 (set_attr "prefix" "*,vex")
9560 (set_attr "mode" "<MODE>")])
9562 (define_insn "*one_cmplhi2_1"
9563 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
9564 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
9565 "ix86_unary_operator_ok (NOT, HImode, operands)"
9568 knotw\t{%1, %0|%0, %1}"
9569 [(set_attr "isa" "*,avx512f")
9570 (set_attr "type" "negnot,msklog")
9571 (set_attr "prefix" "*,vex")
9572 (set_attr "mode" "HI")])
9574 (define_insn "*one_cmplqi2_1"
9575 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
9576 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
9577 "ix86_unary_operator_ok (NOT, QImode, operands)"
9579 switch (which_alternative)
9582 return "not{b}\t%0";
9584 return "not{l}\t%k0";
9586 if (TARGET_AVX512DQ)
9587 return "knotb\t{%1, %0|%0, %1}";
9588 return "knotw\t{%1, %0|%0, %1}";
9593 [(set_attr "isa" "*,*,avx512f")
9594 (set_attr "type" "negnot,negnot,msklog")
9595 (set_attr "prefix" "*,*,vex")
9596 (set_attr "mode" "QI,SI,QI")
9597 ;; Potential partial reg stall on alternative 1.
9598 (set (attr "preferred_for_speed")
9599 (cond [(eq_attr "alternative" "1")
9600 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9601 (symbol_ref "true")))])
9603 ;; ??? Currently never generated - xor is used instead.
9604 (define_insn "*one_cmplsi2_1_zext"
9605 [(set (match_operand:DI 0 "register_operand" "=r")
9607 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9608 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9610 [(set_attr "type" "negnot")
9611 (set_attr "mode" "SI")])
9613 (define_insn "*one_cmpl<mode>2_2"
9614 [(set (reg FLAGS_REG)
9615 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9617 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9618 (not:SWI (match_dup 1)))]
9619 "ix86_match_ccmode (insn, CCNOmode)
9620 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9622 [(set_attr "type" "alu1")
9623 (set_attr "mode" "<MODE>")])
9626 [(set (match_operand 0 "flags_reg_operand")
9627 (match_operator 2 "compare_operator"
9628 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9630 (set (match_operand:SWI 1 "nonimmediate_operand")
9631 (not:SWI (match_dup 3)))]
9632 "ix86_match_ccmode (insn, CCNOmode)"
9633 [(parallel [(set (match_dup 0)
9634 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9637 (xor:SWI (match_dup 3) (const_int -1)))])])
9639 ;; ??? Currently never generated - xor is used instead.
9640 (define_insn "*one_cmplsi2_2_zext"
9641 [(set (reg FLAGS_REG)
9642 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9644 (set (match_operand:DI 0 "register_operand" "=r")
9645 (zero_extend:DI (not:SI (match_dup 1))))]
9646 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9647 && ix86_unary_operator_ok (NOT, SImode, operands)"
9649 [(set_attr "type" "alu1")
9650 (set_attr "mode" "SI")])
9653 [(set (match_operand 0 "flags_reg_operand")
9654 (match_operator 2 "compare_operator"
9655 [(not:SI (match_operand:SI 3 "register_operand"))
9657 (set (match_operand:DI 1 "register_operand")
9658 (zero_extend:DI (not:SI (match_dup 3))))]
9659 "ix86_match_ccmode (insn, CCNOmode)"
9660 [(parallel [(set (match_dup 0)
9661 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9664 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9666 ;; Shift instructions
9668 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9669 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9670 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9671 ;; from the assembler input.
9673 ;; This instruction shifts the target reg/mem as usual, but instead of
9674 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9675 ;; is a left shift double, bits are taken from the high order bits of
9676 ;; reg, else if the insn is a shift right double, bits are taken from the
9677 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9678 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9680 ;; Since sh[lr]d does not change the `reg' operand, that is done
9681 ;; separately, making all shifts emit pairs of shift double and normal
9682 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9683 ;; support a 63 bit shift, each shift where the count is in a reg expands
9684 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9686 ;; If the shift count is a constant, we need never emit more than one
9687 ;; shift pair, instead using moves and sign extension for counts greater
9690 (define_insn "*<mshift><mode>3"
9691 [(set (match_operand:SWI1248_AVX512BWDQ 0 "register_operand" "=k")
9692 (any_lshift:SWI1248_AVX512BWDQ (match_operand:SWI1248_AVX512BWDQ 1 "register_operand" "k")
9693 (match_operand:QI 2 "immediate_operand" "i")))]
9695 "k<mshift><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
9696 [(set_attr "type" "msklog")
9697 (set_attr "prefix" "vex")])
9699 (define_expand "ashl<mode>3"
9700 [(set (match_operand:SDWIM 0 "<shift_operand>")
9701 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9702 (match_operand:QI 2 "nonmemory_operand")))]
9704 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9706 (define_insn "*ashl<mode>3_doubleword"
9707 [(set (match_operand:DWI 0 "register_operand" "=&r")
9708 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
9709 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9710 (clobber (reg:CC FLAGS_REG))]
9713 [(set_attr "type" "multi")])
9716 [(set (match_operand:DWI 0 "register_operand")
9717 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9718 (match_operand:QI 2 "nonmemory_operand")))
9719 (clobber (reg:CC FLAGS_REG))]
9720 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9722 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9724 ;; By default we don't ask for a scratch register, because when DWImode
9725 ;; values are manipulated, registers are already at a premium. But if
9726 ;; we have one handy, we won't turn it away.
9729 [(match_scratch:DWIH 3 "r")
9730 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9732 (match_operand:<DWI> 1 "nonmemory_operand")
9733 (match_operand:QI 2 "nonmemory_operand")))
9734 (clobber (reg:CC FLAGS_REG))])
9738 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9740 (define_insn "x86_64_shld"
9741 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9742 (ior:DI (ashift:DI (match_dup 0)
9743 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9744 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9745 (minus:QI (const_int 64) (match_dup 2)))))
9746 (clobber (reg:CC FLAGS_REG))]
9748 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9749 [(set_attr "type" "ishift")
9750 (set_attr "prefix_0f" "1")
9751 (set_attr "mode" "DI")
9752 (set_attr "athlon_decode" "vector")
9753 (set_attr "amdfam10_decode" "vector")
9754 (set_attr "bdver1_decode" "vector")])
9756 (define_insn "x86_shld"
9757 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9758 (ior:SI (ashift:SI (match_dup 0)
9759 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9760 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9761 (minus:QI (const_int 32) (match_dup 2)))))
9762 (clobber (reg:CC FLAGS_REG))]
9764 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9765 [(set_attr "type" "ishift")
9766 (set_attr "prefix_0f" "1")
9767 (set_attr "mode" "SI")
9768 (set_attr "pent_pair" "np")
9769 (set_attr "athlon_decode" "vector")
9770 (set_attr "amdfam10_decode" "vector")
9771 (set_attr "bdver1_decode" "vector")])
9773 (define_expand "x86_shift<mode>_adj_1"
9774 [(set (reg:CCZ FLAGS_REG)
9775 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9778 (set (match_operand:SWI48 0 "register_operand")
9779 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9780 (match_operand:SWI48 1 "register_operand")
9783 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9784 (match_operand:SWI48 3 "register_operand")
9787 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9789 (define_expand "x86_shift<mode>_adj_2"
9790 [(use (match_operand:SWI48 0 "register_operand"))
9791 (use (match_operand:SWI48 1 "register_operand"))
9792 (use (match_operand:QI 2 "register_operand"))]
9795 rtx_code_label *label = gen_label_rtx ();
9798 emit_insn (gen_testqi_ccz_1 (operands[2],
9799 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9801 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9802 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9803 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9804 gen_rtx_LABEL_REF (VOIDmode, label),
9806 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
9807 JUMP_LABEL (tmp) = label;
9809 emit_move_insn (operands[0], operands[1]);
9810 ix86_expand_clear (operands[1]);
9813 LABEL_NUSES (label) = 1;
9818 ;; Avoid useless masking of count operand.
9819 (define_insn_and_split "*ashl<mode>3_mask"
9820 [(set (match_operand:SWI48 0 "nonimmediate_operand")
9822 (match_operand:SWI48 1 "nonimmediate_operand")
9825 (match_operand:SI 2 "register_operand")
9826 (match_operand:SI 3 "const_int_operand")) 0)))
9827 (clobber (reg:CC FLAGS_REG))]
9828 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9829 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9830 == GET_MODE_BITSIZE (<MODE>mode)-1
9831 && can_create_pseudo_p ()"
9836 (ashift:SWI48 (match_dup 1)
9838 (clobber (reg:CC FLAGS_REG))])]
9839 "operands[2] = gen_lowpart (QImode, operands[2]);")
9841 (define_insn "*bmi2_ashl<mode>3_1"
9842 [(set (match_operand:SWI48 0 "register_operand" "=r")
9843 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9844 (match_operand:SWI48 2 "register_operand" "r")))]
9846 "shlx\t{%2, %1, %0|%0, %1, %2}"
9847 [(set_attr "type" "ishiftx")
9848 (set_attr "mode" "<MODE>")])
9850 (define_insn "*ashl<mode>3_1"
9851 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9852 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9853 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9854 (clobber (reg:CC FLAGS_REG))]
9855 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9857 switch (get_attr_type (insn))
9864 gcc_assert (operands[2] == const1_rtx);
9865 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9866 return "add{<imodesuffix>}\t%0, %0";
9869 if (operands[2] == const1_rtx
9870 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9871 return "sal{<imodesuffix>}\t%0";
9873 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9876 [(set_attr "isa" "*,*,bmi2")
9878 (cond [(eq_attr "alternative" "1")
9879 (const_string "lea")
9880 (eq_attr "alternative" "2")
9881 (const_string "ishiftx")
9882 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9883 (match_operand 0 "register_operand"))
9884 (match_operand 2 "const1_operand"))
9885 (const_string "alu")
9887 (const_string "ishift")))
9888 (set (attr "length_immediate")
9890 (ior (eq_attr "type" "alu")
9891 (and (eq_attr "type" "ishift")
9892 (and (match_operand 2 "const1_operand")
9893 (ior (match_test "TARGET_SHIFT1")
9894 (match_test "optimize_function_for_size_p (cfun)")))))
9896 (const_string "*")))
9897 (set_attr "mode" "<MODE>")])
9899 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9901 [(set (match_operand:SWI48 0 "register_operand")
9902 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9903 (match_operand:QI 2 "register_operand")))
9904 (clobber (reg:CC FLAGS_REG))]
9905 "TARGET_BMI2 && reload_completed"
9907 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9908 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9910 (define_insn "*bmi2_ashlsi3_1_zext"
9911 [(set (match_operand:DI 0 "register_operand" "=r")
9913 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9914 (match_operand:SI 2 "register_operand" "r"))))]
9915 "TARGET_64BIT && TARGET_BMI2"
9916 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9917 [(set_attr "type" "ishiftx")
9918 (set_attr "mode" "SI")])
9920 (define_insn "*ashlsi3_1_zext"
9921 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9923 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9924 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9925 (clobber (reg:CC FLAGS_REG))]
9926 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9928 switch (get_attr_type (insn))
9935 gcc_assert (operands[2] == const1_rtx);
9936 return "add{l}\t%k0, %k0";
9939 if (operands[2] == const1_rtx
9940 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9941 return "sal{l}\t%k0";
9943 return "sal{l}\t{%2, %k0|%k0, %2}";
9946 [(set_attr "isa" "*,*,bmi2")
9948 (cond [(eq_attr "alternative" "1")
9949 (const_string "lea")
9950 (eq_attr "alternative" "2")
9951 (const_string "ishiftx")
9952 (and (match_test "TARGET_DOUBLE_WITH_ADD")
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" "SI")])
9968 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9970 [(set (match_operand:DI 0 "register_operand")
9972 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9973 (match_operand:QI 2 "register_operand"))))
9974 (clobber (reg:CC FLAGS_REG))]
9975 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9977 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9978 "operands[2] = gen_lowpart (SImode, operands[2]);")
9980 (define_insn "*ashlhi3_1"
9981 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9982 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9983 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9984 (clobber (reg:CC FLAGS_REG))]
9985 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9987 switch (get_attr_type (insn))
9993 gcc_assert (operands[2] == const1_rtx);
9994 return "add{w}\t%0, %0";
9997 if (operands[2] == const1_rtx
9998 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9999 return "sal{w}\t%0";
10001 return "sal{w}\t{%2, %0|%0, %2}";
10004 [(set (attr "type")
10005 (cond [(eq_attr "alternative" "1")
10006 (const_string "lea")
10007 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10008 (match_operand 0 "register_operand"))
10009 (match_operand 2 "const1_operand"))
10010 (const_string "alu")
10012 (const_string "ishift")))
10013 (set (attr "length_immediate")
10015 (ior (eq_attr "type" "alu")
10016 (and (eq_attr "type" "ishift")
10017 (and (match_operand 2 "const1_operand")
10018 (ior (match_test "TARGET_SHIFT1")
10019 (match_test "optimize_function_for_size_p (cfun)")))))
10021 (const_string "*")))
10022 (set_attr "mode" "HI,SI")])
10024 (define_insn "*ashlqi3_1"
10025 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
10026 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10027 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10028 (clobber (reg:CC FLAGS_REG))]
10029 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10031 switch (get_attr_type (insn))
10037 gcc_assert (operands[2] == const1_rtx);
10038 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
10039 return "add{l}\t%k0, %k0";
10041 return "add{b}\t%0, %0";
10044 if (operands[2] == const1_rtx
10045 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10047 if (get_attr_mode (insn) == MODE_SI)
10048 return "sal{l}\t%k0";
10050 return "sal{b}\t%0";
10054 if (get_attr_mode (insn) == MODE_SI)
10055 return "sal{l}\t{%2, %k0|%k0, %2}";
10057 return "sal{b}\t{%2, %0|%0, %2}";
10061 [(set (attr "type")
10062 (cond [(eq_attr "alternative" "2")
10063 (const_string "lea")
10064 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10065 (match_operand 0 "register_operand"))
10066 (match_operand 2 "const1_operand"))
10067 (const_string "alu")
10069 (const_string "ishift")))
10070 (set (attr "length_immediate")
10072 (ior (eq_attr "type" "alu")
10073 (and (eq_attr "type" "ishift")
10074 (and (match_operand 2 "const1_operand")
10075 (ior (match_test "TARGET_SHIFT1")
10076 (match_test "optimize_function_for_size_p (cfun)")))))
10078 (const_string "*")))
10079 (set_attr "mode" "QI,SI,SI")
10080 ;; Potential partial reg stall on alternative 1.
10081 (set (attr "preferred_for_speed")
10082 (cond [(eq_attr "alternative" "1")
10083 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10084 (symbol_ref "true")))])
10086 (define_insn "*ashlqi3_1_slp"
10087 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10088 (ashift:QI (match_dup 0)
10089 (match_operand:QI 1 "nonmemory_operand" "cI")))
10090 (clobber (reg:CC FLAGS_REG))]
10091 "(optimize_function_for_size_p (cfun)
10092 || !TARGET_PARTIAL_FLAG_REG_STALL
10093 || (operands[1] == const1_rtx
10095 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10097 switch (get_attr_type (insn))
10100 gcc_assert (operands[1] == const1_rtx);
10101 return "add{b}\t%0, %0";
10104 if (operands[1] == const1_rtx
10105 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10106 return "sal{b}\t%0";
10108 return "sal{b}\t{%1, %0|%0, %1}";
10111 [(set (attr "type")
10112 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10113 (match_operand 0 "register_operand"))
10114 (match_operand 1 "const1_operand"))
10115 (const_string "alu")
10117 (const_string "ishift1")))
10118 (set (attr "length_immediate")
10120 (ior (eq_attr "type" "alu")
10121 (and (eq_attr "type" "ishift1")
10122 (and (match_operand 1 "const1_operand")
10123 (ior (match_test "TARGET_SHIFT1")
10124 (match_test "optimize_function_for_size_p (cfun)")))))
10126 (const_string "*")))
10127 (set_attr "mode" "QI")])
10129 ;; Convert ashift to the lea pattern to avoid flags dependency.
10131 [(set (match_operand:SWI 0 "register_operand")
10132 (ashift:SWI (match_operand:SWI 1 "index_register_operand")
10133 (match_operand 2 "const_0_to_3_operand")))
10134 (clobber (reg:CC FLAGS_REG))]
10136 && REGNO (operands[0]) != REGNO (operands[1])"
10137 [(set (match_dup 0)
10138 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
10140 if (<MODE>mode != <LEAMODE>mode)
10142 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
10143 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
10145 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10148 ;; Convert ashift to the lea pattern to avoid flags dependency.
10150 [(set (match_operand:DI 0 "register_operand")
10152 (ashift:SI (match_operand:SI 1 "index_register_operand")
10153 (match_operand 2 "const_0_to_3_operand"))))
10154 (clobber (reg:CC FLAGS_REG))]
10155 "TARGET_64BIT && reload_completed
10156 && REGNO (operands[0]) != REGNO (operands[1])"
10157 [(set (match_dup 0)
10158 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10160 operands[1] = gen_lowpart (SImode, operands[1]);
10161 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10164 ;; This pattern can't accept a variable shift count, since shifts by
10165 ;; zero don't affect the flags. We assume that shifts by constant
10166 ;; zero are optimized away.
10167 (define_insn "*ashl<mode>3_cmp"
10168 [(set (reg FLAGS_REG)
10170 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10171 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10173 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10174 (ashift:SWI (match_dup 1) (match_dup 2)))]
10175 "(optimize_function_for_size_p (cfun)
10176 || !TARGET_PARTIAL_FLAG_REG_STALL
10177 || (operands[2] == const1_rtx
10179 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10180 && ix86_match_ccmode (insn, CCGOCmode)
10181 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10183 switch (get_attr_type (insn))
10186 gcc_assert (operands[2] == const1_rtx);
10187 return "add{<imodesuffix>}\t%0, %0";
10190 if (operands[2] == const1_rtx
10191 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10192 return "sal{<imodesuffix>}\t%0";
10194 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10197 [(set (attr "type")
10198 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10199 (match_operand 0 "register_operand"))
10200 (match_operand 2 "const1_operand"))
10201 (const_string "alu")
10203 (const_string "ishift")))
10204 (set (attr "length_immediate")
10206 (ior (eq_attr "type" "alu")
10207 (and (eq_attr "type" "ishift")
10208 (and (match_operand 2 "const1_operand")
10209 (ior (match_test "TARGET_SHIFT1")
10210 (match_test "optimize_function_for_size_p (cfun)")))))
10212 (const_string "*")))
10213 (set_attr "mode" "<MODE>")])
10215 (define_insn "*ashlsi3_cmp_zext"
10216 [(set (reg FLAGS_REG)
10218 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10219 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10221 (set (match_operand:DI 0 "register_operand" "=r")
10222 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10224 && (optimize_function_for_size_p (cfun)
10225 || !TARGET_PARTIAL_FLAG_REG_STALL
10226 || (operands[2] == const1_rtx
10228 || TARGET_DOUBLE_WITH_ADD)))
10229 && ix86_match_ccmode (insn, CCGOCmode)
10230 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10232 switch (get_attr_type (insn))
10235 gcc_assert (operands[2] == const1_rtx);
10236 return "add{l}\t%k0, %k0";
10239 if (operands[2] == const1_rtx
10240 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10241 return "sal{l}\t%k0";
10243 return "sal{l}\t{%2, %k0|%k0, %2}";
10246 [(set (attr "type")
10247 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
10248 (match_operand 2 "const1_operand"))
10249 (const_string "alu")
10251 (const_string "ishift")))
10252 (set (attr "length_immediate")
10254 (ior (eq_attr "type" "alu")
10255 (and (eq_attr "type" "ishift")
10256 (and (match_operand 2 "const1_operand")
10257 (ior (match_test "TARGET_SHIFT1")
10258 (match_test "optimize_function_for_size_p (cfun)")))))
10260 (const_string "*")))
10261 (set_attr "mode" "SI")])
10263 (define_insn "*ashl<mode>3_cconly"
10264 [(set (reg FLAGS_REG)
10266 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
10267 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10269 (clobber (match_scratch:SWI 0 "=<r>"))]
10270 "(optimize_function_for_size_p (cfun)
10271 || !TARGET_PARTIAL_FLAG_REG_STALL
10272 || (operands[2] == const1_rtx
10274 || TARGET_DOUBLE_WITH_ADD)))
10275 && ix86_match_ccmode (insn, CCGOCmode)"
10277 switch (get_attr_type (insn))
10280 gcc_assert (operands[2] == const1_rtx);
10281 return "add{<imodesuffix>}\t%0, %0";
10284 if (operands[2] == const1_rtx
10285 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10286 return "sal{<imodesuffix>}\t%0";
10288 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10291 [(set (attr "type")
10292 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10293 (match_operand 0 "register_operand"))
10294 (match_operand 2 "const1_operand"))
10295 (const_string "alu")
10297 (const_string "ishift")))
10298 (set (attr "length_immediate")
10300 (ior (eq_attr "type" "alu")
10301 (and (eq_attr "type" "ishift")
10302 (and (match_operand 2 "const1_operand")
10303 (ior (match_test "TARGET_SHIFT1")
10304 (match_test "optimize_function_for_size_p (cfun)")))))
10306 (const_string "*")))
10307 (set_attr "mode" "<MODE>")])
10309 ;; See comment above `ashl<mode>3' about how this works.
10311 (define_expand "<shift_insn><mode>3"
10312 [(set (match_operand:SDWIM 0 "<shift_operand>")
10313 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
10314 (match_operand:QI 2 "nonmemory_operand")))]
10316 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10318 ;; Avoid useless masking of count operand.
10319 (define_insn_and_split "*<shift_insn><mode>3_mask"
10320 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10322 (match_operand:SWI48 1 "nonimmediate_operand")
10325 (match_operand:SI 2 "register_operand")
10326 (match_operand:SI 3 "const_int_operand")) 0)))
10327 (clobber (reg:CC FLAGS_REG))]
10328 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10329 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10330 == GET_MODE_BITSIZE (<MODE>mode)-1
10331 && can_create_pseudo_p ()"
10335 [(set (match_dup 0)
10336 (any_shiftrt:SWI48 (match_dup 1)
10338 (clobber (reg:CC FLAGS_REG))])]
10339 "operands[2] = gen_lowpart (QImode, operands[2]);")
10341 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
10342 [(set (match_operand:DWI 0 "register_operand" "=&r")
10343 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10344 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10345 (clobber (reg:CC FLAGS_REG))]
10348 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10350 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10351 [(set_attr "type" "multi")])
10353 ;; By default we don't ask for a scratch register, because when DWImode
10354 ;; values are manipulated, registers are already at a premium. But if
10355 ;; we have one handy, we won't turn it away.
10358 [(match_scratch:DWIH 3 "r")
10359 (parallel [(set (match_operand:<DWI> 0 "register_operand")
10361 (match_operand:<DWI> 1 "register_operand")
10362 (match_operand:QI 2 "nonmemory_operand")))
10363 (clobber (reg:CC FLAGS_REG))])
10367 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
10369 (define_insn "x86_64_shrd"
10370 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10371 (ior:DI (lshiftrt:DI (match_dup 0)
10372 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10373 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10374 (minus:QI (const_int 64) (match_dup 2)))))
10375 (clobber (reg:CC FLAGS_REG))]
10377 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10378 [(set_attr "type" "ishift")
10379 (set_attr "prefix_0f" "1")
10380 (set_attr "mode" "DI")
10381 (set_attr "athlon_decode" "vector")
10382 (set_attr "amdfam10_decode" "vector")
10383 (set_attr "bdver1_decode" "vector")])
10385 (define_insn "x86_shrd"
10386 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10387 (ior:SI (lshiftrt:SI (match_dup 0)
10388 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10389 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10390 (minus:QI (const_int 32) (match_dup 2)))))
10391 (clobber (reg:CC FLAGS_REG))]
10393 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10394 [(set_attr "type" "ishift")
10395 (set_attr "prefix_0f" "1")
10396 (set_attr "mode" "SI")
10397 (set_attr "pent_pair" "np")
10398 (set_attr "athlon_decode" "vector")
10399 (set_attr "amdfam10_decode" "vector")
10400 (set_attr "bdver1_decode" "vector")])
10402 (define_insn "ashrdi3_cvt"
10403 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10404 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10405 (match_operand:QI 2 "const_int_operand")))
10406 (clobber (reg:CC FLAGS_REG))]
10407 "TARGET_64BIT && INTVAL (operands[2]) == 63
10408 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10409 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10412 sar{q}\t{%2, %0|%0, %2}"
10413 [(set_attr "type" "imovx,ishift")
10414 (set_attr "prefix_0f" "0,*")
10415 (set_attr "length_immediate" "0,*")
10416 (set_attr "modrm" "0,1")
10417 (set_attr "mode" "DI")])
10419 (define_insn "ashrsi3_cvt"
10420 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10421 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10422 (match_operand:QI 2 "const_int_operand")))
10423 (clobber (reg:CC FLAGS_REG))]
10424 "INTVAL (operands[2]) == 31
10425 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10426 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10429 sar{l}\t{%2, %0|%0, %2}"
10430 [(set_attr "type" "imovx,ishift")
10431 (set_attr "prefix_0f" "0,*")
10432 (set_attr "length_immediate" "0,*")
10433 (set_attr "modrm" "0,1")
10434 (set_attr "mode" "SI")])
10436 (define_insn "*ashrsi3_cvt_zext"
10437 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10439 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10440 (match_operand:QI 2 "const_int_operand"))))
10441 (clobber (reg:CC FLAGS_REG))]
10442 "TARGET_64BIT && INTVAL (operands[2]) == 31
10443 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10444 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10447 sar{l}\t{%2, %k0|%k0, %2}"
10448 [(set_attr "type" "imovx,ishift")
10449 (set_attr "prefix_0f" "0,*")
10450 (set_attr "length_immediate" "0,*")
10451 (set_attr "modrm" "0,1")
10452 (set_attr "mode" "SI")])
10454 (define_expand "x86_shift<mode>_adj_3"
10455 [(use (match_operand:SWI48 0 "register_operand"))
10456 (use (match_operand:SWI48 1 "register_operand"))
10457 (use (match_operand:QI 2 "register_operand"))]
10460 rtx_code_label *label = gen_label_rtx ();
10463 emit_insn (gen_testqi_ccz_1 (operands[2],
10464 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10466 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10467 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10468 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10469 gen_rtx_LABEL_REF (VOIDmode, label),
10471 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10472 JUMP_LABEL (tmp) = label;
10474 emit_move_insn (operands[0], operands[1]);
10475 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10476 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10477 emit_label (label);
10478 LABEL_NUSES (label) = 1;
10483 (define_insn "*bmi2_<shift_insn><mode>3_1"
10484 [(set (match_operand:SWI48 0 "register_operand" "=r")
10485 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10486 (match_operand:SWI48 2 "register_operand" "r")))]
10488 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10489 [(set_attr "type" "ishiftx")
10490 (set_attr "mode" "<MODE>")])
10492 (define_insn "*<shift_insn><mode>3_1"
10493 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10495 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10496 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10497 (clobber (reg:CC FLAGS_REG))]
10498 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10500 switch (get_attr_type (insn))
10506 if (operands[2] == const1_rtx
10507 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10508 return "<shift>{<imodesuffix>}\t%0";
10510 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10513 [(set_attr "isa" "*,bmi2")
10514 (set_attr "type" "ishift,ishiftx")
10515 (set (attr "length_immediate")
10517 (and (match_operand 2 "const1_operand")
10518 (ior (match_test "TARGET_SHIFT1")
10519 (match_test "optimize_function_for_size_p (cfun)")))
10521 (const_string "*")))
10522 (set_attr "mode" "<MODE>")])
10524 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10526 [(set (match_operand:SWI48 0 "register_operand")
10527 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10528 (match_operand:QI 2 "register_operand")))
10529 (clobber (reg:CC FLAGS_REG))]
10530 "TARGET_BMI2 && reload_completed"
10531 [(set (match_dup 0)
10532 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10533 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10535 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10536 [(set (match_operand:DI 0 "register_operand" "=r")
10538 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10539 (match_operand:SI 2 "register_operand" "r"))))]
10540 "TARGET_64BIT && TARGET_BMI2"
10541 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10542 [(set_attr "type" "ishiftx")
10543 (set_attr "mode" "SI")])
10545 (define_insn "*<shift_insn>si3_1_zext"
10546 [(set (match_operand:DI 0 "register_operand" "=r,r")
10548 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10549 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10550 (clobber (reg:CC FLAGS_REG))]
10551 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10553 switch (get_attr_type (insn))
10559 if (operands[2] == const1_rtx
10560 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10561 return "<shift>{l}\t%k0";
10563 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10566 [(set_attr "isa" "*,bmi2")
10567 (set_attr "type" "ishift,ishiftx")
10568 (set (attr "length_immediate")
10570 (and (match_operand 2 "const1_operand")
10571 (ior (match_test "TARGET_SHIFT1")
10572 (match_test "optimize_function_for_size_p (cfun)")))
10574 (const_string "*")))
10575 (set_attr "mode" "SI")])
10577 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10579 [(set (match_operand:DI 0 "register_operand")
10581 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10582 (match_operand:QI 2 "register_operand"))))
10583 (clobber (reg:CC FLAGS_REG))]
10584 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10585 [(set (match_dup 0)
10586 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10587 "operands[2] = gen_lowpart (SImode, operands[2]);")
10589 (define_insn "*<shift_insn><mode>3_1"
10590 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10592 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10593 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10594 (clobber (reg:CC FLAGS_REG))]
10595 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10597 if (operands[2] == const1_rtx
10598 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10599 return "<shift>{<imodesuffix>}\t%0";
10601 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10603 [(set_attr "type" "ishift")
10604 (set (attr "length_immediate")
10606 (and (match_operand 2 "const1_operand")
10607 (ior (match_test "TARGET_SHIFT1")
10608 (match_test "optimize_function_for_size_p (cfun)")))
10610 (const_string "*")))
10611 (set_attr "mode" "<MODE>")])
10613 (define_insn "*<shift_insn>qi3_1_slp"
10614 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10615 (any_shiftrt:QI (match_dup 0)
10616 (match_operand:QI 1 "nonmemory_operand" "cI")))
10617 (clobber (reg:CC FLAGS_REG))]
10618 "(optimize_function_for_size_p (cfun)
10619 || !TARGET_PARTIAL_REG_STALL
10620 || (operands[1] == const1_rtx
10621 && TARGET_SHIFT1))"
10623 if (operands[1] == const1_rtx
10624 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10625 return "<shift>{b}\t%0";
10627 return "<shift>{b}\t{%1, %0|%0, %1}";
10629 [(set_attr "type" "ishift1")
10630 (set (attr "length_immediate")
10632 (and (match_operand 1 "const1_operand")
10633 (ior (match_test "TARGET_SHIFT1")
10634 (match_test "optimize_function_for_size_p (cfun)")))
10636 (const_string "*")))
10637 (set_attr "mode" "QI")])
10639 ;; This pattern can't accept a variable shift count, since shifts by
10640 ;; zero don't affect the flags. We assume that shifts by constant
10641 ;; zero are optimized away.
10642 (define_insn "*<shift_insn><mode>3_cmp"
10643 [(set (reg FLAGS_REG)
10646 (match_operand:SWI 1 "nonimmediate_operand" "0")
10647 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10649 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10650 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10651 "(optimize_function_for_size_p (cfun)
10652 || !TARGET_PARTIAL_FLAG_REG_STALL
10653 || (operands[2] == const1_rtx
10655 && ix86_match_ccmode (insn, CCGOCmode)
10656 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10658 if (operands[2] == const1_rtx
10659 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10660 return "<shift>{<imodesuffix>}\t%0";
10662 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10664 [(set_attr "type" "ishift")
10665 (set (attr "length_immediate")
10667 (and (match_operand 2 "const1_operand")
10668 (ior (match_test "TARGET_SHIFT1")
10669 (match_test "optimize_function_for_size_p (cfun)")))
10671 (const_string "*")))
10672 (set_attr "mode" "<MODE>")])
10674 (define_insn "*<shift_insn>si3_cmp_zext"
10675 [(set (reg FLAGS_REG)
10677 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10678 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10680 (set (match_operand:DI 0 "register_operand" "=r")
10681 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10683 && (optimize_function_for_size_p (cfun)
10684 || !TARGET_PARTIAL_FLAG_REG_STALL
10685 || (operands[2] == const1_rtx
10687 && ix86_match_ccmode (insn, CCGOCmode)
10688 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10690 if (operands[2] == const1_rtx
10691 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10692 return "<shift>{l}\t%k0";
10694 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10696 [(set_attr "type" "ishift")
10697 (set (attr "length_immediate")
10699 (and (match_operand 2 "const1_operand")
10700 (ior (match_test "TARGET_SHIFT1")
10701 (match_test "optimize_function_for_size_p (cfun)")))
10703 (const_string "*")))
10704 (set_attr "mode" "SI")])
10706 (define_insn "*<shift_insn><mode>3_cconly"
10707 [(set (reg FLAGS_REG)
10710 (match_operand:SWI 1 "register_operand" "0")
10711 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10713 (clobber (match_scratch:SWI 0 "=<r>"))]
10714 "(optimize_function_for_size_p (cfun)
10715 || !TARGET_PARTIAL_FLAG_REG_STALL
10716 || (operands[2] == const1_rtx
10718 && ix86_match_ccmode (insn, CCGOCmode)"
10720 if (operands[2] == const1_rtx
10721 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10722 return "<shift>{<imodesuffix>}\t%0";
10724 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10726 [(set_attr "type" "ishift")
10727 (set (attr "length_immediate")
10729 (and (match_operand 2 "const1_operand")
10730 (ior (match_test "TARGET_SHIFT1")
10731 (match_test "optimize_function_for_size_p (cfun)")))
10733 (const_string "*")))
10734 (set_attr "mode" "<MODE>")])
10736 ;; Rotate instructions
10738 (define_expand "<rotate_insn>ti3"
10739 [(set (match_operand:TI 0 "register_operand")
10740 (any_rotate:TI (match_operand:TI 1 "register_operand")
10741 (match_operand:QI 2 "nonmemory_operand")))]
10744 if (const_1_to_63_operand (operands[2], VOIDmode))
10745 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10746 (operands[0], operands[1], operands[2]));
10753 (define_expand "<rotate_insn>di3"
10754 [(set (match_operand:DI 0 "shiftdi_operand")
10755 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10756 (match_operand:QI 2 "nonmemory_operand")))]
10760 ix86_expand_binary_operator (<CODE>, DImode, operands);
10761 else if (const_1_to_31_operand (operands[2], VOIDmode))
10762 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10763 (operands[0], operands[1], operands[2]));
10770 (define_expand "<rotate_insn><mode>3"
10771 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10772 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10773 (match_operand:QI 2 "nonmemory_operand")))]
10775 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10777 ;; Avoid useless masking of count operand.
10778 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10779 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10781 (match_operand:SWI48 1 "nonimmediate_operand")
10784 (match_operand:SI 2 "register_operand")
10785 (match_operand:SI 3 "const_int_operand")) 0)))
10786 (clobber (reg:CC FLAGS_REG))]
10787 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10788 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10789 == GET_MODE_BITSIZE (<MODE>mode)-1
10790 && can_create_pseudo_p ()"
10794 [(set (match_dup 0)
10795 (any_rotate:SWI48 (match_dup 1)
10797 (clobber (reg:CC FLAGS_REG))])]
10798 "operands[2] = gen_lowpart (QImode, operands[2]);")
10800 ;; Implement rotation using two double-precision
10801 ;; shift instructions and a scratch register.
10803 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10804 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10805 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10806 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10807 (clobber (reg:CC FLAGS_REG))
10808 (clobber (match_scratch:DWIH 3 "=&r"))]
10812 [(set (match_dup 3) (match_dup 4))
10814 [(set (match_dup 4)
10815 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10816 (lshiftrt:DWIH (match_dup 5)
10817 (minus:QI (match_dup 6) (match_dup 2)))))
10818 (clobber (reg:CC FLAGS_REG))])
10820 [(set (match_dup 5)
10821 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10822 (lshiftrt:DWIH (match_dup 3)
10823 (minus:QI (match_dup 6) (match_dup 2)))))
10824 (clobber (reg:CC FLAGS_REG))])]
10826 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10828 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10831 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10832 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10833 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10834 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10835 (clobber (reg:CC FLAGS_REG))
10836 (clobber (match_scratch:DWIH 3 "=&r"))]
10840 [(set (match_dup 3) (match_dup 4))
10842 [(set (match_dup 4)
10843 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10844 (ashift:DWIH (match_dup 5)
10845 (minus:QI (match_dup 6) (match_dup 2)))))
10846 (clobber (reg:CC FLAGS_REG))])
10848 [(set (match_dup 5)
10849 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10850 (ashift:DWIH (match_dup 3)
10851 (minus:QI (match_dup 6) (match_dup 2)))))
10852 (clobber (reg:CC FLAGS_REG))])]
10854 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10856 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10859 (define_insn "*bmi2_rorx<mode>3_1"
10860 [(set (match_operand:SWI48 0 "register_operand" "=r")
10861 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10862 (match_operand:QI 2 "immediate_operand" "<S>")))]
10864 "rorx\t{%2, %1, %0|%0, %1, %2}"
10865 [(set_attr "type" "rotatex")
10866 (set_attr "mode" "<MODE>")])
10868 (define_insn "*<rotate_insn><mode>3_1"
10869 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10871 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10872 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10873 (clobber (reg:CC FLAGS_REG))]
10874 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10876 switch (get_attr_type (insn))
10882 if (operands[2] == const1_rtx
10883 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10884 return "<rotate>{<imodesuffix>}\t%0";
10886 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10889 [(set_attr "isa" "*,bmi2")
10890 (set_attr "type" "rotate,rotatex")
10891 (set (attr "length_immediate")
10893 (and (eq_attr "type" "rotate")
10894 (and (match_operand 2 "const1_operand")
10895 (ior (match_test "TARGET_SHIFT1")
10896 (match_test "optimize_function_for_size_p (cfun)"))))
10898 (const_string "*")))
10899 (set_attr "mode" "<MODE>")])
10901 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10903 [(set (match_operand:SWI48 0 "register_operand")
10904 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10905 (match_operand:QI 2 "immediate_operand")))
10906 (clobber (reg:CC FLAGS_REG))]
10907 "TARGET_BMI2 && reload_completed"
10908 [(set (match_dup 0)
10909 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10911 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
10913 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
10917 [(set (match_operand:SWI48 0 "register_operand")
10918 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10919 (match_operand:QI 2 "immediate_operand")))
10920 (clobber (reg:CC FLAGS_REG))]
10921 "TARGET_BMI2 && reload_completed"
10922 [(set (match_dup 0)
10923 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10925 (define_insn "*bmi2_rorxsi3_1_zext"
10926 [(set (match_operand:DI 0 "register_operand" "=r")
10928 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10929 (match_operand:QI 2 "immediate_operand" "I"))))]
10930 "TARGET_64BIT && TARGET_BMI2"
10931 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10932 [(set_attr "type" "rotatex")
10933 (set_attr "mode" "SI")])
10935 (define_insn "*<rotate_insn>si3_1_zext"
10936 [(set (match_operand:DI 0 "register_operand" "=r,r")
10938 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10939 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10940 (clobber (reg:CC FLAGS_REG))]
10941 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10943 switch (get_attr_type (insn))
10949 if (operands[2] == const1_rtx
10950 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10951 return "<rotate>{l}\t%k0";
10953 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10956 [(set_attr "isa" "*,bmi2")
10957 (set_attr "type" "rotate,rotatex")
10958 (set (attr "length_immediate")
10960 (and (eq_attr "type" "rotate")
10961 (and (match_operand 2 "const1_operand")
10962 (ior (match_test "TARGET_SHIFT1")
10963 (match_test "optimize_function_for_size_p (cfun)"))))
10965 (const_string "*")))
10966 (set_attr "mode" "SI")])
10968 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10970 [(set (match_operand:DI 0 "register_operand")
10972 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10973 (match_operand:QI 2 "immediate_operand"))))
10974 (clobber (reg:CC FLAGS_REG))]
10975 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10976 [(set (match_dup 0)
10977 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10979 int bitsize = GET_MODE_BITSIZE (SImode);
10981 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
10985 [(set (match_operand:DI 0 "register_operand")
10987 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10988 (match_operand:QI 2 "immediate_operand"))))
10989 (clobber (reg:CC FLAGS_REG))]
10990 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10991 [(set (match_dup 0)
10992 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10994 (define_insn "*<rotate_insn><mode>3_1"
10995 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10996 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10997 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10998 (clobber (reg:CC FLAGS_REG))]
10999 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11001 if (operands[2] == const1_rtx
11002 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11003 return "<rotate>{<imodesuffix>}\t%0";
11005 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11007 [(set_attr "type" "rotate")
11008 (set (attr "length_immediate")
11010 (and (match_operand 2 "const1_operand")
11011 (ior (match_test "TARGET_SHIFT1")
11012 (match_test "optimize_function_for_size_p (cfun)")))
11014 (const_string "*")))
11015 (set_attr "mode" "<MODE>")])
11017 (define_insn "*<rotate_insn>qi3_1_slp"
11018 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11019 (any_rotate:QI (match_dup 0)
11020 (match_operand:QI 1 "nonmemory_operand" "cI")))
11021 (clobber (reg:CC FLAGS_REG))]
11022 "(optimize_function_for_size_p (cfun)
11023 || !TARGET_PARTIAL_REG_STALL
11024 || (operands[1] == const1_rtx
11025 && TARGET_SHIFT1))"
11027 if (operands[1] == const1_rtx
11028 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11029 return "<rotate>{b}\t%0";
11031 return "<rotate>{b}\t{%1, %0|%0, %1}";
11033 [(set_attr "type" "rotate1")
11034 (set (attr "length_immediate")
11036 (and (match_operand 1 "const1_operand")
11037 (ior (match_test "TARGET_SHIFT1")
11038 (match_test "optimize_function_for_size_p (cfun)")))
11040 (const_string "*")))
11041 (set_attr "mode" "QI")])
11044 [(set (match_operand:HI 0 "register_operand")
11045 (any_rotate:HI (match_dup 0) (const_int 8)))
11046 (clobber (reg:CC FLAGS_REG))]
11048 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
11049 [(parallel [(set (strict_low_part (match_dup 0))
11050 (bswap:HI (match_dup 0)))
11051 (clobber (reg:CC FLAGS_REG))])])
11053 ;; Bit set / bit test instructions
11055 ;; %%% bts, btr, btc, bt.
11056 ;; In general these instructions are *slow* when applied to memory,
11057 ;; since they enforce atomic operation. When applied to registers,
11058 ;; it depends on the cpu implementation. They're never faster than
11059 ;; the corresponding and/ior/xor operations, so with 32-bit there's
11060 ;; no point. But in 64-bit, we can't hold the relevant immediates
11061 ;; within the instruction itself, so operating on bits in the high
11062 ;; 32-bits of a register becomes easier.
11064 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
11065 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
11066 ;; negdf respectively, so they can never be disabled entirely.
11068 (define_insn "*btsq"
11069 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
11071 (match_operand 1 "const_0_to_63_operand" "J"))
11073 (clobber (reg:CC FLAGS_REG))]
11074 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11075 "bts{q}\t{%1, %0|%0, %1}"
11076 [(set_attr "type" "alu1")
11077 (set_attr "prefix_0f" "1")
11078 (set_attr "znver1_decode" "double")
11079 (set_attr "mode" "DI")])
11081 (define_insn "*btrq"
11082 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
11084 (match_operand 1 "const_0_to_63_operand" "J"))
11086 (clobber (reg:CC FLAGS_REG))]
11087 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11088 "btr{q}\t{%1, %0|%0, %1}"
11089 [(set_attr "type" "alu1")
11090 (set_attr "prefix_0f" "1")
11091 (set_attr "znver1_decode" "double")
11092 (set_attr "mode" "DI")])
11094 (define_insn "*btcq"
11095 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
11097 (match_operand 1 "const_0_to_63_operand" "J"))
11098 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
11099 (clobber (reg:CC FLAGS_REG))]
11100 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11101 "btc{q}\t{%1, %0|%0, %1}"
11102 [(set_attr "type" "alu1")
11103 (set_attr "prefix_0f" "1")
11104 (set_attr "znver1_decode" "double")
11105 (set_attr "mode" "DI")])
11107 ;; Allow Nocona to avoid these instructions if a register is available.
11110 [(match_scratch:DI 2 "r")
11111 (parallel [(set (zero_extract:DI
11112 (match_operand:DI 0 "register_operand")
11114 (match_operand 1 "const_0_to_63_operand"))
11116 (clobber (reg:CC FLAGS_REG))])]
11117 "TARGET_64BIT && !TARGET_USE_BT"
11118 [(parallel [(set (match_dup 0)
11119 (ior:DI (match_dup 0) (match_dup 3)))
11120 (clobber (reg:CC FLAGS_REG))])]
11122 int i = INTVAL (operands[1]);
11124 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11126 if (!x86_64_immediate_operand (operands[3], DImode))
11128 emit_move_insn (operands[2], operands[3]);
11129 operands[3] = operands[2];
11134 [(match_scratch:DI 2 "r")
11135 (parallel [(set (zero_extract:DI
11136 (match_operand:DI 0 "register_operand")
11138 (match_operand 1 "const_0_to_63_operand"))
11140 (clobber (reg:CC FLAGS_REG))])]
11141 "TARGET_64BIT && !TARGET_USE_BT"
11142 [(parallel [(set (match_dup 0)
11143 (and:DI (match_dup 0) (match_dup 3)))
11144 (clobber (reg:CC FLAGS_REG))])]
11146 int i = INTVAL (operands[1]);
11148 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
11150 if (!x86_64_immediate_operand (operands[3], DImode))
11152 emit_move_insn (operands[2], operands[3]);
11153 operands[3] = operands[2];
11158 [(match_scratch:DI 2 "r")
11159 (parallel [(set (zero_extract:DI
11160 (match_operand:DI 0 "register_operand")
11162 (match_operand 1 "const_0_to_63_operand"))
11163 (not:DI (zero_extract:DI
11164 (match_dup 0) (const_int 1) (match_dup 1))))
11165 (clobber (reg:CC FLAGS_REG))])]
11166 "TARGET_64BIT && !TARGET_USE_BT"
11167 [(parallel [(set (match_dup 0)
11168 (xor:DI (match_dup 0) (match_dup 3)))
11169 (clobber (reg:CC FLAGS_REG))])]
11171 int i = INTVAL (operands[1]);
11173 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11175 if (!x86_64_immediate_operand (operands[3], DImode))
11177 emit_move_insn (operands[2], operands[3]);
11178 operands[3] = operands[2];
11182 (define_insn "*bt<mode>"
11183 [(set (reg:CCC FLAGS_REG)
11185 (zero_extract:SWI48
11186 (match_operand:SWI48 0 "register_operand" "r")
11188 (match_operand:SI 1 "nonmemory_operand" "rN"))
11192 switch (get_attr_mode (insn))
11195 return "bt{l}\t{%1, %k0|%k0, %1}";
11198 return "bt{q}\t{%q1, %0|%0, %q1}";
11201 gcc_unreachable ();
11204 [(set_attr "type" "alu1")
11205 (set_attr "prefix_0f" "1")
11208 (and (match_test "CONST_INT_P (operands[1])")
11209 (match_test "INTVAL (operands[1]) < 32"))
11210 (const_string "SI")
11211 (const_string "<MODE>")))])
11213 (define_insn_and_split "*jcc_bt<mode>"
11215 (if_then_else (match_operator 0 "bt_comparison_operator"
11216 [(zero_extract:SWI48
11217 (match_operand:SWI48 1 "register_operand")
11219 (match_operand:SI 2 "nonmemory_operand"))
11221 (label_ref (match_operand 3))
11223 (clobber (reg:CC FLAGS_REG))]
11224 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11225 && (CONST_INT_P (operands[2])
11226 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
11227 && INTVAL (operands[2])
11228 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
11229 : register_operand (operands[2], SImode))
11230 && can_create_pseudo_p ()"
11233 [(set (reg:CCC FLAGS_REG)
11235 (zero_extract:SWI48
11241 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11242 (label_ref (match_dup 3))
11245 operands[0] = shallow_copy_rtx (operands[0]);
11246 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11249 (define_insn_and_split "*jcc_bt<mode>_1"
11251 (if_then_else (match_operator 0 "bt_comparison_operator"
11252 [(zero_extract:SWI48
11253 (match_operand:SWI48 1 "register_operand")
11256 (match_operand:QI 2 "register_operand")))
11258 (label_ref (match_operand 3))
11260 (clobber (reg:CC FLAGS_REG))]
11261 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11262 && can_create_pseudo_p ()"
11265 [(set (reg:CCC FLAGS_REG)
11267 (zero_extract:SWI48
11273 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11274 (label_ref (match_dup 3))
11277 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
11278 operands[0] = shallow_copy_rtx (operands[0]);
11279 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11282 ;; Avoid useless masking of bit offset operand.
11283 (define_insn_and_split "*jcc_bt<mode>_mask"
11285 (if_then_else (match_operator 0 "bt_comparison_operator"
11286 [(zero_extract:SWI48
11287 (match_operand:SWI48 1 "register_operand")
11290 (match_operand:SI 2 "register_operand")
11291 (match_operand 3 "const_int_operand")))])
11292 (label_ref (match_operand 4))
11294 (clobber (reg:CC FLAGS_REG))]
11295 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11296 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11297 == GET_MODE_BITSIZE (<MODE>mode)-1
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 4))
11313 operands[0] = shallow_copy_rtx (operands[0]);
11314 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11317 ;; Store-flag instructions.
11319 ;; For all sCOND expanders, also expand the compare or test insn that
11320 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
11322 (define_insn_and_split "*setcc_di_1"
11323 [(set (match_operand:DI 0 "register_operand" "=q")
11324 (match_operator:DI 1 "ix86_comparison_operator"
11325 [(reg FLAGS_REG) (const_int 0)]))]
11326 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
11328 "&& reload_completed"
11329 [(set (match_dup 2) (match_dup 1))
11330 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
11332 operands[1] = shallow_copy_rtx (operands[1]);
11333 PUT_MODE (operands[1], QImode);
11334 operands[2] = gen_lowpart (QImode, operands[0]);
11337 (define_insn_and_split "*setcc_si_1_and"
11338 [(set (match_operand:SI 0 "register_operand" "=q")
11339 (match_operator:SI 1 "ix86_comparison_operator"
11340 [(reg FLAGS_REG) (const_int 0)]))
11341 (clobber (reg:CC FLAGS_REG))]
11342 "!TARGET_PARTIAL_REG_STALL
11343 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
11345 "&& reload_completed"
11346 [(set (match_dup 2) (match_dup 1))
11347 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
11348 (clobber (reg:CC FLAGS_REG))])]
11350 operands[1] = shallow_copy_rtx (operands[1]);
11351 PUT_MODE (operands[1], QImode);
11352 operands[2] = gen_lowpart (QImode, operands[0]);
11355 (define_insn_and_split "*setcc_si_1_movzbl"
11356 [(set (match_operand:SI 0 "register_operand" "=q")
11357 (match_operator:SI 1 "ix86_comparison_operator"
11358 [(reg FLAGS_REG) (const_int 0)]))]
11359 "!TARGET_PARTIAL_REG_STALL
11360 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
11362 "&& reload_completed"
11363 [(set (match_dup 2) (match_dup 1))
11364 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
11366 operands[1] = shallow_copy_rtx (operands[1]);
11367 PUT_MODE (operands[1], QImode);
11368 operands[2] = gen_lowpart (QImode, operands[0]);
11371 (define_insn "*setcc_qi"
11372 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11373 (match_operator:QI 1 "ix86_comparison_operator"
11374 [(reg FLAGS_REG) (const_int 0)]))]
11377 [(set_attr "type" "setcc")
11378 (set_attr "mode" "QI")])
11380 (define_insn "*setcc_qi_slp"
11381 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11382 (match_operator:QI 1 "ix86_comparison_operator"
11383 [(reg FLAGS_REG) (const_int 0)]))]
11386 [(set_attr "type" "setcc")
11387 (set_attr "mode" "QI")])
11389 ;; In general it is not safe to assume too much about CCmode registers,
11390 ;; so simplify-rtx stops when it sees a second one. Under certain
11391 ;; conditions this is safe on x86, so help combine not create
11398 [(set (match_operand:QI 0 "nonimmediate_operand")
11399 (ne:QI (match_operator 1 "ix86_comparison_operator"
11400 [(reg FLAGS_REG) (const_int 0)])
11403 [(set (match_dup 0) (match_dup 1))]
11405 operands[1] = shallow_copy_rtx (operands[1]);
11406 PUT_MODE (operands[1], QImode);
11410 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11411 (ne:QI (match_operator 1 "ix86_comparison_operator"
11412 [(reg FLAGS_REG) (const_int 0)])
11415 [(set (match_dup 0) (match_dup 1))]
11417 operands[1] = shallow_copy_rtx (operands[1]);
11418 PUT_MODE (operands[1], QImode);
11422 [(set (match_operand:QI 0 "nonimmediate_operand")
11423 (eq:QI (match_operator 1 "ix86_comparison_operator"
11424 [(reg FLAGS_REG) (const_int 0)])
11427 [(set (match_dup 0) (match_dup 1))]
11429 operands[1] = shallow_copy_rtx (operands[1]);
11430 PUT_MODE (operands[1], QImode);
11431 PUT_CODE (operands[1],
11432 ix86_reverse_condition (GET_CODE (operands[1]),
11433 GET_MODE (XEXP (operands[1], 0))));
11435 /* Make sure that (a) the CCmode we have for the flags is strong
11436 enough for the reversed compare or (b) we have a valid FP compare. */
11437 if (! ix86_comparison_operator (operands[1], VOIDmode))
11442 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11443 (eq:QI (match_operator 1 "ix86_comparison_operator"
11444 [(reg FLAGS_REG) (const_int 0)])
11447 [(set (match_dup 0) (match_dup 1))]
11449 operands[1] = shallow_copy_rtx (operands[1]);
11450 PUT_MODE (operands[1], QImode);
11451 PUT_CODE (operands[1],
11452 ix86_reverse_condition (GET_CODE (operands[1]),
11453 GET_MODE (XEXP (operands[1], 0))));
11455 /* Make sure that (a) the CCmode we have for the flags is strong
11456 enough for the reversed compare or (b) we have a valid FP compare. */
11457 if (! ix86_comparison_operator (operands[1], VOIDmode))
11461 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
11462 ;; subsequent logical operations are used to imitate conditional moves.
11463 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
11466 (define_insn "setcc_<mode>_sse"
11467 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
11468 (match_operator:MODEF 3 "sse_comparison_operator"
11469 [(match_operand:MODEF 1 "register_operand" "0,x")
11470 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
11471 "SSE_FLOAT_MODE_P (<MODE>mode)"
11473 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
11474 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
11475 [(set_attr "isa" "noavx,avx")
11476 (set_attr "type" "ssecmp")
11477 (set_attr "length_immediate" "1")
11478 (set_attr "prefix" "orig,vex")
11479 (set_attr "mode" "<MODE>")])
11481 ;; Basic conditional jump instructions.
11482 ;; We ignore the overflow flag for signed branch instructions.
11484 (define_insn "*jcc_1"
11486 (if_then_else (match_operator 1 "ix86_comparison_operator"
11487 [(reg FLAGS_REG) (const_int 0)])
11488 (label_ref (match_operand 0))
11492 [(set_attr "type" "ibr")
11493 (set_attr "modrm" "0")
11494 (set (attr "length")
11496 (and (ge (minus (match_dup 0) (pc))
11498 (lt (minus (match_dup 0) (pc))
11502 (set_attr "maybe_prefix_bnd" "1")])
11504 (define_insn "*jcc_2"
11506 (if_then_else (match_operator 1 "ix86_comparison_operator"
11507 [(reg FLAGS_REG) (const_int 0)])
11509 (label_ref (match_operand 0))))]
11512 [(set_attr "type" "ibr")
11513 (set_attr "modrm" "0")
11514 (set (attr "length")
11516 (and (ge (minus (match_dup 0) (pc))
11518 (lt (minus (match_dup 0) (pc))
11522 (set_attr "maybe_prefix_bnd" "1")])
11524 ;; In general it is not safe to assume too much about CCmode registers,
11525 ;; so simplify-rtx stops when it sees a second one. Under certain
11526 ;; conditions this is safe on x86, so help combine not create
11534 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11535 [(reg FLAGS_REG) (const_int 0)])
11537 (label_ref (match_operand 1))
11541 (if_then_else (match_dup 0)
11542 (label_ref (match_dup 1))
11545 operands[0] = shallow_copy_rtx (operands[0]);
11546 PUT_MODE (operands[0], VOIDmode);
11551 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11552 [(reg FLAGS_REG) (const_int 0)])
11554 (label_ref (match_operand 1))
11558 (if_then_else (match_dup 0)
11559 (label_ref (match_dup 1))
11562 operands[0] = shallow_copy_rtx (operands[0]);
11563 PUT_MODE (operands[0], VOIDmode);
11564 PUT_CODE (operands[0],
11565 ix86_reverse_condition (GET_CODE (operands[0]),
11566 GET_MODE (XEXP (operands[0], 0))));
11568 /* Make sure that (a) the CCmode we have for the flags is strong
11569 enough for the reversed compare or (b) we have a valid FP compare. */
11570 if (! ix86_comparison_operator (operands[0], VOIDmode))
11574 ;; Define combination compare-and-branch fp compare instructions to help
11577 (define_insn "*jcc<mode>_0_i387"
11579 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11580 [(match_operand:X87MODEF 1 "register_operand" "f")
11581 (match_operand:X87MODEF 2 "const0_operand")])
11582 (label_ref (match_operand 3))
11584 (clobber (reg:CCFP FPSR_REG))
11585 (clobber (reg:CCFP FLAGS_REG))
11586 (clobber (match_scratch:HI 4 "=a"))]
11587 "TARGET_80387 && !TARGET_CMOVE"
11590 (define_insn "*jcc<mode>_0_r_i387"
11592 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11593 [(match_operand:X87MODEF 1 "register_operand" "f")
11594 (match_operand:X87MODEF 2 "const0_operand")])
11596 (label_ref (match_operand 3))))
11597 (clobber (reg:CCFP FPSR_REG))
11598 (clobber (reg:CCFP FLAGS_REG))
11599 (clobber (match_scratch:HI 4 "=a"))]
11600 "TARGET_80387 && !TARGET_CMOVE"
11603 (define_insn "*jccxf_i387"
11605 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11606 [(match_operand:XF 1 "register_operand" "f")
11607 (match_operand:XF 2 "register_operand" "f")])
11608 (label_ref (match_operand 3))
11610 (clobber (reg:CCFP FPSR_REG))
11611 (clobber (reg:CCFP FLAGS_REG))
11612 (clobber (match_scratch:HI 4 "=a"))]
11613 "TARGET_80387 && !TARGET_CMOVE"
11616 (define_insn "*jccxf_r_i387"
11618 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11619 [(match_operand:XF 1 "register_operand" "f")
11620 (match_operand:XF 2 "register_operand" "f")])
11622 (label_ref (match_operand 3))))
11623 (clobber (reg:CCFP FPSR_REG))
11624 (clobber (reg:CCFP FLAGS_REG))
11625 (clobber (match_scratch:HI 4 "=a"))]
11626 "TARGET_80387 && !TARGET_CMOVE"
11629 (define_insn "*jcc<mode>_i387"
11631 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11632 [(match_operand:MODEF 1 "register_operand" "f")
11633 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11634 (label_ref (match_operand 3))
11636 (clobber (reg:CCFP FPSR_REG))
11637 (clobber (reg:CCFP FLAGS_REG))
11638 (clobber (match_scratch:HI 4 "=a"))]
11639 "TARGET_80387 && !TARGET_CMOVE"
11642 (define_insn "*jcc<mode>_r_i387"
11644 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11645 [(match_operand:MODEF 1 "register_operand" "f")
11646 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11648 (label_ref (match_operand 3))))
11649 (clobber (reg:CCFP FPSR_REG))
11650 (clobber (reg:CCFP FLAGS_REG))
11651 (clobber (match_scratch:HI 4 "=a"))]
11652 "TARGET_80387 && !TARGET_CMOVE"
11655 (define_insn "*jccu<mode>_i387"
11657 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11658 [(match_operand:X87MODEF 1 "register_operand" "f")
11659 (match_operand:X87MODEF 2 "register_operand" "f")])
11660 (label_ref (match_operand 3))
11662 (clobber (reg:CCFP FPSR_REG))
11663 (clobber (reg:CCFP FLAGS_REG))
11664 (clobber (match_scratch:HI 4 "=a"))]
11665 "TARGET_80387 && !TARGET_CMOVE"
11668 (define_insn "*jccu<mode>_r_i387"
11670 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11671 [(match_operand:X87MODEF 1 "register_operand" "f")
11672 (match_operand:X87MODEF 2 "register_operand" "f")])
11674 (label_ref (match_operand 3))))
11675 (clobber (reg:CCFP FPSR_REG))
11676 (clobber (reg:CCFP FLAGS_REG))
11677 (clobber (match_scratch:HI 4 "=a"))]
11678 "TARGET_80387 && !TARGET_CMOVE"
11683 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11684 [(match_operand:X87MODEF 1 "register_operand")
11685 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11687 (match_operand 4)))
11688 (clobber (reg:CCFP FPSR_REG))
11689 (clobber (reg:CCFP FLAGS_REG))]
11690 "TARGET_80387 && !TARGET_CMOVE
11691 && reload_completed"
11694 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11695 operands[3], operands[4], NULL_RTX);
11701 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11702 [(match_operand:X87MODEF 1 "register_operand")
11703 (match_operand:X87MODEF 2 "general_operand")])
11705 (match_operand 4)))
11706 (clobber (reg:CCFP FPSR_REG))
11707 (clobber (reg:CCFP FLAGS_REG))
11708 (clobber (match_scratch:HI 5))]
11709 "TARGET_80387 && !TARGET_CMOVE
11710 && reload_completed"
11713 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11714 operands[3], operands[4], operands[5]);
11718 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11719 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11720 ;; with a precedence over other operators and is always put in the first
11721 ;; place. Swap condition and operands to match ficom instruction.
11723 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11726 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11727 [(match_operator:X87MODEF 1 "float_operator"
11728 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11729 (match_operand:X87MODEF 3 "register_operand" "f")])
11730 (label_ref (match_operand 4))
11732 (clobber (reg:CCFP FPSR_REG))
11733 (clobber (reg:CCFP FLAGS_REG))
11734 (clobber (match_scratch:HI 5 "=a"))]
11735 "TARGET_80387 && !TARGET_CMOVE
11736 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11737 || optimize_function_for_size_p (cfun))"
11740 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11743 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11744 [(match_operator:X87MODEF 1 "float_operator"
11745 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11746 (match_operand:X87MODEF 3 "register_operand" "f")])
11748 (label_ref (match_operand 4))))
11749 (clobber (reg:CCFP FPSR_REG))
11750 (clobber (reg:CCFP FLAGS_REG))
11751 (clobber (match_scratch:HI 5 "=a"))]
11752 "TARGET_80387 && !TARGET_CMOVE
11753 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11754 || optimize_function_for_size_p (cfun))"
11760 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11761 [(match_operator:X87MODEF 1 "float_operator"
11762 [(match_operand:SWI24 2 "memory_operand")])
11763 (match_operand:X87MODEF 3 "register_operand")])
11765 (match_operand 5)))
11766 (clobber (reg:CCFP FPSR_REG))
11767 (clobber (reg:CCFP FLAGS_REG))
11768 (clobber (match_scratch:HI 6))]
11769 "TARGET_80387 && !TARGET_CMOVE
11770 && reload_completed"
11773 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11774 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11775 operands[4], operands[5], operands[6]);
11779 ;; Unconditional and other jump instructions
11781 (define_insn "jump"
11783 (label_ref (match_operand 0)))]
11786 [(set_attr "type" "ibr")
11787 (set_attr "modrm" "0")
11788 (set (attr "length")
11790 (and (ge (minus (match_dup 0) (pc))
11792 (lt (minus (match_dup 0) (pc))
11796 (set_attr "maybe_prefix_bnd" "1")])
11798 (define_expand "indirect_jump"
11799 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11803 operands[0] = convert_memory_address (word_mode, operands[0]);
11806 (define_insn "*indirect_jump"
11807 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11810 [(set_attr "type" "ibr")
11811 (set_attr "length_immediate" "0")
11812 (set_attr "maybe_prefix_bnd" "1")])
11814 (define_expand "tablejump"
11815 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11816 (use (label_ref (match_operand 1)))])]
11819 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11820 relative. Convert the relative address to an absolute address. */
11824 enum rtx_code code;
11826 /* We can't use @GOTOFF for text labels on VxWorks;
11827 see gotoff_operand. */
11828 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11832 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11834 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11838 op1 = pic_offset_table_rtx;
11843 op0 = pic_offset_table_rtx;
11847 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11852 operands[0] = convert_memory_address (word_mode, operands[0]);
11855 (define_insn "*tablejump_1"
11856 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11857 (use (label_ref (match_operand 1)))]
11860 [(set_attr "type" "ibr")
11861 (set_attr "length_immediate" "0")
11862 (set_attr "maybe_prefix_bnd" "1")])
11864 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11867 [(set (reg FLAGS_REG) (match_operand 0))
11868 (set (match_operand:QI 1 "register_operand")
11869 (match_operator:QI 2 "ix86_comparison_operator"
11870 [(reg FLAGS_REG) (const_int 0)]))
11871 (set (match_operand 3 "any_QIreg_operand")
11872 (zero_extend (match_dup 1)))]
11873 "(peep2_reg_dead_p (3, operands[1])
11874 || operands_match_p (operands[1], operands[3]))
11875 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11876 [(set (match_dup 4) (match_dup 0))
11877 (set (strict_low_part (match_dup 5))
11880 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11881 operands[5] = gen_lowpart (QImode, operands[3]);
11882 ix86_expand_clear (operands[3]);
11886 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11887 (match_operand 4)])
11888 (set (match_operand:QI 1 "register_operand")
11889 (match_operator:QI 2 "ix86_comparison_operator"
11890 [(reg FLAGS_REG) (const_int 0)]))
11891 (set (match_operand 3 "any_QIreg_operand")
11892 (zero_extend (match_dup 1)))]
11893 "(peep2_reg_dead_p (3, operands[1])
11894 || operands_match_p (operands[1], operands[3]))
11895 && ! reg_overlap_mentioned_p (operands[3], operands[0])
11896 && ! reg_set_p (operands[3], operands[4])"
11897 [(parallel [(set (match_dup 5) (match_dup 0))
11899 (set (strict_low_part (match_dup 6))
11902 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11903 operands[6] = gen_lowpart (QImode, operands[3]);
11904 ix86_expand_clear (operands[3]);
11907 ;; Similar, but match zero extend with andsi3.
11910 [(set (reg FLAGS_REG) (match_operand 0))
11911 (set (match_operand:QI 1 "register_operand")
11912 (match_operator:QI 2 "ix86_comparison_operator"
11913 [(reg FLAGS_REG) (const_int 0)]))
11914 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
11915 (and:SI (match_dup 3) (const_int 255)))
11916 (clobber (reg:CC FLAGS_REG))])]
11917 "REGNO (operands[1]) == REGNO (operands[3])
11918 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11919 [(set (match_dup 4) (match_dup 0))
11920 (set (strict_low_part (match_dup 5))
11923 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11924 operands[5] = gen_lowpart (QImode, operands[3]);
11925 ix86_expand_clear (operands[3]);
11929 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11930 (match_operand 4)])
11931 (set (match_operand:QI 1 "register_operand")
11932 (match_operator:QI 2 "ix86_comparison_operator"
11933 [(reg FLAGS_REG) (const_int 0)]))
11934 (parallel [(set (match_operand 3 "any_QIreg_operand")
11935 (zero_extend (match_dup 1)))
11936 (clobber (reg:CC FLAGS_REG))])]
11937 "(peep2_reg_dead_p (3, operands[1])
11938 || operands_match_p (operands[1], operands[3]))
11939 && ! reg_overlap_mentioned_p (operands[3], operands[0])
11940 && ! reg_set_p (operands[3], operands[4])"
11941 [(parallel [(set (match_dup 5) (match_dup 0))
11943 (set (strict_low_part (match_dup 6))
11946 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11947 operands[6] = gen_lowpart (QImode, operands[3]);
11948 ix86_expand_clear (operands[3]);
11951 ;; Call instructions.
11953 ;; The predicates normally associated with named expanders are not properly
11954 ;; checked for calls. This is a bug in the generic code, but it isn't that
11955 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11957 ;; P6 processors will jump to the address after the decrement when %esp
11958 ;; is used as a call operand, so they will execute return address as a code.
11959 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11961 ;; Register constraint for call instruction.
11962 (define_mode_attr c [(SI "l") (DI "r")])
11964 ;; Call subroutine returning no value.
11966 (define_expand "call"
11967 [(call (match_operand:QI 0)
11969 (use (match_operand 2))]
11972 ix86_expand_call (NULL, operands[0], operands[1],
11973 operands[2], NULL, false);
11977 (define_expand "sibcall"
11978 [(call (match_operand:QI 0)
11980 (use (match_operand 2))]
11983 ix86_expand_call (NULL, operands[0], operands[1],
11984 operands[2], NULL, true);
11988 (define_insn "*call"
11989 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11990 (match_operand 1))]
11991 "!SIBLING_CALL_P (insn)"
11992 "* return ix86_output_call_insn (insn, operands[0]);"
11993 [(set_attr "type" "call")])
11995 ;; This covers both call and sibcall since only GOT slot is allowed.
11996 (define_insn "*call_got_x32"
11997 [(call (mem:QI (zero_extend:DI
11998 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
11999 (match_operand 1))]
12002 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
12003 return ix86_output_call_insn (insn, fnaddr);
12005 [(set_attr "type" "call")])
12007 ;; Since sibcall never returns, we can only use call-clobbered register
12009 (define_insn "*sibcall_GOT_32"
12012 (match_operand:SI 0 "register_no_elim_operand" "U")
12013 (match_operand:SI 1 "GOT32_symbol_operand"))))
12014 (match_operand 2))]
12015 "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
12017 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
12018 fnaddr = gen_const_mem (SImode, fnaddr);
12019 return ix86_output_call_insn (insn, fnaddr);
12021 [(set_attr "type" "call")])
12023 (define_insn "*sibcall"
12024 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
12025 (match_operand 1))]
12026 "SIBLING_CALL_P (insn)"
12027 "* return ix86_output_call_insn (insn, operands[0]);"
12028 [(set_attr "type" "call")])
12030 (define_insn "*sibcall_memory"
12031 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
12033 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12035 "* return ix86_output_call_insn (insn, operands[0]);"
12036 [(set_attr "type" "call")])
12039 [(set (match_operand:W 0 "register_operand")
12040 (match_operand:W 1 "memory_operand"))
12041 (call (mem:QI (match_dup 0))
12042 (match_operand 3))]
12043 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
12044 && !reg_mentioned_p (operands[0],
12045 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12046 [(parallel [(call (mem:QI (match_dup 1))
12048 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12051 [(set (match_operand:W 0 "register_operand")
12052 (match_operand:W 1 "memory_operand"))
12053 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12054 (call (mem:QI (match_dup 0))
12055 (match_operand 3))]
12056 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
12057 && !reg_mentioned_p (operands[0],
12058 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12059 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12060 (parallel [(call (mem:QI (match_dup 1))
12062 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12064 (define_expand "call_pop"
12065 [(parallel [(call (match_operand:QI 0)
12066 (match_operand:SI 1))
12067 (set (reg:SI SP_REG)
12068 (plus:SI (reg:SI SP_REG)
12069 (match_operand:SI 3)))])]
12072 ix86_expand_call (NULL, operands[0], operands[1],
12073 operands[2], operands[3], false);
12077 (define_insn "*call_pop"
12078 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
12080 (set (reg:SI SP_REG)
12081 (plus:SI (reg:SI SP_REG)
12082 (match_operand:SI 2 "immediate_operand" "i")))]
12083 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12084 "* return ix86_output_call_insn (insn, operands[0]);"
12085 [(set_attr "type" "call")])
12087 (define_insn "*sibcall_pop"
12088 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
12090 (set (reg:SI SP_REG)
12091 (plus:SI (reg:SI SP_REG)
12092 (match_operand:SI 2 "immediate_operand" "i")))]
12093 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12094 "* return ix86_output_call_insn (insn, operands[0]);"
12095 [(set_attr "type" "call")])
12097 (define_insn "*sibcall_pop_memory"
12098 [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
12100 (set (reg:SI SP_REG)
12101 (plus:SI (reg:SI SP_REG)
12102 (match_operand:SI 2 "immediate_operand" "i")))
12103 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12105 "* return ix86_output_call_insn (insn, operands[0]);"
12106 [(set_attr "type" "call")])
12109 [(set (match_operand:SI 0 "register_operand")
12110 (match_operand:SI 1 "memory_operand"))
12111 (parallel [(call (mem:QI (match_dup 0))
12113 (set (reg:SI SP_REG)
12114 (plus:SI (reg:SI SP_REG)
12115 (match_operand:SI 4 "immediate_operand")))])]
12116 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12117 && !reg_mentioned_p (operands[0],
12118 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12119 [(parallel [(call (mem:QI (match_dup 1))
12121 (set (reg:SI SP_REG)
12122 (plus:SI (reg:SI SP_REG)
12124 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12127 [(set (match_operand:SI 0 "register_operand")
12128 (match_operand:SI 1 "memory_operand"))
12129 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12130 (parallel [(call (mem:QI (match_dup 0))
12132 (set (reg:SI SP_REG)
12133 (plus:SI (reg:SI SP_REG)
12134 (match_operand:SI 4 "immediate_operand")))])]
12135 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12136 && !reg_mentioned_p (operands[0],
12137 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12138 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12139 (parallel [(call (mem:QI (match_dup 1))
12141 (set (reg:SI SP_REG)
12142 (plus:SI (reg:SI SP_REG)
12144 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12146 ;; Combining simple memory jump instruction
12149 [(set (match_operand:W 0 "register_operand")
12150 (match_operand:W 1 "memory_operand"))
12151 (set (pc) (match_dup 0))]
12152 "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
12153 [(set (pc) (match_dup 1))])
12155 ;; Call subroutine, returning value in operand 0
12157 (define_expand "call_value"
12158 [(set (match_operand 0)
12159 (call (match_operand:QI 1)
12160 (match_operand 2)))
12161 (use (match_operand 3))]
12164 ix86_expand_call (operands[0], operands[1], operands[2],
12165 operands[3], NULL, false);
12169 (define_expand "sibcall_value"
12170 [(set (match_operand 0)
12171 (call (match_operand:QI 1)
12172 (match_operand 2)))
12173 (use (match_operand 3))]
12176 ix86_expand_call (operands[0], operands[1], operands[2],
12177 operands[3], NULL, true);
12181 (define_insn "*call_value"
12182 [(set (match_operand 0)
12183 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
12184 (match_operand 2)))]
12185 "!SIBLING_CALL_P (insn)"
12186 "* return ix86_output_call_insn (insn, operands[1]);"
12187 [(set_attr "type" "callv")])
12189 ;; This covers both call and sibcall since only GOT slot is allowed.
12190 (define_insn "*call_value_got_x32"
12191 [(set (match_operand 0)
12194 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
12195 (match_operand 2)))]
12198 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
12199 return ix86_output_call_insn (insn, fnaddr);
12201 [(set_attr "type" "callv")])
12203 ;; Since sibcall never returns, we can only use call-clobbered register
12205 (define_insn "*sibcall_value_GOT_32"
12206 [(set (match_operand 0)
12209 (match_operand:SI 1 "register_no_elim_operand" "U")
12210 (match_operand:SI 2 "GOT32_symbol_operand"))))
12211 (match_operand 3)))]
12212 "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
12214 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
12215 fnaddr = gen_const_mem (SImode, fnaddr);
12216 return ix86_output_call_insn (insn, fnaddr);
12218 [(set_attr "type" "callv")])
12220 (define_insn "*sibcall_value"
12221 [(set (match_operand 0)
12222 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
12223 (match_operand 2)))]
12224 "SIBLING_CALL_P (insn)"
12225 "* return ix86_output_call_insn (insn, operands[1]);"
12226 [(set_attr "type" "callv")])
12228 (define_insn "*sibcall_value_memory"
12229 [(set (match_operand 0)
12230 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
12231 (match_operand 2)))
12232 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12234 "* return ix86_output_call_insn (insn, operands[1]);"
12235 [(set_attr "type" "callv")])
12238 [(set (match_operand:W 0 "register_operand")
12239 (match_operand:W 1 "memory_operand"))
12240 (set (match_operand 2)
12241 (call (mem:QI (match_dup 0))
12242 (match_operand 3)))]
12243 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
12244 && !reg_mentioned_p (operands[0],
12245 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12246 [(parallel [(set (match_dup 2)
12247 (call (mem:QI (match_dup 1))
12249 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12252 [(set (match_operand:W 0 "register_operand")
12253 (match_operand:W 1 "memory_operand"))
12254 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12255 (set (match_operand 2)
12256 (call (mem:QI (match_dup 0))
12257 (match_operand 3)))]
12258 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
12259 && !reg_mentioned_p (operands[0],
12260 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12261 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12262 (parallel [(set (match_dup 2)
12263 (call (mem:QI (match_dup 1))
12265 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12267 (define_expand "call_value_pop"
12268 [(parallel [(set (match_operand 0)
12269 (call (match_operand:QI 1)
12270 (match_operand:SI 2)))
12271 (set (reg:SI SP_REG)
12272 (plus:SI (reg:SI SP_REG)
12273 (match_operand:SI 4)))])]
12276 ix86_expand_call (operands[0], operands[1], operands[2],
12277 operands[3], operands[4], false);
12281 (define_insn "*call_value_pop"
12282 [(set (match_operand 0)
12283 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
12284 (match_operand 2)))
12285 (set (reg:SI SP_REG)
12286 (plus:SI (reg:SI SP_REG)
12287 (match_operand:SI 3 "immediate_operand" "i")))]
12288 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12289 "* return ix86_output_call_insn (insn, operands[1]);"
12290 [(set_attr "type" "callv")])
12292 (define_insn "*sibcall_value_pop"
12293 [(set (match_operand 0)
12294 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
12295 (match_operand 2)))
12296 (set (reg:SI SP_REG)
12297 (plus:SI (reg:SI SP_REG)
12298 (match_operand:SI 3 "immediate_operand" "i")))]
12299 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12300 "* return ix86_output_call_insn (insn, operands[1]);"
12301 [(set_attr "type" "callv")])
12303 (define_insn "*sibcall_value_pop_memory"
12304 [(set (match_operand 0)
12305 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
12306 (match_operand 2)))
12307 (set (reg:SI SP_REG)
12308 (plus:SI (reg:SI SP_REG)
12309 (match_operand:SI 3 "immediate_operand" "i")))
12310 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12312 "* return ix86_output_call_insn (insn, operands[1]);"
12313 [(set_attr "type" "callv")])
12316 [(set (match_operand:SI 0 "register_operand")
12317 (match_operand:SI 1 "memory_operand"))
12318 (parallel [(set (match_operand 2)
12319 (call (mem:QI (match_dup 0))
12320 (match_operand 3)))
12321 (set (reg:SI SP_REG)
12322 (plus:SI (reg:SI SP_REG)
12323 (match_operand:SI 4 "immediate_operand")))])]
12324 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12325 && !reg_mentioned_p (operands[0],
12326 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12327 [(parallel [(set (match_dup 2)
12328 (call (mem:QI (match_dup 1))
12330 (set (reg:SI SP_REG)
12331 (plus:SI (reg:SI SP_REG)
12333 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12336 [(set (match_operand:SI 0 "register_operand")
12337 (match_operand:SI 1 "memory_operand"))
12338 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12339 (parallel [(set (match_operand 2)
12340 (call (mem:QI (match_dup 0))
12341 (match_operand 3)))
12342 (set (reg:SI SP_REG)
12343 (plus:SI (reg:SI SP_REG)
12344 (match_operand:SI 4 "immediate_operand")))])]
12345 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12346 && !reg_mentioned_p (operands[0],
12347 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12348 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12349 (parallel [(set (match_dup 2)
12350 (call (mem:QI (match_dup 1))
12352 (set (reg:SI SP_REG)
12353 (plus:SI (reg:SI SP_REG)
12355 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12357 ;; Call subroutine returning any type.
12359 (define_expand "untyped_call"
12360 [(parallel [(call (match_operand 0)
12363 (match_operand 2)])]
12368 /* In order to give reg-stack an easier job in validating two
12369 coprocessor registers as containing a possible return value,
12370 simply pretend the untyped call returns a complex long double
12373 We can't use SSE_REGPARM_MAX here since callee is unprototyped
12374 and should have the default ABI. */
12376 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12377 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12378 operands[0], const0_rtx,
12379 GEN_INT ((TARGET_64BIT
12380 ? (ix86_abi == SYSV_ABI
12381 ? X86_64_SSE_REGPARM_MAX
12382 : X86_64_MS_SSE_REGPARM_MAX)
12383 : X86_32_SSE_REGPARM_MAX)
12387 for (i = 0; i < XVECLEN (operands[2], 0); i++)
12389 rtx set = XVECEXP (operands[2], 0, i);
12390 emit_move_insn (SET_DEST (set), SET_SRC (set));
12393 /* The optimizer does not know that the call sets the function value
12394 registers we stored in the result block. We avoid problems by
12395 claiming that all hard registers are used and clobbered at this
12397 emit_insn (gen_blockage ());
12402 ;; Prologue and epilogue instructions
12404 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12405 ;; all of memory. This blocks insns from being moved across this point.
12407 (define_insn "blockage"
12408 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12411 [(set_attr "length" "0")])
12413 ;; Do not schedule instructions accessing memory across this point.
12415 (define_expand "memory_blockage"
12416 [(set (match_dup 0)
12417 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12420 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12421 MEM_VOLATILE_P (operands[0]) = 1;
12424 (define_insn "*memory_blockage"
12425 [(set (match_operand:BLK 0)
12426 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12429 [(set_attr "length" "0")])
12431 ;; As USE insns aren't meaningful after reload, this is used instead
12432 ;; to prevent deleting instructions setting registers for PIC code
12433 (define_insn "prologue_use"
12434 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12437 [(set_attr "length" "0")])
12439 ;; Insn emitted into the body of a function to return from a function.
12440 ;; This is only done if the function's epilogue is known to be simple.
12441 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12443 (define_expand "return"
12445 "ix86_can_use_return_insn_p ()"
12447 if (crtl->args.pops_args)
12449 rtx popc = GEN_INT (crtl->args.pops_args);
12450 emit_jump_insn (gen_simple_return_pop_internal (popc));
12455 ;; We need to disable this for TARGET_SEH, as otherwise
12456 ;; shrink-wrapped prologue gets enabled too. This might exceed
12457 ;; the maximum size of prologue in unwind information.
12458 ;; Also disallow shrink-wrapping if using stack slot to pass the
12459 ;; static chain pointer - the first instruction has to be pushl %esi
12460 ;; and it can't be moved around, as we use alternate entry points
12463 (define_expand "simple_return"
12465 "!TARGET_SEH && !ix86_static_chain_on_stack"
12467 if (crtl->args.pops_args)
12469 rtx popc = GEN_INT (crtl->args.pops_args);
12470 emit_jump_insn (gen_simple_return_pop_internal (popc));
12475 (define_insn "simple_return_internal"
12479 [(set_attr "length" "1")
12480 (set_attr "atom_unit" "jeu")
12481 (set_attr "length_immediate" "0")
12482 (set_attr "modrm" "0")
12483 (set_attr "maybe_prefix_bnd" "1")])
12485 (define_insn "interrupt_return"
12487 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
12490 return TARGET_64BIT ? "iretq" : "iret";
12493 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12494 ;; instruction Athlon and K8 have.
12496 (define_insn "simple_return_internal_long"
12498 (unspec [(const_int 0)] UNSPEC_REP)]
12501 if (ix86_bnd_prefixed_insn_p (insn))
12504 return "rep%; ret";
12506 [(set_attr "length" "2")
12507 (set_attr "atom_unit" "jeu")
12508 (set_attr "length_immediate" "0")
12509 (set_attr "prefix_rep" "1")
12510 (set_attr "modrm" "0")])
12512 (define_insn "simple_return_pop_internal"
12514 (use (match_operand:SI 0 "const_int_operand"))]
12517 [(set_attr "length" "3")
12518 (set_attr "atom_unit" "jeu")
12519 (set_attr "length_immediate" "2")
12520 (set_attr "modrm" "0")
12521 (set_attr "maybe_prefix_bnd" "1")])
12523 (define_insn "simple_return_indirect_internal"
12525 (use (match_operand:SI 0 "register_operand" "r"))]
12528 [(set_attr "type" "ibr")
12529 (set_attr "length_immediate" "0")
12530 (set_attr "maybe_prefix_bnd" "1")])
12536 [(set_attr "length" "1")
12537 (set_attr "length_immediate" "0")
12538 (set_attr "modrm" "0")])
12540 ;; Generate nops. Operand 0 is the number of nops, up to 8.
12541 (define_insn "nops"
12542 [(unspec_volatile [(match_operand 0 "const_int_operand")]
12546 int num = INTVAL (operands[0]);
12548 gcc_assert (IN_RANGE (num, 1, 8));
12551 fputs ("\tnop\n", asm_out_file);
12555 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12556 (set_attr "length_immediate" "0")
12557 (set_attr "modrm" "0")])
12559 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12560 ;; branch prediction penalty for the third jump in a 16-byte
12564 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12567 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12568 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12570 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12571 The align insn is used to avoid 3 jump instructions in the row to improve
12572 branch prediction and the benefits hardly outweigh the cost of extra 8
12573 nops on the average inserted by full alignment pseudo operation. */
12577 [(set_attr "length" "16")])
12579 (define_expand "prologue"
12582 "ix86_expand_prologue (); DONE;")
12584 (define_expand "set_got"
12586 [(set (match_operand:SI 0 "register_operand")
12587 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12588 (clobber (reg:CC FLAGS_REG))])]
12591 if (flag_pic && !TARGET_VXWORKS_RTP)
12592 ix86_pc_thunk_call_expanded = true;
12595 (define_insn "*set_got"
12596 [(set (match_operand:SI 0 "register_operand" "=r")
12597 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12598 (clobber (reg:CC FLAGS_REG))]
12600 "* return output_set_got (operands[0], NULL_RTX);"
12601 [(set_attr "type" "multi")
12602 (set_attr "length" "12")])
12604 (define_expand "set_got_labelled"
12606 [(set (match_operand:SI 0 "register_operand")
12607 (unspec:SI [(label_ref (match_operand 1))]
12609 (clobber (reg:CC FLAGS_REG))])]
12612 if (flag_pic && !TARGET_VXWORKS_RTP)
12613 ix86_pc_thunk_call_expanded = true;
12616 (define_insn "*set_got_labelled"
12617 [(set (match_operand:SI 0 "register_operand" "=r")
12618 (unspec:SI [(label_ref (match_operand 1))]
12620 (clobber (reg:CC FLAGS_REG))]
12622 "* return output_set_got (operands[0], operands[1]);"
12623 [(set_attr "type" "multi")
12624 (set_attr "length" "12")])
12626 (define_insn "set_got_rex64"
12627 [(set (match_operand:DI 0 "register_operand" "=r")
12628 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12630 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12631 [(set_attr "type" "lea")
12632 (set_attr "length_address" "4")
12633 (set_attr "modrm_class" "unknown")
12634 (set_attr "mode" "DI")])
12636 (define_insn "set_rip_rex64"
12637 [(set (match_operand:DI 0 "register_operand" "=r")
12638 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12640 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12641 [(set_attr "type" "lea")
12642 (set_attr "length_address" "4")
12643 (set_attr "mode" "DI")])
12645 (define_insn "set_got_offset_rex64"
12646 [(set (match_operand:DI 0 "register_operand" "=r")
12648 [(label_ref (match_operand 1))]
12649 UNSPEC_SET_GOT_OFFSET))]
12651 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12652 [(set_attr "type" "imov")
12653 (set_attr "length_immediate" "0")
12654 (set_attr "length_address" "8")
12655 (set_attr "mode" "DI")])
12657 (define_expand "epilogue"
12660 "ix86_expand_epilogue (1); DONE;")
12662 (define_expand "sibcall_epilogue"
12665 "ix86_expand_epilogue (0); DONE;")
12667 (define_expand "eh_return"
12668 [(use (match_operand 0 "register_operand"))]
12671 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12673 /* Tricky bit: we write the address of the handler to which we will
12674 be returning into someone else's stack frame, one word below the
12675 stack address we wish to restore. */
12676 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12677 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12678 tmp = gen_rtx_MEM (Pmode, tmp);
12679 emit_move_insn (tmp, ra);
12681 emit_jump_insn (gen_eh_return_internal ());
12686 (define_insn_and_split "eh_return_internal"
12690 "epilogue_completed"
12692 "ix86_expand_epilogue (2); DONE;")
12694 (define_insn "leave"
12695 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12696 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12697 (clobber (mem:BLK (scratch)))]
12700 [(set_attr "type" "leave")])
12702 (define_insn "leave_rex64"
12703 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12704 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12705 (clobber (mem:BLK (scratch)))]
12708 [(set_attr "type" "leave")])
12710 ;; Handle -fsplit-stack.
12712 (define_expand "split_stack_prologue"
12716 ix86_expand_split_stack_prologue ();
12720 ;; In order to support the call/return predictor, we use a return
12721 ;; instruction which the middle-end doesn't see.
12722 (define_insn "split_stack_return"
12723 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12724 UNSPECV_SPLIT_STACK_RETURN)]
12727 if (operands[0] == const0_rtx)
12732 [(set_attr "atom_unit" "jeu")
12733 (set_attr "modrm" "0")
12734 (set (attr "length")
12735 (if_then_else (match_operand:SI 0 "const0_operand")
12738 (set (attr "length_immediate")
12739 (if_then_else (match_operand:SI 0 "const0_operand")
12743 ;; If there are operand 0 bytes available on the stack, jump to
12746 (define_expand "split_stack_space_check"
12747 [(set (pc) (if_then_else
12748 (ltu (minus (reg SP_REG)
12749 (match_operand 0 "register_operand"))
12750 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12751 (label_ref (match_operand 1))
12755 rtx reg, size, limit;
12757 reg = gen_reg_rtx (Pmode);
12758 size = force_reg (Pmode, operands[0]);
12759 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12760 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12761 UNSPEC_STACK_CHECK);
12762 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12763 ix86_expand_branch (GEU, reg, limit, operands[1]);
12768 ;; Bit manipulation instructions.
12770 (define_expand "ffs<mode>2"
12771 [(set (match_dup 2) (const_int -1))
12772 (parallel [(set (match_dup 3) (match_dup 4))
12773 (set (match_operand:SWI48 0 "register_operand")
12775 (match_operand:SWI48 1 "nonimmediate_operand")))])
12776 (set (match_dup 0) (if_then_else:SWI48
12777 (eq (match_dup 3) (const_int 0))
12780 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12781 (clobber (reg:CC FLAGS_REG))])]
12784 machine_mode flags_mode;
12786 if (<MODE>mode == SImode && !TARGET_CMOVE)
12788 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12793 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12795 operands[2] = gen_reg_rtx (<MODE>mode);
12796 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12797 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12800 (define_insn_and_split "ffssi2_no_cmove"
12801 [(set (match_operand:SI 0 "register_operand" "=r")
12802 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12803 (clobber (match_scratch:SI 2 "=&q"))
12804 (clobber (reg:CC FLAGS_REG))]
12807 "&& reload_completed"
12808 [(parallel [(set (match_dup 4) (match_dup 5))
12809 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12810 (set (strict_low_part (match_dup 3))
12811 (eq:QI (match_dup 4) (const_int 0)))
12812 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12813 (clobber (reg:CC FLAGS_REG))])
12814 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12815 (clobber (reg:CC FLAGS_REG))])
12816 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12817 (clobber (reg:CC FLAGS_REG))])]
12819 machine_mode flags_mode
12820 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12822 operands[3] = gen_lowpart (QImode, operands[2]);
12823 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12824 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12826 ix86_expand_clear (operands[2]);
12829 (define_insn "*tzcnt<mode>_1"
12830 [(set (reg:CCC FLAGS_REG)
12831 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12833 (set (match_operand:SWI48 0 "register_operand" "=r")
12834 (ctz:SWI48 (match_dup 1)))]
12835 "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
12836 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12837 [(set_attr "type" "alu1")
12838 (set_attr "prefix_0f" "1")
12839 (set_attr "prefix_rep" "1")
12840 (set_attr "btver2_decode" "double")
12841 (set_attr "mode" "<MODE>")])
12843 (define_insn "*bsf<mode>_1"
12844 [(set (reg:CCZ FLAGS_REG)
12845 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12847 (set (match_operand:SWI48 0 "register_operand" "=r")
12848 (ctz:SWI48 (match_dup 1)))]
12850 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12851 [(set_attr "type" "alu1")
12852 (set_attr "prefix_0f" "1")
12853 (set_attr "btver2_decode" "double")
12854 (set_attr "znver1_decode" "vector")
12855 (set_attr "mode" "<MODE>")])
12857 (define_expand "ctz<mode>2"
12859 [(set (match_operand:SWI48 0 "register_operand")
12861 (match_operand:SWI48 1 "nonimmediate_operand")))
12862 (clobber (reg:CC FLAGS_REG))])])
12864 ; False dependency happens when destination is only updated by tzcnt,
12865 ; lzcnt or popcnt. There is no false dependency when destination is
12866 ; also used in source.
12867 (define_insn_and_split "*ctz<mode>2_falsedep_1"
12868 [(set (match_operand:SWI48 0 "register_operand" "=r")
12870 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12871 (clobber (reg:CC FLAGS_REG))]
12872 "(TARGET_BMI || TARGET_GENERIC)
12873 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12875 "&& reload_completed"
12877 [(set (match_dup 0)
12878 (ctz:SWI48 (match_dup 1)))
12879 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12880 (clobber (reg:CC FLAGS_REG))])]
12882 if (!reg_mentioned_p (operands[0], operands[1]))
12883 ix86_expand_clear (operands[0]);
12886 (define_insn "*ctz<mode>2_falsedep"
12887 [(set (match_operand:SWI48 0 "register_operand" "=r")
12889 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12890 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12891 UNSPEC_INSN_FALSE_DEP)
12892 (clobber (reg:CC FLAGS_REG))]
12896 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12897 else if (TARGET_GENERIC)
12898 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12899 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12901 gcc_unreachable ();
12903 [(set_attr "type" "alu1")
12904 (set_attr "prefix_0f" "1")
12905 (set_attr "prefix_rep" "1")
12906 (set_attr "mode" "<MODE>")])
12908 (define_insn "*ctz<mode>2"
12909 [(set (match_operand:SWI48 0 "register_operand" "=r")
12910 (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12911 (clobber (reg:CC FLAGS_REG))]
12915 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12916 else if (optimize_function_for_size_p (cfun))
12918 else if (TARGET_GENERIC)
12919 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12920 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12922 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12924 [(set_attr "type" "alu1")
12925 (set_attr "prefix_0f" "1")
12926 (set (attr "prefix_rep")
12928 (ior (match_test "TARGET_BMI")
12929 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12930 (match_test "TARGET_GENERIC")))
12932 (const_string "0")))
12933 (set_attr "mode" "<MODE>")])
12935 ;; Version of tzcnt that is expanded from intrinsics. This version provides
12936 ;; operand size as output when source operand is zero.
12938 (define_expand "bmi_tzcnt_<mode>"
12940 [(set (match_operand:SWI248 0 "register_operand")
12942 [(match_operand:SWI248 1 "nonimmediate_operand")]
12944 (clobber (reg:CC FLAGS_REG))])]
12947 ; False dependency happens when destination is only updated by tzcnt,
12948 ; lzcnt or popcnt. There is no false dependency when destination is
12949 ; also used in source.
12950 (define_insn_and_split "*bmi_tzcnt_<mode>_falsedep_1"
12951 [(set (match_operand:SWI48 0 "register_operand" "=r")
12953 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")]
12955 (clobber (reg:CC FLAGS_REG))]
12957 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12959 "&& reload_completed"
12961 [(set (match_dup 0)
12962 (unspec:SWI48 [(match_dup 1)] UNSPEC_TZCNT))
12963 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12964 (clobber (reg:CC FLAGS_REG))])]
12966 if (!reg_mentioned_p (operands[0], operands[1]))
12967 ix86_expand_clear (operands[0]);
12970 (define_insn "*bmi_tzcnt_<mode>_falsedep"
12971 [(set (match_operand:SWI48 0 "register_operand" "=r")
12973 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")]
12975 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12976 UNSPEC_INSN_FALSE_DEP)
12977 (clobber (reg:CC FLAGS_REG))]
12979 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12980 [(set_attr "type" "alu1")
12981 (set_attr "prefix_0f" "1")
12982 (set_attr "prefix_rep" "1")
12983 (set_attr "mode" "<MODE>")])
12985 (define_insn "*bmi_tzcnt_<mode>"
12986 [(set (match_operand:SWI248 0 "register_operand" "=r")
12988 [(match_operand:SWI248 1 "nonimmediate_operand" "rm")]
12990 (clobber (reg:CC FLAGS_REG))]
12992 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12993 [(set_attr "type" "alu1")
12994 (set_attr "prefix_0f" "1")
12995 (set_attr "prefix_rep" "1")
12996 (set_attr "mode" "<MODE>")])
12998 (define_expand "clz<mode>2"
13000 [(set (match_operand:SWI48 0 "register_operand")
13003 (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
13004 (clobber (reg:CC FLAGS_REG))])
13006 [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
13007 (clobber (reg:CC FLAGS_REG))])]
13012 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
13015 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
13018 (define_expand "clz<mode>2_lzcnt"
13020 [(set (match_operand:SWI48 0 "register_operand")
13022 (match_operand:SWI48 1 "nonimmediate_operand")))
13023 (clobber (reg:CC FLAGS_REG))])]
13026 (define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
13027 [(set (match_operand:SWI48 0 "register_operand" "=r")
13029 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13030 (clobber (reg:CC FLAGS_REG))]
13032 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
13034 "&& reload_completed"
13036 [(set (match_dup 0)
13037 (clz:SWI48 (match_dup 1)))
13038 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13039 (clobber (reg:CC FLAGS_REG))])]
13041 if (!reg_mentioned_p (operands[0], operands[1]))
13042 ix86_expand_clear (operands[0]);
13045 (define_insn "*clz<mode>2_lzcnt_falsedep"
13046 [(set (match_operand:SWI48 0 "register_operand" "=r")
13048 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13049 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13050 UNSPEC_INSN_FALSE_DEP)
13051 (clobber (reg:CC FLAGS_REG))]
13053 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13054 [(set_attr "prefix_rep" "1")
13055 (set_attr "type" "bitmanip")
13056 (set_attr "mode" "<MODE>")])
13058 (define_insn "*clz<mode>2_lzcnt"
13059 [(set (match_operand:SWI48 0 "register_operand" "=r")
13060 (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13061 (clobber (reg:CC FLAGS_REG))]
13063 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13064 [(set_attr "prefix_rep" "1")
13065 (set_attr "type" "bitmanip")
13066 (set_attr "mode" "<MODE>")])
13068 ;; Version of lzcnt that is expanded from intrinsics. This version provides
13069 ;; operand size as output when source operand is zero.
13071 (define_expand "lzcnt_<mode>"
13073 [(set (match_operand:SWI248 0 "register_operand")
13075 [(match_operand:SWI248 1 "nonimmediate_operand")]
13077 (clobber (reg:CC FLAGS_REG))])]
13080 ; False dependency happens when destination is only updated by tzcnt,
13081 ; lzcnt or popcnt. There is no false dependency when destination is
13082 ; also used in source.
13083 (define_insn_and_split "*lzcnt_<mode>_falsedep_1"
13084 [(set (match_operand:SWI48 0 "register_operand" "=r")
13086 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")]
13088 (clobber (reg:CC FLAGS_REG))]
13090 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
13092 "&& reload_completed"
13094 [(set (match_dup 0)
13095 (unspec:SWI48 [(match_dup 1)] UNSPEC_LZCNT))
13096 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13097 (clobber (reg:CC FLAGS_REG))])]
13099 if (!reg_mentioned_p (operands[0], operands[1]))
13100 ix86_expand_clear (operands[0]);
13103 (define_insn "*lzcnt_<mode>_falsedep"
13104 [(set (match_operand:SWI48 0 "register_operand" "=r")
13106 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")]
13108 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13109 UNSPEC_INSN_FALSE_DEP)
13110 (clobber (reg:CC FLAGS_REG))]
13112 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13113 [(set_attr "type" "alu1")
13114 (set_attr "prefix_0f" "1")
13115 (set_attr "prefix_rep" "1")
13116 (set_attr "mode" "<MODE>")])
13118 (define_insn "*lzcnt_<mode>"
13119 [(set (match_operand:SWI248 0 "register_operand" "=r")
13121 [(match_operand:SWI248 1 "nonimmediate_operand" "rm")]
13123 (clobber (reg:CC FLAGS_REG))]
13125 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13126 [(set_attr "type" "alu1")
13127 (set_attr "prefix_0f" "1")
13128 (set_attr "prefix_rep" "1")
13129 (set_attr "mode" "<MODE>")])
13131 ;; BMI instructions.
13132 (define_insn "*bmi_andn_<mode>"
13133 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
13135 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
13136 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
13137 (clobber (reg:CC FLAGS_REG))]
13139 "andn\t{%2, %1, %0|%0, %1, %2}"
13140 [(set_attr "type" "bitmanip")
13141 (set_attr "btver2_decode" "direct, double")
13142 (set_attr "mode" "<MODE>")])
13144 (define_insn "*bmi_andn_<mode>_ccno"
13145 [(set (reg FLAGS_REG)
13148 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
13149 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
13151 (clobber (match_scratch:SWI48 0 "=r,r"))]
13152 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
13153 "andn\t{%2, %1, %0|%0, %1, %2}"
13154 [(set_attr "type" "bitmanip")
13155 (set_attr "btver2_decode" "direct, double")
13156 (set_attr "mode" "<MODE>")])
13158 (define_insn "bmi_bextr_<mode>"
13159 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
13160 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13161 (match_operand:SWI48 2 "register_operand" "r,r")]
13163 (clobber (reg:CC FLAGS_REG))]
13165 "bextr\t{%2, %1, %0|%0, %1, %2}"
13166 [(set_attr "type" "bitmanip")
13167 (set_attr "btver2_decode" "direct, double")
13168 (set_attr "mode" "<MODE>")])
13170 (define_insn "*bmi_bextr_<mode>_ccz"
13171 [(set (reg:CCZ FLAGS_REG)
13173 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13174 (match_operand:SWI48 2 "register_operand" "r,r")]
13177 (clobber (match_scratch:SWI48 0 "=r,r"))]
13179 "bextr\t{%2, %1, %0|%0, %1, %2}"
13180 [(set_attr "type" "bitmanip")
13181 (set_attr "btver2_decode" "direct, double")
13182 (set_attr "mode" "<MODE>")])
13184 (define_insn "*bmi_blsi_<mode>"
13185 [(set (match_operand:SWI48 0 "register_operand" "=r")
13188 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
13190 (clobber (reg:CC FLAGS_REG))]
13192 "blsi\t{%1, %0|%0, %1}"
13193 [(set_attr "type" "bitmanip")
13194 (set_attr "btver2_decode" "double")
13195 (set_attr "mode" "<MODE>")])
13197 (define_insn "*bmi_blsmsk_<mode>"
13198 [(set (match_operand:SWI48 0 "register_operand" "=r")
13201 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13204 (clobber (reg:CC FLAGS_REG))]
13206 "blsmsk\t{%1, %0|%0, %1}"
13207 [(set_attr "type" "bitmanip")
13208 (set_attr "btver2_decode" "double")
13209 (set_attr "mode" "<MODE>")])
13211 (define_insn "*bmi_blsr_<mode>"
13212 [(set (match_operand:SWI48 0 "register_operand" "=r")
13215 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13218 (clobber (reg:CC FLAGS_REG))]
13220 "blsr\t{%1, %0|%0, %1}"
13221 [(set_attr "type" "bitmanip")
13222 (set_attr "btver2_decode" "double")
13223 (set_attr "mode" "<MODE>")])
13225 ;; BMI2 instructions.
13226 (define_expand "bmi2_bzhi_<mode>3"
13228 [(set (match_operand:SWI48 0 "register_operand")
13229 (zero_extract:SWI48
13230 (match_operand:SWI48 1 "nonimmediate_operand")
13232 (and:SWI48 (match_operand:SWI48 2 "register_operand")
13236 (clobber (reg:CC FLAGS_REG))])]
13238 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
13240 (define_insn "*bmi2_bzhi_<mode>3"
13241 [(set (match_operand:SWI48 0 "register_operand" "=r")
13242 (zero_extract:SWI48
13243 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13245 (and:SWI48 (match_operand:SWI48 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{%2, %1, %0|%0, %1, %2}"
13252 [(set_attr "type" "bitmanip")
13253 (set_attr "prefix" "vex")
13254 (set_attr "mode" "<MODE>")])
13256 (define_mode_attr k [(SI "k") (DI "q")])
13258 (define_insn "*bmi2_bzhi_<mode>3_1"
13259 [(set (match_operand:SWI48 0 "register_operand" "=r")
13260 (zero_extract:SWI48
13261 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13263 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13264 (match_operand:SWI48 3 "const_int_operand" "n"))
13266 (clobber (reg:CC FLAGS_REG))]
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_bzhi_<mode>3_1_ccz"
13274 [(set (reg:CCZ FLAGS_REG)
13276 (zero_extract:SWI48
13277 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13279 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13280 (match_operand:SWI48 3 "const_int_operand" "n"))
13283 (clobber (match_scratch:SWI48 0 "=r"))]
13284 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13285 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13286 [(set_attr "type" "bitmanip")
13287 (set_attr "prefix" "vex")
13288 (set_attr "mode" "<MODE>")])
13290 (define_insn "bmi2_pdep_<mode>3"
13291 [(set (match_operand:SWI48 0 "register_operand" "=r")
13292 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13293 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13296 "pdep\t{%2, %1, %0|%0, %1, %2}"
13297 [(set_attr "type" "bitmanip")
13298 (set_attr "prefix" "vex")
13299 (set_attr "mode" "<MODE>")])
13301 (define_insn "bmi2_pext_<mode>3"
13302 [(set (match_operand:SWI48 0 "register_operand" "=r")
13303 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13304 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13307 "pext\t{%2, %1, %0|%0, %1, %2}"
13308 [(set_attr "type" "bitmanip")
13309 (set_attr "prefix" "vex")
13310 (set_attr "mode" "<MODE>")])
13312 ;; TBM instructions.
13313 (define_insn "tbm_bextri_<mode>"
13314 [(set (match_operand:SWI48 0 "register_operand" "=r")
13315 (zero_extract:SWI48
13316 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13317 (match_operand 2 "const_0_to_255_operand" "N")
13318 (match_operand 3 "const_0_to_255_operand" "N")))
13319 (clobber (reg:CC FLAGS_REG))]
13322 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
13323 return "bextr\t{%2, %1, %0|%0, %1, %2}";
13325 [(set_attr "type" "bitmanip")
13326 (set_attr "mode" "<MODE>")])
13328 (define_insn "*tbm_blcfill_<mode>"
13329 [(set (match_operand:SWI48 0 "register_operand" "=r")
13332 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13335 (clobber (reg:CC FLAGS_REG))]
13337 "blcfill\t{%1, %0|%0, %1}"
13338 [(set_attr "type" "bitmanip")
13339 (set_attr "mode" "<MODE>")])
13341 (define_insn "*tbm_blci_<mode>"
13342 [(set (match_operand:SWI48 0 "register_operand" "=r")
13346 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13349 (clobber (reg:CC FLAGS_REG))]
13351 "blci\t{%1, %0|%0, %1}"
13352 [(set_attr "type" "bitmanip")
13353 (set_attr "mode" "<MODE>")])
13355 (define_insn "*tbm_blcic_<mode>"
13356 [(set (match_operand:SWI48 0 "register_operand" "=r")
13359 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13363 (clobber (reg:CC FLAGS_REG))]
13365 "blcic\t{%1, %0|%0, %1}"
13366 [(set_attr "type" "bitmanip")
13367 (set_attr "mode" "<MODE>")])
13369 (define_insn "*tbm_blcmsk_<mode>"
13370 [(set (match_operand:SWI48 0 "register_operand" "=r")
13373 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13376 (clobber (reg:CC FLAGS_REG))]
13378 "blcmsk\t{%1, %0|%0, %1}"
13379 [(set_attr "type" "bitmanip")
13380 (set_attr "mode" "<MODE>")])
13382 (define_insn "*tbm_blcs_<mode>"
13383 [(set (match_operand:SWI48 0 "register_operand" "=r")
13386 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13389 (clobber (reg:CC FLAGS_REG))]
13391 "blcs\t{%1, %0|%0, %1}"
13392 [(set_attr "type" "bitmanip")
13393 (set_attr "mode" "<MODE>")])
13395 (define_insn "*tbm_blsfill_<mode>"
13396 [(set (match_operand:SWI48 0 "register_operand" "=r")
13399 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13402 (clobber (reg:CC FLAGS_REG))]
13404 "blsfill\t{%1, %0|%0, %1}"
13405 [(set_attr "type" "bitmanip")
13406 (set_attr "mode" "<MODE>")])
13408 (define_insn "*tbm_blsic_<mode>"
13409 [(set (match_operand:SWI48 0 "register_operand" "=r")
13412 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13416 (clobber (reg:CC FLAGS_REG))]
13418 "blsic\t{%1, %0|%0, %1}"
13419 [(set_attr "type" "bitmanip")
13420 (set_attr "mode" "<MODE>")])
13422 (define_insn "*tbm_t1mskc_<mode>"
13423 [(set (match_operand:SWI48 0 "register_operand" "=r")
13426 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13430 (clobber (reg:CC FLAGS_REG))]
13432 "t1mskc\t{%1, %0|%0, %1}"
13433 [(set_attr "type" "bitmanip")
13434 (set_attr "mode" "<MODE>")])
13436 (define_insn "*tbm_tzmsk_<mode>"
13437 [(set (match_operand:SWI48 0 "register_operand" "=r")
13440 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13444 (clobber (reg:CC FLAGS_REG))]
13446 "tzmsk\t{%1, %0|%0, %1}"
13447 [(set_attr "type" "bitmanip")
13448 (set_attr "mode" "<MODE>")])
13450 (define_insn "bsr_rex64"
13451 [(set (match_operand:DI 0 "register_operand" "=r")
13452 (minus:DI (const_int 63)
13453 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13454 (clobber (reg:CC FLAGS_REG))]
13456 "bsr{q}\t{%1, %0|%0, %1}"
13457 [(set_attr "type" "alu1")
13458 (set_attr "prefix_0f" "1")
13459 (set_attr "znver1_decode" "vector")
13460 (set_attr "mode" "DI")])
13463 [(set (match_operand:SI 0 "register_operand" "=r")
13464 (minus:SI (const_int 31)
13465 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13466 (clobber (reg:CC FLAGS_REG))]
13468 "bsr{l}\t{%1, %0|%0, %1}"
13469 [(set_attr "type" "alu1")
13470 (set_attr "prefix_0f" "1")
13471 (set_attr "znver1_decode" "vector")
13472 (set_attr "mode" "SI")])
13474 (define_insn "*bsrhi"
13475 [(set (match_operand:HI 0 "register_operand" "=r")
13476 (minus:HI (const_int 15)
13477 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13478 (clobber (reg:CC FLAGS_REG))]
13480 "bsr{w}\t{%1, %0|%0, %1}"
13481 [(set_attr "type" "alu1")
13482 (set_attr "prefix_0f" "1")
13483 (set_attr "znver1_decode" "vector")
13484 (set_attr "mode" "HI")])
13486 (define_expand "popcount<mode>2"
13488 [(set (match_operand:SWI248 0 "register_operand")
13490 (match_operand:SWI248 1 "nonimmediate_operand")))
13491 (clobber (reg:CC FLAGS_REG))])]
13494 (define_insn_and_split "*popcount<mode>2_falsedep_1"
13495 [(set (match_operand:SWI48 0 "register_operand" "=r")
13497 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13498 (clobber (reg:CC FLAGS_REG))]
13500 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
13502 "&& reload_completed"
13504 [(set (match_dup 0)
13505 (popcount:SWI48 (match_dup 1)))
13506 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13507 (clobber (reg:CC FLAGS_REG))])]
13509 if (!reg_mentioned_p (operands[0], operands[1]))
13510 ix86_expand_clear (operands[0]);
13513 (define_insn "*popcount<mode>2_falsedep"
13514 [(set (match_operand:SWI48 0 "register_operand" "=r")
13516 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13517 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13518 UNSPEC_INSN_FALSE_DEP)
13519 (clobber (reg:CC FLAGS_REG))]
13523 return "popcnt\t{%1, %0|%0, %1}";
13525 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13528 [(set_attr "prefix_rep" "1")
13529 (set_attr "type" "bitmanip")
13530 (set_attr "mode" "<MODE>")])
13532 (define_insn "*popcount<mode>2"
13533 [(set (match_operand:SWI248 0 "register_operand" "=r")
13535 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
13536 (clobber (reg:CC FLAGS_REG))]
13540 return "popcnt\t{%1, %0|%0, %1}";
13542 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13545 [(set_attr "prefix_rep" "1")
13546 (set_attr "type" "bitmanip")
13547 (set_attr "mode" "<MODE>")])
13549 (define_expand "bswapdi2"
13550 [(set (match_operand:DI 0 "register_operand")
13551 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
13555 operands[1] = force_reg (DImode, operands[1]);
13558 (define_expand "bswapsi2"
13559 [(set (match_operand:SI 0 "register_operand")
13560 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
13565 else if (TARGET_BSWAP)
13566 operands[1] = force_reg (SImode, operands[1]);
13569 rtx x = operands[0];
13571 emit_move_insn (x, operands[1]);
13572 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13573 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
13574 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13579 (define_insn "*bswap<mode>2_movbe"
13580 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
13581 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
13583 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13586 movbe\t{%1, %0|%0, %1}
13587 movbe\t{%1, %0|%0, %1}"
13588 [(set_attr "type" "bitmanip,imov,imov")
13589 (set_attr "modrm" "0,1,1")
13590 (set_attr "prefix_0f" "*,1,1")
13591 (set_attr "prefix_extra" "*,1,1")
13592 (set_attr "mode" "<MODE>")])
13594 (define_insn "*bswap<mode>2"
13595 [(set (match_operand:SWI48 0 "register_operand" "=r")
13596 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
13599 [(set_attr "type" "bitmanip")
13600 (set_attr "modrm" "0")
13601 (set_attr "mode" "<MODE>")])
13603 (define_insn "*bswaphi_lowpart_1"
13604 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
13605 (bswap:HI (match_dup 0)))
13606 (clobber (reg:CC FLAGS_REG))]
13607 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
13609 xchg{b}\t{%h0, %b0|%b0, %h0}
13610 rol{w}\t{$8, %0|%0, 8}"
13611 [(set_attr "length" "2,4")
13612 (set_attr "mode" "QI,HI")])
13614 (define_insn "bswaphi_lowpart"
13615 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
13616 (bswap:HI (match_dup 0)))
13617 (clobber (reg:CC FLAGS_REG))]
13619 "rol{w}\t{$8, %0|%0, 8}"
13620 [(set_attr "length" "4")
13621 (set_attr "mode" "HI")])
13623 (define_expand "paritydi2"
13624 [(set (match_operand:DI 0 "register_operand")
13625 (parity:DI (match_operand:DI 1 "register_operand")))]
13628 rtx scratch = gen_reg_rtx (QImode);
13630 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
13631 NULL_RTX, operands[1]));
13633 ix86_expand_setcc (scratch, ORDERED,
13634 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
13637 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
13640 rtx tmp = gen_reg_rtx (SImode);
13642 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
13643 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
13648 (define_expand "paritysi2"
13649 [(set (match_operand:SI 0 "register_operand")
13650 (parity:SI (match_operand:SI 1 "register_operand")))]
13653 rtx scratch = gen_reg_rtx (QImode);
13655 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
13657 ix86_expand_setcc (scratch, ORDERED,
13658 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
13660 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
13664 (define_insn_and_split "paritydi2_cmp"
13665 [(set (reg:CC FLAGS_REG)
13666 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
13668 (clobber (match_scratch:DI 0 "=r"))
13669 (clobber (match_scratch:SI 1 "=&r"))
13670 (clobber (match_scratch:HI 2 "=Q"))]
13673 "&& reload_completed"
13675 [(set (match_dup 1)
13676 (xor:SI (match_dup 1) (match_dup 4)))
13677 (clobber (reg:CC FLAGS_REG))])
13679 [(set (reg:CC FLAGS_REG)
13680 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13681 (clobber (match_dup 1))
13682 (clobber (match_dup 2))])]
13684 operands[4] = gen_lowpart (SImode, operands[3]);
13688 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
13689 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
13692 operands[1] = gen_highpart (SImode, operands[3]);
13695 (define_insn_and_split "paritysi2_cmp"
13696 [(set (reg:CC FLAGS_REG)
13697 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
13699 (clobber (match_scratch:SI 0 "=r"))
13700 (clobber (match_scratch:HI 1 "=&Q"))]
13703 "&& reload_completed"
13705 [(set (match_dup 1)
13706 (xor:HI (match_dup 1) (match_dup 3)))
13707 (clobber (reg:CC FLAGS_REG))])
13709 [(set (reg:CC FLAGS_REG)
13710 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13711 (clobber (match_dup 1))])]
13713 operands[3] = gen_lowpart (HImode, operands[2]);
13715 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
13716 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
13719 (define_insn "*parityhi2_cmp"
13720 [(set (reg:CC FLAGS_REG)
13721 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
13723 (clobber (match_scratch:HI 0 "=Q"))]
13725 "xor{b}\t{%h0, %b0|%b0, %h0}"
13726 [(set_attr "length" "2")
13727 (set_attr "mode" "HI")])
13730 ;; Thread-local storage patterns for ELF.
13732 ;; Note that these code sequences must appear exactly as shown
13733 ;; in order to allow linker relaxation.
13735 (define_insn "*tls_global_dynamic_32_gnu"
13736 [(set (match_operand:SI 0 "register_operand" "=a")
13738 [(match_operand:SI 1 "register_operand" "Yb")
13739 (match_operand 2 "tls_symbolic_operand")
13740 (match_operand 3 "constant_call_address_operand" "Bz")
13743 (clobber (match_scratch:SI 4 "=d"))
13744 (clobber (match_scratch:SI 5 "=c"))
13745 (clobber (reg:CC FLAGS_REG))]
13746 "!TARGET_64BIT && TARGET_GNU_TLS"
13748 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13750 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
13753 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
13754 if (TARGET_SUN_TLS)
13755 #ifdef HAVE_AS_IX86_TLSGDPLT
13756 return "call\t%a2@tlsgdplt";
13758 return "call\t%p3@plt";
13760 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13761 return "call\t%P3";
13762 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
13764 [(set_attr "type" "multi")
13765 (set_attr "length" "12")])
13767 (define_expand "tls_global_dynamic_32"
13769 [(set (match_operand:SI 0 "register_operand")
13770 (unspec:SI [(match_operand:SI 2 "register_operand")
13771 (match_operand 1 "tls_symbolic_operand")
13772 (match_operand 3 "constant_call_address_operand")
13775 (clobber (match_scratch:SI 4))
13776 (clobber (match_scratch:SI 5))
13777 (clobber (reg:CC FLAGS_REG))])]
13779 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13781 (define_insn "*tls_global_dynamic_64_<mode>"
13782 [(set (match_operand:P 0 "register_operand" "=a")
13784 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
13785 (match_operand 3)))
13786 (unspec:P [(match_operand 1 "tls_symbolic_operand")
13792 fputs (ASM_BYTE "0x66\n", asm_out_file);
13794 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13795 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13796 fputs (ASM_SHORT "0x6666\n", asm_out_file);
13798 fputs (ASM_BYTE "0x66\n", asm_out_file);
13799 fputs ("\trex64\n", asm_out_file);
13800 if (TARGET_SUN_TLS)
13801 return "call\t%p2@plt";
13802 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13803 return "call\t%P2";
13804 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
13806 [(set_attr "type" "multi")
13807 (set (attr "length")
13808 (symbol_ref "TARGET_X32 ? 15 : 16"))])
13810 (define_insn "*tls_global_dynamic_64_largepic"
13811 [(set (match_operand:DI 0 "register_operand" "=a")
13813 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
13814 (match_operand:DI 3 "immediate_operand" "i")))
13815 (match_operand 4)))
13816 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13819 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13820 && GET_CODE (operands[3]) == CONST
13821 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13822 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13825 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13826 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13827 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13828 return "call\t{*%%rax|rax}";
13830 [(set_attr "type" "multi")
13831 (set_attr "length" "22")])
13833 (define_expand "tls_global_dynamic_64_<mode>"
13835 [(set (match_operand:P 0 "register_operand")
13837 (mem:QI (match_operand 2))
13839 (unspec:P [(match_operand 1 "tls_symbolic_operand")
13843 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13845 (define_insn "*tls_local_dynamic_base_32_gnu"
13846 [(set (match_operand:SI 0 "register_operand" "=a")
13848 [(match_operand:SI 1 "register_operand" "Yb")
13849 (match_operand 2 "constant_call_address_operand" "Bz")
13851 UNSPEC_TLS_LD_BASE))
13852 (clobber (match_scratch:SI 3 "=d"))
13853 (clobber (match_scratch:SI 4 "=c"))
13854 (clobber (reg:CC FLAGS_REG))]
13855 "!TARGET_64BIT && TARGET_GNU_TLS"
13858 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13859 if (TARGET_SUN_TLS)
13861 if (HAVE_AS_IX86_TLSLDMPLT)
13862 return "call\t%&@tlsldmplt";
13864 return "call\t%p2@plt";
13866 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13867 return "call\t%P2";
13868 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
13870 [(set_attr "type" "multi")
13871 (set_attr "length" "11")])
13873 (define_expand "tls_local_dynamic_base_32"
13875 [(set (match_operand:SI 0 "register_operand")
13877 [(match_operand:SI 1 "register_operand")
13878 (match_operand 2 "constant_call_address_operand")
13880 UNSPEC_TLS_LD_BASE))
13881 (clobber (match_scratch:SI 3))
13882 (clobber (match_scratch:SI 4))
13883 (clobber (reg:CC FLAGS_REG))])]
13885 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13887 (define_insn "*tls_local_dynamic_base_64_<mode>"
13888 [(set (match_operand:P 0 "register_operand" "=a")
13890 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13891 (match_operand 2)))
13892 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
13896 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13897 if (TARGET_SUN_TLS)
13898 return "call\t%p1@plt";
13899 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13900 return "call\t%P1";
13901 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
13903 [(set_attr "type" "multi")
13904 (set_attr "length" "12")])
13906 (define_insn "*tls_local_dynamic_base_64_largepic"
13907 [(set (match_operand:DI 0 "register_operand" "=a")
13909 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13910 (match_operand:DI 2 "immediate_operand" "i")))
13911 (match_operand 3)))
13912 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
13913 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13914 && GET_CODE (operands[2]) == CONST
13915 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13916 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13919 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13920 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13921 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13922 return "call\t{*%%rax|rax}";
13924 [(set_attr "type" "multi")
13925 (set_attr "length" "22")])
13927 (define_expand "tls_local_dynamic_base_64_<mode>"
13929 [(set (match_operand:P 0 "register_operand")
13931 (mem:QI (match_operand 1))
13933 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
13935 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13937 ;; Local dynamic of a single variable is a lose. Show combine how
13938 ;; to convert that back to global dynamic.
13940 (define_insn_and_split "*tls_local_dynamic_32_once"
13941 [(set (match_operand:SI 0 "register_operand" "=a")
13943 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13944 (match_operand 2 "constant_call_address_operand" "Bz")
13946 UNSPEC_TLS_LD_BASE)
13947 (const:SI (unspec:SI
13948 [(match_operand 3 "tls_symbolic_operand")]
13950 (clobber (match_scratch:SI 4 "=d"))
13951 (clobber (match_scratch:SI 5 "=c"))
13952 (clobber (reg:CC FLAGS_REG))]
13957 [(set (match_dup 0)
13958 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13961 (clobber (match_dup 4))
13962 (clobber (match_dup 5))
13963 (clobber (reg:CC FLAGS_REG))])])
13965 ;; Segment register for the thread base ptr load
13966 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13968 ;; Load and add the thread base pointer from %<tp_seg>:0.
13969 (define_insn "*load_tp_x32"
13970 [(set (match_operand:SI 0 "register_operand" "=r")
13971 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13973 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13974 [(set_attr "type" "imov")
13975 (set_attr "modrm" "0")
13976 (set_attr "length" "7")
13977 (set_attr "memory" "load")
13978 (set_attr "imm_disp" "false")])
13980 (define_insn "*load_tp_x32_zext"
13981 [(set (match_operand:DI 0 "register_operand" "=r")
13982 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13984 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13985 [(set_attr "type" "imov")
13986 (set_attr "modrm" "0")
13987 (set_attr "length" "7")
13988 (set_attr "memory" "load")
13989 (set_attr "imm_disp" "false")])
13991 (define_insn "*load_tp_<mode>"
13992 [(set (match_operand:P 0 "register_operand" "=r")
13993 (unspec:P [(const_int 0)] UNSPEC_TP))]
13995 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13996 [(set_attr "type" "imov")
13997 (set_attr "modrm" "0")
13998 (set_attr "length" "7")
13999 (set_attr "memory" "load")
14000 (set_attr "imm_disp" "false")])
14002 (define_insn "*add_tp_x32"
14003 [(set (match_operand:SI 0 "register_operand" "=r")
14004 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14005 (match_operand:SI 1 "register_operand" "0")))
14006 (clobber (reg:CC FLAGS_REG))]
14008 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
14009 [(set_attr "type" "alu")
14010 (set_attr "modrm" "0")
14011 (set_attr "length" "7")
14012 (set_attr "memory" "load")
14013 (set_attr "imm_disp" "false")])
14015 (define_insn "*add_tp_x32_zext"
14016 [(set (match_operand:DI 0 "register_operand" "=r")
14018 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14019 (match_operand:SI 1 "register_operand" "0"))))
14020 (clobber (reg:CC FLAGS_REG))]
14022 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
14023 [(set_attr "type" "alu")
14024 (set_attr "modrm" "0")
14025 (set_attr "length" "7")
14026 (set_attr "memory" "load")
14027 (set_attr "imm_disp" "false")])
14029 (define_insn "*add_tp_<mode>"
14030 [(set (match_operand:P 0 "register_operand" "=r")
14031 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
14032 (match_operand:P 1 "register_operand" "0")))
14033 (clobber (reg:CC FLAGS_REG))]
14035 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
14036 [(set_attr "type" "alu")
14037 (set_attr "modrm" "0")
14038 (set_attr "length" "7")
14039 (set_attr "memory" "load")
14040 (set_attr "imm_disp" "false")])
14042 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
14043 ;; %rax as destination of the initial executable code sequence.
14044 (define_insn "tls_initial_exec_64_sun"
14045 [(set (match_operand:DI 0 "register_operand" "=a")
14047 [(match_operand 1 "tls_symbolic_operand")]
14048 UNSPEC_TLS_IE_SUN))
14049 (clobber (reg:CC FLAGS_REG))]
14050 "TARGET_64BIT && TARGET_SUN_TLS"
14053 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
14054 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
14056 [(set_attr "type" "multi")])
14058 ;; GNU2 TLS patterns can be split.
14060 (define_expand "tls_dynamic_gnu2_32"
14061 [(set (match_dup 3)
14062 (plus:SI (match_operand:SI 2 "register_operand")
14064 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
14067 [(set (match_operand:SI 0 "register_operand")
14068 (unspec:SI [(match_dup 1) (match_dup 3)
14069 (match_dup 2) (reg:SI SP_REG)]
14071 (clobber (reg:CC FLAGS_REG))])]
14072 "!TARGET_64BIT && TARGET_GNU2_TLS"
14074 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14075 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14078 (define_insn "*tls_dynamic_gnu2_lea_32"
14079 [(set (match_operand:SI 0 "register_operand" "=r")
14080 (plus:SI (match_operand:SI 1 "register_operand" "b")
14082 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
14083 UNSPEC_TLSDESC))))]
14084 "!TARGET_64BIT && TARGET_GNU2_TLS"
14085 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
14086 [(set_attr "type" "lea")
14087 (set_attr "mode" "SI")
14088 (set_attr "length" "6")
14089 (set_attr "length_address" "4")])
14091 (define_insn "*tls_dynamic_gnu2_call_32"
14092 [(set (match_operand:SI 0 "register_operand" "=a")
14093 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
14094 (match_operand:SI 2 "register_operand" "0")
14095 ;; we have to make sure %ebx still points to the GOT
14096 (match_operand:SI 3 "register_operand" "b")
14099 (clobber (reg:CC FLAGS_REG))]
14100 "!TARGET_64BIT && TARGET_GNU2_TLS"
14101 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14102 [(set_attr "type" "call")
14103 (set_attr "length" "2")
14104 (set_attr "length_address" "0")])
14106 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14107 [(set (match_operand:SI 0 "register_operand" "=&a")
14109 (unspec:SI [(match_operand 3 "tls_modbase_operand")
14110 (match_operand:SI 4)
14111 (match_operand:SI 2 "register_operand" "b")
14114 (const:SI (unspec:SI
14115 [(match_operand 1 "tls_symbolic_operand")]
14117 (clobber (reg:CC FLAGS_REG))]
14118 "!TARGET_64BIT && TARGET_GNU2_TLS"
14121 [(set (match_dup 0) (match_dup 5))]
14123 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14124 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14127 (define_expand "tls_dynamic_gnu2_64"
14128 [(set (match_dup 2)
14129 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14132 [(set (match_operand:DI 0 "register_operand")
14133 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14135 (clobber (reg:CC FLAGS_REG))])]
14136 "TARGET_64BIT && TARGET_GNU2_TLS"
14138 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14139 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14142 (define_insn "*tls_dynamic_gnu2_lea_64"
14143 [(set (match_operand:DI 0 "register_operand" "=r")
14144 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14146 "TARGET_64BIT && TARGET_GNU2_TLS"
14147 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
14148 [(set_attr "type" "lea")
14149 (set_attr "mode" "DI")
14150 (set_attr "length" "7")
14151 (set_attr "length_address" "4")])
14153 (define_insn "*tls_dynamic_gnu2_call_64"
14154 [(set (match_operand:DI 0 "register_operand" "=a")
14155 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14156 (match_operand:DI 2 "register_operand" "0")
14159 (clobber (reg:CC FLAGS_REG))]
14160 "TARGET_64BIT && TARGET_GNU2_TLS"
14161 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14162 [(set_attr "type" "call")
14163 (set_attr "length" "2")
14164 (set_attr "length_address" "0")])
14166 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14167 [(set (match_operand:DI 0 "register_operand" "=&a")
14169 (unspec:DI [(match_operand 2 "tls_modbase_operand")
14170 (match_operand:DI 3)
14173 (const:DI (unspec:DI
14174 [(match_operand 1 "tls_symbolic_operand")]
14176 (clobber (reg:CC FLAGS_REG))]
14177 "TARGET_64BIT && TARGET_GNU2_TLS"
14180 [(set (match_dup 0) (match_dup 4))]
14182 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14183 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14186 ;; These patterns match the binary 387 instructions for addM3, subM3,
14187 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14188 ;; SFmode. The first is the normal insn, the second the same insn but
14189 ;; with one operand a conversion, and the third the same insn but with
14190 ;; the other operand a conversion. The conversion may be SFmode or
14191 ;; SImode if the target mode DFmode, but only SImode if the target mode
14194 ;; Gcc is slightly more smart about handling normal two address instructions
14195 ;; so use special patterns for add and mull.
14197 (define_insn "*fop_<mode>_comm"
14198 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
14199 (match_operator:MODEF 3 "binary_fp_operator"
14200 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
14201 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
14202 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14203 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14204 && COMMUTATIVE_ARITH_P (operands[3])
14205 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14206 "* return output_387_binary_op (insn, operands);"
14207 [(set (attr "type")
14208 (if_then_else (eq_attr "alternative" "1,2")
14209 (if_then_else (match_operand:MODEF 3 "mult_operator")
14210 (const_string "ssemul")
14211 (const_string "sseadd"))
14212 (if_then_else (match_operand:MODEF 3 "mult_operator")
14213 (const_string "fmul")
14214 (const_string "fop"))))
14215 (set_attr "isa" "*,noavx,avx")
14216 (set_attr "prefix" "orig,orig,vex")
14217 (set_attr "mode" "<MODE>")
14218 (set (attr "enabled")
14220 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14222 (eq_attr "alternative" "0")
14223 (symbol_ref "TARGET_MIX_SSE_I387
14224 && X87_ENABLE_ARITH (<MODE>mode)")
14225 (const_string "*"))
14227 (eq_attr "alternative" "0")
14228 (symbol_ref "true")
14229 (symbol_ref "false"))))])
14231 (define_insn "*rcpsf2_sse"
14232 [(set (match_operand:SF 0 "register_operand" "=x")
14233 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14236 "%vrcpss\t{%1, %d0|%d0, %1}"
14237 [(set_attr "type" "sse")
14238 (set_attr "atom_sse_attr" "rcp")
14239 (set_attr "btver2_sse_attr" "rcp")
14240 (set_attr "prefix" "maybe_vex")
14241 (set_attr "mode" "SF")])
14243 (define_insn "*fop_<mode>_1"
14244 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
14245 (match_operator:MODEF 3 "binary_fp_operator"
14246 [(match_operand:MODEF 1
14247 "x87nonimm_ssenomem_operand" "0,fm,0,v")
14248 (match_operand:MODEF 2
14249 "nonimmediate_operand" "fm,0,xm,vm")]))]
14250 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14251 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14252 && !COMMUTATIVE_ARITH_P (operands[3])
14253 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14254 "* return output_387_binary_op (insn, operands);"
14255 [(set (attr "type")
14256 (if_then_else (eq_attr "alternative" "2,3")
14257 (if_then_else (match_operand:MODEF 3 "div_operator")
14258 (const_string "ssediv")
14259 (const_string "sseadd"))
14260 (if_then_else (match_operand:MODEF 3 "div_operator")
14261 (const_string "fdiv")
14262 (const_string "fop"))))
14263 (set_attr "isa" "*,*,noavx,avx")
14264 (set_attr "prefix" "orig,orig,orig,vex")
14265 (set_attr "mode" "<MODE>")
14266 (set (attr "enabled")
14268 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14270 (eq_attr "alternative" "0,1")
14271 (symbol_ref "TARGET_MIX_SSE_I387
14272 && X87_ENABLE_ARITH (<MODE>mode)")
14273 (const_string "*"))
14275 (eq_attr "alternative" "0,1")
14276 (symbol_ref "true")
14277 (symbol_ref "false"))))])
14279 ;; ??? Add SSE splitters for these!
14280 (define_insn "*fop_<MODEF:mode>_2_i387"
14281 [(set (match_operand:MODEF 0 "register_operand" "=f")
14282 (match_operator:MODEF 3 "binary_fp_operator"
14284 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14285 (match_operand:MODEF 2 "register_operand" "0")]))]
14286 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14287 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14288 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14289 || optimize_function_for_size_p (cfun))"
14290 "* return output_387_binary_op (insn, operands);"
14291 [(set (attr "type")
14292 (cond [(match_operand:MODEF 3 "mult_operator")
14293 (const_string "fmul")
14294 (match_operand:MODEF 3 "div_operator")
14295 (const_string "fdiv")
14297 (const_string "fop")))
14298 (set_attr "fp_int_src" "true")
14299 (set_attr "mode" "<SWI24:MODE>")])
14301 (define_insn "*fop_<MODEF:mode>_3_i387"
14302 [(set (match_operand:MODEF 0 "register_operand" "=f")
14303 (match_operator:MODEF 3 "binary_fp_operator"
14304 [(match_operand:MODEF 1 "register_operand" "0")
14306 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14307 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14308 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14309 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14310 || optimize_function_for_size_p (cfun))"
14311 "* return output_387_binary_op (insn, operands);"
14312 [(set (attr "type")
14313 (cond [(match_operand:MODEF 3 "mult_operator")
14314 (const_string "fmul")
14315 (match_operand:MODEF 3 "div_operator")
14316 (const_string "fdiv")
14318 (const_string "fop")))
14319 (set_attr "fp_int_src" "true")
14320 (set_attr "mode" "<MODE>")])
14322 (define_insn "*fop_df_4_i387"
14323 [(set (match_operand:DF 0 "register_operand" "=f,f")
14324 (match_operator:DF 3 "binary_fp_operator"
14326 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14327 (match_operand:DF 2 "register_operand" "0,f")]))]
14328 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14329 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14330 "* return output_387_binary_op (insn, operands);"
14331 [(set (attr "type")
14332 (cond [(match_operand:DF 3 "mult_operator")
14333 (const_string "fmul")
14334 (match_operand:DF 3 "div_operator")
14335 (const_string "fdiv")
14337 (const_string "fop")))
14338 (set_attr "mode" "SF")])
14340 (define_insn "*fop_df_5_i387"
14341 [(set (match_operand:DF 0 "register_operand" "=f,f")
14342 (match_operator:DF 3 "binary_fp_operator"
14343 [(match_operand:DF 1 "register_operand" "0,f")
14345 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14346 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14347 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14348 "* return output_387_binary_op (insn, operands);"
14349 [(set (attr "type")
14350 (cond [(match_operand:DF 3 "mult_operator")
14351 (const_string "fmul")
14352 (match_operand:DF 3 "div_operator")
14353 (const_string "fdiv")
14355 (const_string "fop")))
14356 (set_attr "mode" "SF")])
14358 (define_insn "*fop_df_6_i387"
14359 [(set (match_operand:DF 0 "register_operand" "=f,f")
14360 (match_operator:DF 3 "binary_fp_operator"
14362 (match_operand:SF 1 "register_operand" "0,f"))
14364 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14365 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14366 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14367 "* return output_387_binary_op (insn, operands);"
14368 [(set (attr "type")
14369 (cond [(match_operand:DF 3 "mult_operator")
14370 (const_string "fmul")
14371 (match_operand:DF 3 "div_operator")
14372 (const_string "fdiv")
14374 (const_string "fop")))
14375 (set_attr "mode" "SF")])
14377 (define_insn "*fop_xf_comm_i387"
14378 [(set (match_operand:XF 0 "register_operand" "=f")
14379 (match_operator:XF 3 "binary_fp_operator"
14380 [(match_operand:XF 1 "register_operand" "%0")
14381 (match_operand:XF 2 "register_operand" "f")]))]
14383 && COMMUTATIVE_ARITH_P (operands[3])"
14384 "* return output_387_binary_op (insn, operands);"
14385 [(set (attr "type")
14386 (if_then_else (match_operand:XF 3 "mult_operator")
14387 (const_string "fmul")
14388 (const_string "fop")))
14389 (set_attr "mode" "XF")])
14391 (define_insn "*fop_xf_1_i387"
14392 [(set (match_operand:XF 0 "register_operand" "=f,f")
14393 (match_operator:XF 3 "binary_fp_operator"
14394 [(match_operand:XF 1 "register_operand" "0,f")
14395 (match_operand:XF 2 "register_operand" "f,0")]))]
14397 && !COMMUTATIVE_ARITH_P (operands[3])"
14398 "* return output_387_binary_op (insn, operands);"
14399 [(set (attr "type")
14400 (if_then_else (match_operand:XF 3 "div_operator")
14401 (const_string "fdiv")
14402 (const_string "fop")))
14403 (set_attr "mode" "XF")])
14405 (define_insn "*fop_xf_2_i387"
14406 [(set (match_operand:XF 0 "register_operand" "=f")
14407 (match_operator:XF 3 "binary_fp_operator"
14409 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14410 (match_operand:XF 2 "register_operand" "0")]))]
14412 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14413 "* return output_387_binary_op (insn, operands);"
14414 [(set (attr "type")
14415 (cond [(match_operand:XF 3 "mult_operator")
14416 (const_string "fmul")
14417 (match_operand:XF 3 "div_operator")
14418 (const_string "fdiv")
14420 (const_string "fop")))
14421 (set_attr "fp_int_src" "true")
14422 (set_attr "mode" "<MODE>")])
14424 (define_insn "*fop_xf_3_i387"
14425 [(set (match_operand:XF 0 "register_operand" "=f")
14426 (match_operator:XF 3 "binary_fp_operator"
14427 [(match_operand:XF 1 "register_operand" "0")
14429 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14431 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14432 "* return output_387_binary_op (insn, operands);"
14433 [(set (attr "type")
14434 (cond [(match_operand:XF 3 "mult_operator")
14435 (const_string "fmul")
14436 (match_operand:XF 3 "div_operator")
14437 (const_string "fdiv")
14439 (const_string "fop")))
14440 (set_attr "fp_int_src" "true")
14441 (set_attr "mode" "<MODE>")])
14443 (define_insn "*fop_xf_4_i387"
14444 [(set (match_operand:XF 0 "register_operand" "=f,f")
14445 (match_operator:XF 3 "binary_fp_operator"
14447 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
14448 (match_operand:XF 2 "register_operand" "0,f")]))]
14450 "* return output_387_binary_op (insn, operands);"
14451 [(set (attr "type")
14452 (cond [(match_operand:XF 3 "mult_operator")
14453 (const_string "fmul")
14454 (match_operand:XF 3 "div_operator")
14455 (const_string "fdiv")
14457 (const_string "fop")))
14458 (set_attr "mode" "<MODE>")])
14460 (define_insn "*fop_xf_5_i387"
14461 [(set (match_operand:XF 0 "register_operand" "=f,f")
14462 (match_operator:XF 3 "binary_fp_operator"
14463 [(match_operand:XF 1 "register_operand" "0,f")
14465 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14467 "* return output_387_binary_op (insn, operands);"
14468 [(set (attr "type")
14469 (cond [(match_operand:XF 3 "mult_operator")
14470 (const_string "fmul")
14471 (match_operand:XF 3 "div_operator")
14472 (const_string "fdiv")
14474 (const_string "fop")))
14475 (set_attr "mode" "<MODE>")])
14477 (define_insn "*fop_xf_6_i387"
14478 [(set (match_operand:XF 0 "register_operand" "=f,f")
14479 (match_operator:XF 3 "binary_fp_operator"
14481 (match_operand:MODEF 1 "register_operand" "0,f"))
14483 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14485 "* return output_387_binary_op (insn, operands);"
14486 [(set (attr "type")
14487 (cond [(match_operand:XF 3 "mult_operator")
14488 (const_string "fmul")
14489 (match_operand:XF 3 "div_operator")
14490 (const_string "fdiv")
14492 (const_string "fop")))
14493 (set_attr "mode" "<MODE>")])
14495 ;; FPU special functions.
14497 ;; This pattern implements a no-op XFmode truncation for
14498 ;; all fancy i386 XFmode math functions.
14500 (define_insn "truncxf<mode>2_i387_noop_unspec"
14501 [(set (match_operand:MODEF 0 "register_operand" "=f")
14502 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
14503 UNSPEC_TRUNC_NOOP))]
14504 "TARGET_USE_FANCY_MATH_387"
14505 "* return output_387_reg_move (insn, operands);"
14506 [(set_attr "type" "fmov")
14507 (set_attr "mode" "<MODE>")])
14509 (define_insn "sqrtxf2"
14510 [(set (match_operand:XF 0 "register_operand" "=f")
14511 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14512 "TARGET_USE_FANCY_MATH_387"
14514 [(set_attr "type" "fpspc")
14515 (set_attr "mode" "XF")
14516 (set_attr "athlon_decode" "direct")
14517 (set_attr "amdfam10_decode" "direct")
14518 (set_attr "bdver1_decode" "direct")])
14520 (define_insn "sqrt_extend<mode>xf2_i387"
14521 [(set (match_operand:XF 0 "register_operand" "=f")
14524 (match_operand:MODEF 1 "register_operand" "0"))))]
14525 "TARGET_USE_FANCY_MATH_387"
14527 [(set_attr "type" "fpspc")
14528 (set_attr "mode" "XF")
14529 (set_attr "athlon_decode" "direct")
14530 (set_attr "amdfam10_decode" "direct")
14531 (set_attr "bdver1_decode" "direct")])
14533 (define_insn "*rsqrtsf2_sse"
14534 [(set (match_operand:SF 0 "register_operand" "=x")
14535 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14538 "%vrsqrtss\t{%1, %d0|%d0, %1}"
14539 [(set_attr "type" "sse")
14540 (set_attr "atom_sse_attr" "rcp")
14541 (set_attr "btver2_sse_attr" "rcp")
14542 (set_attr "prefix" "maybe_vex")
14543 (set_attr "mode" "SF")])
14545 (define_expand "rsqrtsf2"
14546 [(set (match_operand:SF 0 "register_operand")
14547 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
14551 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
14555 (define_insn "*sqrt<mode>2_sse"
14556 [(set (match_operand:MODEF 0 "register_operand" "=v")
14558 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
14559 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14560 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
14561 [(set_attr "type" "sse")
14562 (set_attr "atom_sse_attr" "sqrt")
14563 (set_attr "btver2_sse_attr" "sqrt")
14564 (set_attr "prefix" "maybe_vex")
14565 (set_attr "mode" "<MODE>")
14566 (set_attr "athlon_decode" "*")
14567 (set_attr "amdfam10_decode" "*")
14568 (set_attr "bdver1_decode" "*")])
14570 (define_expand "sqrt<mode>2"
14571 [(set (match_operand:MODEF 0 "register_operand")
14573 (match_operand:MODEF 1 "nonimmediate_operand")))]
14574 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
14575 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14577 if (<MODE>mode == SFmode
14579 && TARGET_RECIP_SQRT
14580 && !optimize_function_for_size_p (cfun)
14581 && flag_finite_math_only && !flag_trapping_math
14582 && flag_unsafe_math_optimizations)
14584 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
14588 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
14590 rtx op0 = gen_reg_rtx (XFmode);
14591 rtx op1 = force_reg (<MODE>mode, operands[1]);
14593 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
14594 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
14599 (define_insn "fpremxf4_i387"
14600 [(set (match_operand:XF 0 "register_operand" "=f")
14601 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14602 (match_operand:XF 3 "register_operand" "1")]
14604 (set (match_operand:XF 1 "register_operand" "=u")
14605 (unspec:XF [(match_dup 2) (match_dup 3)]
14607 (set (reg:CCFP FPSR_REG)
14608 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14610 "TARGET_USE_FANCY_MATH_387
14611 && flag_finite_math_only"
14613 [(set_attr "type" "fpspc")
14614 (set_attr "znver1_decode" "vector")
14615 (set_attr "mode" "XF")])
14617 (define_expand "fmodxf3"
14618 [(use (match_operand:XF 0 "register_operand"))
14619 (use (match_operand:XF 1 "general_operand"))
14620 (use (match_operand:XF 2 "general_operand"))]
14621 "TARGET_USE_FANCY_MATH_387
14622 && flag_finite_math_only"
14624 rtx_code_label *label = gen_label_rtx ();
14626 rtx op1 = gen_reg_rtx (XFmode);
14627 rtx op2 = gen_reg_rtx (XFmode);
14629 emit_move_insn (op2, operands[2]);
14630 emit_move_insn (op1, operands[1]);
14632 emit_label (label);
14633 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14634 ix86_emit_fp_unordered_jump (label);
14635 LABEL_NUSES (label) = 1;
14637 emit_move_insn (operands[0], op1);
14641 (define_expand "fmod<mode>3"
14642 [(use (match_operand:MODEF 0 "register_operand"))
14643 (use (match_operand:MODEF 1 "general_operand"))
14644 (use (match_operand:MODEF 2 "general_operand"))]
14645 "TARGET_USE_FANCY_MATH_387
14646 && flag_finite_math_only"
14648 rtx (*gen_truncxf) (rtx, rtx);
14650 rtx_code_label *label = gen_label_rtx ();
14652 rtx op1 = gen_reg_rtx (XFmode);
14653 rtx op2 = gen_reg_rtx (XFmode);
14655 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14656 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14658 emit_label (label);
14659 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14660 ix86_emit_fp_unordered_jump (label);
14661 LABEL_NUSES (label) = 1;
14663 /* Truncate the result properly for strict SSE math. */
14664 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14665 && !TARGET_MIX_SSE_I387)
14666 gen_truncxf = gen_truncxf<mode>2;
14668 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14670 emit_insn (gen_truncxf (operands[0], op1));
14674 (define_insn "fprem1xf4_i387"
14675 [(set (match_operand:XF 0 "register_operand" "=f")
14676 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14677 (match_operand:XF 3 "register_operand" "1")]
14679 (set (match_operand:XF 1 "register_operand" "=u")
14680 (unspec:XF [(match_dup 2) (match_dup 3)]
14682 (set (reg:CCFP FPSR_REG)
14683 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14685 "TARGET_USE_FANCY_MATH_387
14686 && flag_finite_math_only"
14688 [(set_attr "type" "fpspc")
14689 (set_attr "znver1_decode" "vector")
14690 (set_attr "mode" "XF")])
14692 (define_expand "remainderxf3"
14693 [(use (match_operand:XF 0 "register_operand"))
14694 (use (match_operand:XF 1 "general_operand"))
14695 (use (match_operand:XF 2 "general_operand"))]
14696 "TARGET_USE_FANCY_MATH_387
14697 && flag_finite_math_only"
14699 rtx_code_label *label = gen_label_rtx ();
14701 rtx op1 = gen_reg_rtx (XFmode);
14702 rtx op2 = gen_reg_rtx (XFmode);
14704 emit_move_insn (op2, operands[2]);
14705 emit_move_insn (op1, operands[1]);
14707 emit_label (label);
14708 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14709 ix86_emit_fp_unordered_jump (label);
14710 LABEL_NUSES (label) = 1;
14712 emit_move_insn (operands[0], op1);
14716 (define_expand "remainder<mode>3"
14717 [(use (match_operand:MODEF 0 "register_operand"))
14718 (use (match_operand:MODEF 1 "general_operand"))
14719 (use (match_operand:MODEF 2 "general_operand"))]
14720 "TARGET_USE_FANCY_MATH_387
14721 && flag_finite_math_only"
14723 rtx (*gen_truncxf) (rtx, rtx);
14725 rtx_code_label *label = gen_label_rtx ();
14727 rtx op1 = gen_reg_rtx (XFmode);
14728 rtx op2 = gen_reg_rtx (XFmode);
14730 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14731 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14733 emit_label (label);
14735 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14736 ix86_emit_fp_unordered_jump (label);
14737 LABEL_NUSES (label) = 1;
14739 /* Truncate the result properly for strict SSE math. */
14740 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14741 && !TARGET_MIX_SSE_I387)
14742 gen_truncxf = gen_truncxf<mode>2;
14744 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14746 emit_insn (gen_truncxf (operands[0], op1));
14750 (define_int_iterator SINCOS
14754 (define_int_attr sincos
14755 [(UNSPEC_SIN "sin")
14756 (UNSPEC_COS "cos")])
14758 (define_insn "*<sincos>xf2_i387"
14759 [(set (match_operand:XF 0 "register_operand" "=f")
14760 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14762 "TARGET_USE_FANCY_MATH_387
14763 && flag_unsafe_math_optimizations"
14765 [(set_attr "type" "fpspc")
14766 (set_attr "znver1_decode" "vector")
14767 (set_attr "mode" "XF")])
14769 (define_insn "*<sincos>_extend<mode>xf2_i387"
14770 [(set (match_operand:XF 0 "register_operand" "=f")
14771 (unspec:XF [(float_extend:XF
14772 (match_operand:MODEF 1 "register_operand" "0"))]
14774 "TARGET_USE_FANCY_MATH_387
14775 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14776 || TARGET_MIX_SSE_I387)
14777 && flag_unsafe_math_optimizations"
14779 [(set_attr "type" "fpspc")
14780 (set_attr "znver1_decode" "vector")
14781 (set_attr "mode" "XF")])
14783 ;; When sincos pattern is defined, sin and cos builtin functions will be
14784 ;; expanded to sincos pattern with one of its outputs left unused.
14785 ;; CSE pass will figure out if two sincos patterns can be combined,
14786 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14787 ;; depending on the unused output.
14789 (define_insn "sincosxf3"
14790 [(set (match_operand:XF 0 "register_operand" "=f")
14791 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14792 UNSPEC_SINCOS_COS))
14793 (set (match_operand:XF 1 "register_operand" "=u")
14794 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14795 "TARGET_USE_FANCY_MATH_387
14796 && flag_unsafe_math_optimizations"
14798 [(set_attr "type" "fpspc")
14799 (set_attr "znver1_decode" "vector")
14800 (set_attr "mode" "XF")])
14803 [(set (match_operand:XF 0 "register_operand")
14804 (unspec:XF [(match_operand:XF 2 "register_operand")]
14805 UNSPEC_SINCOS_COS))
14806 (set (match_operand:XF 1 "register_operand")
14807 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14808 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14809 && can_create_pseudo_p ()"
14810 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14813 [(set (match_operand:XF 0 "register_operand")
14814 (unspec:XF [(match_operand:XF 2 "register_operand")]
14815 UNSPEC_SINCOS_COS))
14816 (set (match_operand:XF 1 "register_operand")
14817 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14818 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14819 && can_create_pseudo_p ()"
14820 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14822 (define_insn "sincos_extend<mode>xf3_i387"
14823 [(set (match_operand:XF 0 "register_operand" "=f")
14824 (unspec:XF [(float_extend:XF
14825 (match_operand:MODEF 2 "register_operand" "0"))]
14826 UNSPEC_SINCOS_COS))
14827 (set (match_operand:XF 1 "register_operand" "=u")
14828 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14829 "TARGET_USE_FANCY_MATH_387
14830 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14831 || TARGET_MIX_SSE_I387)
14832 && flag_unsafe_math_optimizations"
14834 [(set_attr "type" "fpspc")
14835 (set_attr "znver1_decode" "vector")
14836 (set_attr "mode" "XF")])
14839 [(set (match_operand:XF 0 "register_operand")
14840 (unspec:XF [(float_extend:XF
14841 (match_operand:MODEF 2 "register_operand"))]
14842 UNSPEC_SINCOS_COS))
14843 (set (match_operand:XF 1 "register_operand")
14844 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14845 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14846 && can_create_pseudo_p ()"
14847 [(set (match_dup 1)
14848 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14851 [(set (match_operand:XF 0 "register_operand")
14852 (unspec:XF [(float_extend:XF
14853 (match_operand:MODEF 2 "register_operand"))]
14854 UNSPEC_SINCOS_COS))
14855 (set (match_operand:XF 1 "register_operand")
14856 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14857 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14858 && can_create_pseudo_p ()"
14859 [(set (match_dup 0)
14860 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14862 (define_expand "sincos<mode>3"
14863 [(use (match_operand:MODEF 0 "register_operand"))
14864 (use (match_operand:MODEF 1 "register_operand"))
14865 (use (match_operand:MODEF 2 "register_operand"))]
14866 "TARGET_USE_FANCY_MATH_387
14867 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14868 || TARGET_MIX_SSE_I387)
14869 && flag_unsafe_math_optimizations"
14871 rtx op0 = gen_reg_rtx (XFmode);
14872 rtx op1 = gen_reg_rtx (XFmode);
14874 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14875 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14876 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14880 (define_insn "fptanxf4_i387"
14881 [(set (match_operand:XF 0 "register_operand" "=f")
14882 (match_operand:XF 3 "const_double_operand" "F"))
14883 (set (match_operand:XF 1 "register_operand" "=u")
14884 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14886 "TARGET_USE_FANCY_MATH_387
14887 && flag_unsafe_math_optimizations
14888 && standard_80387_constant_p (operands[3]) == 2"
14890 [(set_attr "type" "fpspc")
14891 (set_attr "znver1_decode" "vector")
14892 (set_attr "mode" "XF")])
14894 (define_insn "fptan_extend<mode>xf4_i387"
14895 [(set (match_operand:MODEF 0 "register_operand" "=f")
14896 (match_operand:MODEF 3 "const_double_operand" "F"))
14897 (set (match_operand:XF 1 "register_operand" "=u")
14898 (unspec:XF [(float_extend:XF
14899 (match_operand:MODEF 2 "register_operand" "0"))]
14901 "TARGET_USE_FANCY_MATH_387
14902 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14903 || TARGET_MIX_SSE_I387)
14904 && flag_unsafe_math_optimizations
14905 && standard_80387_constant_p (operands[3]) == 2"
14907 [(set_attr "type" "fpspc")
14908 (set_attr "znver1_decode" "vector")
14909 (set_attr "mode" "XF")])
14911 (define_expand "tanxf2"
14912 [(use (match_operand:XF 0 "register_operand"))
14913 (use (match_operand:XF 1 "register_operand"))]
14914 "TARGET_USE_FANCY_MATH_387
14915 && flag_unsafe_math_optimizations"
14917 rtx one = gen_reg_rtx (XFmode);
14918 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14920 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14924 (define_expand "tan<mode>2"
14925 [(use (match_operand:MODEF 0 "register_operand"))
14926 (use (match_operand:MODEF 1 "register_operand"))]
14927 "TARGET_USE_FANCY_MATH_387
14928 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14929 || TARGET_MIX_SSE_I387)
14930 && flag_unsafe_math_optimizations"
14932 rtx op0 = gen_reg_rtx (XFmode);
14934 rtx one = gen_reg_rtx (<MODE>mode);
14935 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14937 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14938 operands[1], op2));
14939 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14943 (define_insn "*fpatanxf3_i387"
14944 [(set (match_operand:XF 0 "register_operand" "=f")
14945 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14946 (match_operand:XF 2 "register_operand" "u")]
14948 (clobber (match_scratch:XF 3 "=2"))]
14949 "TARGET_USE_FANCY_MATH_387
14950 && flag_unsafe_math_optimizations"
14952 [(set_attr "type" "fpspc")
14953 (set_attr "znver1_decode" "vector")
14954 (set_attr "mode" "XF")])
14956 (define_insn "fpatan_extend<mode>xf3_i387"
14957 [(set (match_operand:XF 0 "register_operand" "=f")
14958 (unspec:XF [(float_extend:XF
14959 (match_operand:MODEF 1 "register_operand" "0"))
14961 (match_operand:MODEF 2 "register_operand" "u"))]
14963 (clobber (match_scratch:XF 3 "=2"))]
14964 "TARGET_USE_FANCY_MATH_387
14965 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14966 || TARGET_MIX_SSE_I387)
14967 && flag_unsafe_math_optimizations"
14969 [(set_attr "type" "fpspc")
14970 (set_attr "znver1_decode" "vector")
14971 (set_attr "mode" "XF")])
14973 (define_expand "atan2xf3"
14974 [(parallel [(set (match_operand:XF 0 "register_operand")
14975 (unspec:XF [(match_operand:XF 2 "register_operand")
14976 (match_operand:XF 1 "register_operand")]
14978 (clobber (match_scratch:XF 3))])]
14979 "TARGET_USE_FANCY_MATH_387
14980 && flag_unsafe_math_optimizations")
14982 (define_expand "atan2<mode>3"
14983 [(use (match_operand:MODEF 0 "register_operand"))
14984 (use (match_operand:MODEF 1 "register_operand"))
14985 (use (match_operand:MODEF 2 "register_operand"))]
14986 "TARGET_USE_FANCY_MATH_387
14987 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14988 || TARGET_MIX_SSE_I387)
14989 && flag_unsafe_math_optimizations"
14991 rtx op0 = gen_reg_rtx (XFmode);
14993 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14994 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14998 (define_expand "atanxf2"
14999 [(parallel [(set (match_operand:XF 0 "register_operand")
15000 (unspec:XF [(match_dup 2)
15001 (match_operand:XF 1 "register_operand")]
15003 (clobber (match_scratch:XF 3))])]
15004 "TARGET_USE_FANCY_MATH_387
15005 && flag_unsafe_math_optimizations"
15007 operands[2] = gen_reg_rtx (XFmode);
15008 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15011 (define_expand "atan<mode>2"
15012 [(use (match_operand:MODEF 0 "register_operand"))
15013 (use (match_operand:MODEF 1 "register_operand"))]
15014 "TARGET_USE_FANCY_MATH_387
15015 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15016 || TARGET_MIX_SSE_I387)
15017 && flag_unsafe_math_optimizations"
15019 rtx op0 = gen_reg_rtx (XFmode);
15021 rtx op2 = gen_reg_rtx (<MODE>mode);
15022 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
15024 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
15025 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15029 (define_expand "asinxf2"
15030 [(set (match_dup 2)
15031 (mult:XF (match_operand:XF 1 "register_operand")
15033 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15034 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15035 (parallel [(set (match_operand:XF 0 "register_operand")
15036 (unspec:XF [(match_dup 5) (match_dup 1)]
15038 (clobber (match_scratch:XF 6))])]
15039 "TARGET_USE_FANCY_MATH_387
15040 && flag_unsafe_math_optimizations"
15044 for (i = 2; i < 6; i++)
15045 operands[i] = gen_reg_rtx (XFmode);
15047 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15050 (define_expand "asin<mode>2"
15051 [(use (match_operand:MODEF 0 "register_operand"))
15052 (use (match_operand:MODEF 1 "general_operand"))]
15053 "TARGET_USE_FANCY_MATH_387
15054 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15055 || TARGET_MIX_SSE_I387)
15056 && flag_unsafe_math_optimizations"
15058 rtx op0 = gen_reg_rtx (XFmode);
15059 rtx op1 = gen_reg_rtx (XFmode);
15061 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15062 emit_insn (gen_asinxf2 (op0, op1));
15063 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15067 (define_expand "acosxf2"
15068 [(set (match_dup 2)
15069 (mult:XF (match_operand:XF 1 "register_operand")
15071 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15072 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15073 (parallel [(set (match_operand:XF 0 "register_operand")
15074 (unspec:XF [(match_dup 1) (match_dup 5)]
15076 (clobber (match_scratch:XF 6))])]
15077 "TARGET_USE_FANCY_MATH_387
15078 && flag_unsafe_math_optimizations"
15082 for (i = 2; i < 6; i++)
15083 operands[i] = gen_reg_rtx (XFmode);
15085 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15088 (define_expand "acos<mode>2"
15089 [(use (match_operand:MODEF 0 "register_operand"))
15090 (use (match_operand:MODEF 1 "general_operand"))]
15091 "TARGET_USE_FANCY_MATH_387
15092 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15093 || TARGET_MIX_SSE_I387)
15094 && flag_unsafe_math_optimizations"
15096 rtx op0 = gen_reg_rtx (XFmode);
15097 rtx op1 = gen_reg_rtx (XFmode);
15099 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15100 emit_insn (gen_acosxf2 (op0, op1));
15101 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15105 (define_insn "fyl2xxf3_i387"
15106 [(set (match_operand:XF 0 "register_operand" "=f")
15107 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15108 (match_operand:XF 2 "register_operand" "u")]
15110 (clobber (match_scratch:XF 3 "=2"))]
15111 "TARGET_USE_FANCY_MATH_387
15112 && flag_unsafe_math_optimizations"
15114 [(set_attr "type" "fpspc")
15115 (set_attr "znver1_decode" "vector")
15116 (set_attr "mode" "XF")])
15118 (define_insn "fyl2x_extend<mode>xf3_i387"
15119 [(set (match_operand:XF 0 "register_operand" "=f")
15120 (unspec:XF [(float_extend:XF
15121 (match_operand:MODEF 1 "register_operand" "0"))
15122 (match_operand:XF 2 "register_operand" "u")]
15124 (clobber (match_scratch:XF 3 "=2"))]
15125 "TARGET_USE_FANCY_MATH_387
15126 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15127 || TARGET_MIX_SSE_I387)
15128 && flag_unsafe_math_optimizations"
15130 [(set_attr "type" "fpspc")
15131 (set_attr "znver1_decode" "vector")
15132 (set_attr "mode" "XF")])
15134 (define_expand "logxf2"
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 (4)); /* fldln2 */
15146 (define_expand "log<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 (4)); /* fldln2 */
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 "log10xf2"
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], standard_80387_constant_rtx (3)); /* fldlg2 */
15176 (define_expand "log10<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, standard_80387_constant_rtx (3)); /* fldlg2 */
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_expand "log2xf2"
15195 [(parallel [(set (match_operand:XF 0 "register_operand")
15196 (unspec:XF [(match_operand:XF 1 "register_operand")
15197 (match_dup 2)] UNSPEC_FYL2X))
15198 (clobber (match_scratch:XF 3))])]
15199 "TARGET_USE_FANCY_MATH_387
15200 && flag_unsafe_math_optimizations"
15202 operands[2] = gen_reg_rtx (XFmode);
15203 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15206 (define_expand "log2<mode>2"
15207 [(use (match_operand:MODEF 0 "register_operand"))
15208 (use (match_operand:MODEF 1 "register_operand"))]
15209 "TARGET_USE_FANCY_MATH_387
15210 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15211 || TARGET_MIX_SSE_I387)
15212 && flag_unsafe_math_optimizations"
15214 rtx op0 = gen_reg_rtx (XFmode);
15216 rtx op2 = gen_reg_rtx (XFmode);
15217 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15219 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15220 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15224 (define_insn "fyl2xp1xf3_i387"
15225 [(set (match_operand:XF 0 "register_operand" "=f")
15226 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15227 (match_operand:XF 2 "register_operand" "u")]
15229 (clobber (match_scratch:XF 3 "=2"))]
15230 "TARGET_USE_FANCY_MATH_387
15231 && flag_unsafe_math_optimizations"
15233 [(set_attr "type" "fpspc")
15234 (set_attr "znver1_decode" "vector")
15235 (set_attr "mode" "XF")])
15237 (define_insn "fyl2xp1_extend<mode>xf3_i387"
15238 [(set (match_operand:XF 0 "register_operand" "=f")
15239 (unspec:XF [(float_extend:XF
15240 (match_operand:MODEF 1 "register_operand" "0"))
15241 (match_operand:XF 2 "register_operand" "u")]
15243 (clobber (match_scratch:XF 3 "=2"))]
15244 "TARGET_USE_FANCY_MATH_387
15245 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15246 || TARGET_MIX_SSE_I387)
15247 && flag_unsafe_math_optimizations"
15249 [(set_attr "type" "fpspc")
15250 (set_attr "znver1_decode" "vector")
15251 (set_attr "mode" "XF")])
15253 (define_expand "log1pxf2"
15254 [(use (match_operand:XF 0 "register_operand"))
15255 (use (match_operand:XF 1 "register_operand"))]
15256 "TARGET_USE_FANCY_MATH_387
15257 && flag_unsafe_math_optimizations"
15259 ix86_emit_i387_log1p (operands[0], operands[1]);
15263 (define_expand "log1p<mode>2"
15264 [(use (match_operand:MODEF 0 "register_operand"))
15265 (use (match_operand:MODEF 1 "register_operand"))]
15266 "TARGET_USE_FANCY_MATH_387
15267 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15268 || TARGET_MIX_SSE_I387)
15269 && flag_unsafe_math_optimizations"
15273 op0 = gen_reg_rtx (XFmode);
15275 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
15277 ix86_emit_i387_log1p (op0, operands[1]);
15278 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15282 (define_insn "fxtractxf3_i387"
15283 [(set (match_operand:XF 0 "register_operand" "=f")
15284 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15285 UNSPEC_XTRACT_FRACT))
15286 (set (match_operand:XF 1 "register_operand" "=u")
15287 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15288 "TARGET_USE_FANCY_MATH_387
15289 && flag_unsafe_math_optimizations"
15291 [(set_attr "type" "fpspc")
15292 (set_attr "znver1_decode" "vector")
15293 (set_attr "mode" "XF")])
15295 (define_insn "fxtract_extend<mode>xf3_i387"
15296 [(set (match_operand:XF 0 "register_operand" "=f")
15297 (unspec:XF [(float_extend:XF
15298 (match_operand:MODEF 2 "register_operand" "0"))]
15299 UNSPEC_XTRACT_FRACT))
15300 (set (match_operand:XF 1 "register_operand" "=u")
15301 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
15302 "TARGET_USE_FANCY_MATH_387
15303 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15304 || TARGET_MIX_SSE_I387)
15305 && flag_unsafe_math_optimizations"
15307 [(set_attr "type" "fpspc")
15308 (set_attr "znver1_decode" "vector")
15309 (set_attr "mode" "XF")])
15311 (define_expand "logbxf2"
15312 [(parallel [(set (match_dup 2)
15313 (unspec:XF [(match_operand:XF 1 "register_operand")]
15314 UNSPEC_XTRACT_FRACT))
15315 (set (match_operand:XF 0 "register_operand")
15316 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15317 "TARGET_USE_FANCY_MATH_387
15318 && flag_unsafe_math_optimizations"
15319 "operands[2] = gen_reg_rtx (XFmode);")
15321 (define_expand "logb<mode>2"
15322 [(use (match_operand:MODEF 0 "register_operand"))
15323 (use (match_operand:MODEF 1 "register_operand"))]
15324 "TARGET_USE_FANCY_MATH_387
15325 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15326 || TARGET_MIX_SSE_I387)
15327 && flag_unsafe_math_optimizations"
15329 rtx op0 = gen_reg_rtx (XFmode);
15330 rtx op1 = gen_reg_rtx (XFmode);
15332 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15333 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
15337 (define_expand "ilogbxf2"
15338 [(use (match_operand:SI 0 "register_operand"))
15339 (use (match_operand:XF 1 "register_operand"))]
15340 "TARGET_USE_FANCY_MATH_387
15341 && flag_unsafe_math_optimizations"
15345 if (optimize_insn_for_size_p ())
15348 op0 = gen_reg_rtx (XFmode);
15349 op1 = gen_reg_rtx (XFmode);
15351 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
15352 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15356 (define_expand "ilogb<mode>2"
15357 [(use (match_operand:SI 0 "register_operand"))
15358 (use (match_operand:MODEF 1 "register_operand"))]
15359 "TARGET_USE_FANCY_MATH_387
15360 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15361 || TARGET_MIX_SSE_I387)
15362 && flag_unsafe_math_optimizations"
15366 if (optimize_insn_for_size_p ())
15369 op0 = gen_reg_rtx (XFmode);
15370 op1 = gen_reg_rtx (XFmode);
15372 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15373 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15377 (define_insn "*f2xm1xf2_i387"
15378 [(set (match_operand:XF 0 "register_operand" "=f")
15379 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15381 "TARGET_USE_FANCY_MATH_387
15382 && flag_unsafe_math_optimizations"
15384 [(set_attr "type" "fpspc")
15385 (set_attr "znver1_decode" "vector")
15386 (set_attr "mode" "XF")])
15388 (define_insn "fscalexf4_i387"
15389 [(set (match_operand:XF 0 "register_operand" "=f")
15390 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15391 (match_operand:XF 3 "register_operand" "1")]
15392 UNSPEC_FSCALE_FRACT))
15393 (set (match_operand:XF 1 "register_operand" "=u")
15394 (unspec:XF [(match_dup 2) (match_dup 3)]
15395 UNSPEC_FSCALE_EXP))]
15396 "TARGET_USE_FANCY_MATH_387
15397 && flag_unsafe_math_optimizations"
15399 [(set_attr "type" "fpspc")
15400 (set_attr "znver1_decode" "vector")
15401 (set_attr "mode" "XF")])
15403 (define_expand "expNcorexf3"
15404 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15405 (match_operand:XF 2 "register_operand")))
15406 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15407 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15408 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15409 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15410 (parallel [(set (match_operand:XF 0 "register_operand")
15411 (unspec:XF [(match_dup 8) (match_dup 4)]
15412 UNSPEC_FSCALE_FRACT))
15414 (unspec:XF [(match_dup 8) (match_dup 4)]
15415 UNSPEC_FSCALE_EXP))])]
15416 "TARGET_USE_FANCY_MATH_387
15417 && flag_unsafe_math_optimizations"
15421 for (i = 3; i < 10; i++)
15422 operands[i] = gen_reg_rtx (XFmode);
15424 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15427 (define_expand "expxf2"
15428 [(use (match_operand:XF 0 "register_operand"))
15429 (use (match_operand:XF 1 "register_operand"))]
15430 "TARGET_USE_FANCY_MATH_387
15431 && flag_unsafe_math_optimizations"
15435 op2 = gen_reg_rtx (XFmode);
15436 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
15438 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15442 (define_expand "exp<mode>2"
15443 [(use (match_operand:MODEF 0 "register_operand"))
15444 (use (match_operand:MODEF 1 "general_operand"))]
15445 "TARGET_USE_FANCY_MATH_387
15446 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15447 || TARGET_MIX_SSE_I387)
15448 && flag_unsafe_math_optimizations"
15452 op0 = gen_reg_rtx (XFmode);
15453 op1 = gen_reg_rtx (XFmode);
15455 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15456 emit_insn (gen_expxf2 (op0, op1));
15457 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15461 (define_expand "exp10xf2"
15462 [(use (match_operand:XF 0 "register_operand"))
15463 (use (match_operand:XF 1 "register_operand"))]
15464 "TARGET_USE_FANCY_MATH_387
15465 && flag_unsafe_math_optimizations"
15469 op2 = gen_reg_rtx (XFmode);
15470 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
15472 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15476 (define_expand "exp10<mode>2"
15477 [(use (match_operand:MODEF 0 "register_operand"))
15478 (use (match_operand:MODEF 1 "general_operand"))]
15479 "TARGET_USE_FANCY_MATH_387
15480 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15481 || TARGET_MIX_SSE_I387)
15482 && flag_unsafe_math_optimizations"
15486 op0 = gen_reg_rtx (XFmode);
15487 op1 = gen_reg_rtx (XFmode);
15489 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15490 emit_insn (gen_exp10xf2 (op0, op1));
15491 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15495 (define_expand "exp2xf2"
15496 [(use (match_operand:XF 0 "register_operand"))
15497 (use (match_operand:XF 1 "register_operand"))]
15498 "TARGET_USE_FANCY_MATH_387
15499 && flag_unsafe_math_optimizations"
15503 op2 = gen_reg_rtx (XFmode);
15504 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15506 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15510 (define_expand "exp2<mode>2"
15511 [(use (match_operand:MODEF 0 "register_operand"))
15512 (use (match_operand:MODEF 1 "general_operand"))]
15513 "TARGET_USE_FANCY_MATH_387
15514 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15515 || TARGET_MIX_SSE_I387)
15516 && flag_unsafe_math_optimizations"
15520 op0 = gen_reg_rtx (XFmode);
15521 op1 = gen_reg_rtx (XFmode);
15523 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15524 emit_insn (gen_exp2xf2 (op0, op1));
15525 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15529 (define_expand "expm1xf2"
15530 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15532 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15533 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15534 (set (match_dup 9) (float_extend:XF (match_dup 13)))
15535 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15536 (parallel [(set (match_dup 7)
15537 (unspec:XF [(match_dup 6) (match_dup 4)]
15538 UNSPEC_FSCALE_FRACT))
15540 (unspec:XF [(match_dup 6) (match_dup 4)]
15541 UNSPEC_FSCALE_EXP))])
15542 (parallel [(set (match_dup 10)
15543 (unspec:XF [(match_dup 9) (match_dup 8)]
15544 UNSPEC_FSCALE_FRACT))
15545 (set (match_dup 11)
15546 (unspec:XF [(match_dup 9) (match_dup 8)]
15547 UNSPEC_FSCALE_EXP))])
15548 (set (match_dup 12) (minus:XF (match_dup 10)
15549 (float_extend:XF (match_dup 13))))
15550 (set (match_operand:XF 0 "register_operand")
15551 (plus:XF (match_dup 12) (match_dup 7)))]
15552 "TARGET_USE_FANCY_MATH_387
15553 && flag_unsafe_math_optimizations"
15557 for (i = 2; i < 13; i++)
15558 operands[i] = gen_reg_rtx (XFmode);
15561 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
15563 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
15566 (define_expand "expm1<mode>2"
15567 [(use (match_operand:MODEF 0 "register_operand"))
15568 (use (match_operand:MODEF 1 "general_operand"))]
15569 "TARGET_USE_FANCY_MATH_387
15570 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15571 || TARGET_MIX_SSE_I387)
15572 && flag_unsafe_math_optimizations"
15576 op0 = gen_reg_rtx (XFmode);
15577 op1 = gen_reg_rtx (XFmode);
15579 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15580 emit_insn (gen_expm1xf2 (op0, op1));
15581 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15585 (define_expand "ldexpxf3"
15586 [(match_operand:XF 0 "register_operand")
15587 (match_operand:XF 1 "register_operand")
15588 (match_operand:SI 2 "register_operand")]
15589 "TARGET_USE_FANCY_MATH_387
15590 && flag_unsafe_math_optimizations"
15594 tmp1 = gen_reg_rtx (XFmode);
15595 tmp2 = gen_reg_rtx (XFmode);
15597 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
15598 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
15599 operands[1], tmp1));
15603 (define_expand "ldexp<mode>3"
15604 [(use (match_operand:MODEF 0 "register_operand"))
15605 (use (match_operand:MODEF 1 "general_operand"))
15606 (use (match_operand:SI 2 "register_operand"))]
15607 "TARGET_USE_FANCY_MATH_387
15608 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15609 || TARGET_MIX_SSE_I387)
15610 && flag_unsafe_math_optimizations"
15614 op0 = gen_reg_rtx (XFmode);
15615 op1 = gen_reg_rtx (XFmode);
15617 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15618 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15619 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15623 (define_expand "scalbxf3"
15624 [(parallel [(set (match_operand:XF 0 " register_operand")
15625 (unspec:XF [(match_operand:XF 1 "register_operand")
15626 (match_operand:XF 2 "register_operand")]
15627 UNSPEC_FSCALE_FRACT))
15629 (unspec:XF [(match_dup 1) (match_dup 2)]
15630 UNSPEC_FSCALE_EXP))])]
15631 "TARGET_USE_FANCY_MATH_387
15632 && flag_unsafe_math_optimizations"
15634 operands[3] = gen_reg_rtx (XFmode);
15637 (define_expand "scalb<mode>3"
15638 [(use (match_operand:MODEF 0 "register_operand"))
15639 (use (match_operand:MODEF 1 "general_operand"))
15640 (use (match_operand:MODEF 2 "general_operand"))]
15641 "TARGET_USE_FANCY_MATH_387
15642 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15643 || TARGET_MIX_SSE_I387)
15644 && flag_unsafe_math_optimizations"
15648 op0 = gen_reg_rtx (XFmode);
15649 op1 = gen_reg_rtx (XFmode);
15650 op2 = gen_reg_rtx (XFmode);
15652 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15653 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15654 emit_insn (gen_scalbxf3 (op0, op1, op2));
15655 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15659 (define_expand "significandxf2"
15660 [(parallel [(set (match_operand:XF 0 "register_operand")
15661 (unspec:XF [(match_operand:XF 1 "register_operand")]
15662 UNSPEC_XTRACT_FRACT))
15664 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15665 "TARGET_USE_FANCY_MATH_387
15666 && flag_unsafe_math_optimizations"
15667 "operands[2] = gen_reg_rtx (XFmode);")
15669 (define_expand "significand<mode>2"
15670 [(use (match_operand:MODEF 0 "register_operand"))
15671 (use (match_operand:MODEF 1 "register_operand"))]
15672 "TARGET_USE_FANCY_MATH_387
15673 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15674 || TARGET_MIX_SSE_I387)
15675 && flag_unsafe_math_optimizations"
15677 rtx op0 = gen_reg_rtx (XFmode);
15678 rtx op1 = gen_reg_rtx (XFmode);
15680 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15681 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15686 (define_insn "sse4_1_round<mode>2"
15687 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
15688 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x,v")
15689 (match_operand:SI 2 "const_0_to_15_operand" "n,n")]
15693 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
15694 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15695 [(set_attr "type" "ssecvt")
15696 (set_attr "prefix_extra" "1,*")
15697 (set_attr "length_immediate" "*,1")
15698 (set_attr "prefix" "maybe_vex,evex")
15699 (set_attr "isa" "noavx512f,avx512f")
15700 (set_attr "mode" "<MODE>")])
15702 (define_insn "rintxf2"
15703 [(set (match_operand:XF 0 "register_operand" "=f")
15704 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15706 "TARGET_USE_FANCY_MATH_387"
15708 [(set_attr "type" "fpspc")
15709 (set_attr "znver1_decode" "vector")
15710 (set_attr "mode" "XF")])
15712 (define_insn "rint<mode>2_frndint"
15713 [(set (match_operand:MODEF 0 "register_operand" "=f")
15714 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "0")]
15716 "TARGET_USE_FANCY_MATH_387"
15718 [(set_attr "type" "fpspc")
15719 (set_attr "znver1_decode" "vector")
15720 (set_attr "mode" "<MODE>")])
15722 (define_expand "rint<mode>2"
15723 [(use (match_operand:MODEF 0 "register_operand"))
15724 (use (match_operand:MODEF 1 "register_operand"))]
15725 "(TARGET_USE_FANCY_MATH_387
15726 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15727 || TARGET_MIX_SSE_I387))
15728 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15730 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15733 emit_insn (gen_sse4_1_round<mode>2
15734 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
15736 ix86_expand_rint (operands[0], operands[1]);
15739 emit_insn (gen_rint<mode>2_frndint (operands[0], operands[1]));
15743 (define_expand "round<mode>2"
15744 [(match_operand:X87MODEF 0 "register_operand")
15745 (match_operand:X87MODEF 1 "nonimmediate_operand")]
15746 "(TARGET_USE_FANCY_MATH_387
15747 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15748 || TARGET_MIX_SSE_I387)
15749 && flag_unsafe_math_optimizations)
15750 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15751 && !flag_trapping_math && !flag_rounding_math)"
15753 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15754 && !flag_trapping_math && !flag_rounding_math)
15758 operands[1] = force_reg (<MODE>mode, operands[1]);
15759 ix86_expand_round_sse4 (operands[0], operands[1]);
15761 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15762 ix86_expand_round (operands[0], operands[1]);
15764 ix86_expand_rounddf_32 (operands[0], operands[1]);
15768 operands[1] = force_reg (<MODE>mode, operands[1]);
15769 ix86_emit_i387_round (operands[0], operands[1]);
15774 (define_insn_and_split "*fistdi2_1"
15775 [(set (match_operand:DI 0 "nonimmediate_operand")
15776 (unspec:DI [(match_operand:XF 1 "register_operand")]
15778 "TARGET_USE_FANCY_MATH_387
15779 && can_create_pseudo_p ()"
15784 if (memory_operand (operands[0], VOIDmode))
15785 emit_insn (gen_fistdi2 (operands[0], operands[1]));
15788 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15789 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15794 [(set_attr "type" "fpspc")
15795 (set_attr "mode" "DI")])
15797 (define_insn "fistdi2"
15798 [(set (match_operand:DI 0 "memory_operand" "=m")
15799 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15801 (clobber (match_scratch:XF 2 "=&1f"))]
15802 "TARGET_USE_FANCY_MATH_387"
15803 "* return output_fix_trunc (insn, operands, false);"
15804 [(set_attr "type" "fpspc")
15805 (set_attr "mode" "DI")])
15807 (define_insn "fistdi2_with_temp"
15808 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15809 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15811 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15812 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15813 "TARGET_USE_FANCY_MATH_387"
15815 [(set_attr "type" "fpspc")
15816 (set_attr "mode" "DI")])
15819 [(set (match_operand:DI 0 "register_operand")
15820 (unspec:DI [(match_operand:XF 1 "register_operand")]
15822 (clobber (match_operand:DI 2 "memory_operand"))
15823 (clobber (match_scratch 3))]
15825 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15826 (clobber (match_dup 3))])
15827 (set (match_dup 0) (match_dup 2))])
15830 [(set (match_operand:DI 0 "memory_operand")
15831 (unspec:DI [(match_operand:XF 1 "register_operand")]
15833 (clobber (match_operand:DI 2 "memory_operand"))
15834 (clobber (match_scratch 3))]
15836 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15837 (clobber (match_dup 3))])])
15839 (define_insn_and_split "*fist<mode>2_1"
15840 [(set (match_operand:SWI24 0 "register_operand")
15841 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15843 "TARGET_USE_FANCY_MATH_387
15844 && can_create_pseudo_p ()"
15849 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15850 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15854 [(set_attr "type" "fpspc")
15855 (set_attr "mode" "<MODE>")])
15857 (define_insn "fist<mode>2"
15858 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15859 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15861 "TARGET_USE_FANCY_MATH_387"
15862 "* return output_fix_trunc (insn, operands, false);"
15863 [(set_attr "type" "fpspc")
15864 (set_attr "mode" "<MODE>")])
15866 (define_insn "fist<mode>2_with_temp"
15867 [(set (match_operand:SWI24 0 "register_operand" "=r")
15868 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15870 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15871 "TARGET_USE_FANCY_MATH_387"
15873 [(set_attr "type" "fpspc")
15874 (set_attr "mode" "<MODE>")])
15877 [(set (match_operand:SWI24 0 "register_operand")
15878 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15880 (clobber (match_operand:SWI24 2 "memory_operand"))]
15882 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15883 (set (match_dup 0) (match_dup 2))])
15886 [(set (match_operand:SWI24 0 "memory_operand")
15887 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15889 (clobber (match_operand:SWI24 2 "memory_operand"))]
15891 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15893 (define_expand "lrintxf<mode>2"
15894 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15895 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15897 "TARGET_USE_FANCY_MATH_387")
15899 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15900 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15901 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15902 UNSPEC_FIX_NOTRUNC))]
15903 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15905 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15906 [(match_operand:SWI248x 0 "nonimmediate_operand")
15907 (match_operand:X87MODEF 1 "register_operand")]
15908 "(TARGET_USE_FANCY_MATH_387
15909 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15910 || TARGET_MIX_SSE_I387)
15911 && flag_unsafe_math_optimizations)
15912 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15913 && <SWI248x:MODE>mode != HImode
15914 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15915 && !flag_trapping_math && !flag_rounding_math)"
15917 if (optimize_insn_for_size_p ())
15920 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15921 && <SWI248x:MODE>mode != HImode
15922 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15923 && !flag_trapping_math && !flag_rounding_math)
15924 ix86_expand_lround (operands[0], operands[1]);
15926 ix86_emit_i387_round (operands[0], operands[1]);
15930 (define_int_iterator FRNDINT_ROUNDING
15931 [UNSPEC_FRNDINT_FLOOR
15932 UNSPEC_FRNDINT_CEIL
15933 UNSPEC_FRNDINT_TRUNC])
15935 (define_int_iterator FIST_ROUNDING
15939 ;; Base name for define_insn
15940 (define_int_attr rounding_insn
15941 [(UNSPEC_FRNDINT_FLOOR "floor")
15942 (UNSPEC_FRNDINT_CEIL "ceil")
15943 (UNSPEC_FRNDINT_TRUNC "btrunc")
15944 (UNSPEC_FIST_FLOOR "floor")
15945 (UNSPEC_FIST_CEIL "ceil")])
15947 (define_int_attr rounding
15948 [(UNSPEC_FRNDINT_FLOOR "floor")
15949 (UNSPEC_FRNDINT_CEIL "ceil")
15950 (UNSPEC_FRNDINT_TRUNC "trunc")
15951 (UNSPEC_FIST_FLOOR "floor")
15952 (UNSPEC_FIST_CEIL "ceil")])
15954 (define_int_attr ROUNDING
15955 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15956 (UNSPEC_FRNDINT_CEIL "CEIL")
15957 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15958 (UNSPEC_FIST_FLOOR "FLOOR")
15959 (UNSPEC_FIST_CEIL "CEIL")])
15961 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15962 (define_insn_and_split "frndint<mode>2_<rounding>"
15963 [(set (match_operand:X87MODEF 0 "register_operand")
15964 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand")]
15966 (clobber (reg:CC FLAGS_REG))]
15967 "TARGET_USE_FANCY_MATH_387
15968 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
15969 && can_create_pseudo_p ()"
15974 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15976 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15977 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15979 emit_insn (gen_frndint<mode>2_<rounding>_i387 (operands[0], operands[1],
15980 operands[2], operands[3]));
15983 [(set_attr "type" "frndint")
15984 (set_attr "i387_cw" "<rounding>")
15985 (set_attr "mode" "<MODE>")])
15987 (define_insn "frndint<mode>2_<rounding>_i387"
15988 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
15989 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand" "0")]
15991 (use (match_operand:HI 2 "memory_operand" "m"))
15992 (use (match_operand:HI 3 "memory_operand" "m"))]
15993 "TARGET_USE_FANCY_MATH_387
15994 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
15995 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15996 [(set_attr "type" "frndint")
15997 (set_attr "i387_cw" "<rounding>")
15998 (set_attr "mode" "<MODE>")])
16000 (define_expand "<rounding_insn>xf2"
16001 [(parallel [(set (match_operand:XF 0 "register_operand")
16002 (unspec:XF [(match_operand:XF 1 "register_operand")]
16004 (clobber (reg:CC FLAGS_REG))])]
16005 "TARGET_USE_FANCY_MATH_387
16006 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
16008 (define_expand "<rounding_insn><mode>2"
16009 [(parallel [(set (match_operand:MODEF 0 "register_operand")
16010 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
16012 (clobber (reg:CC FLAGS_REG))])]
16013 "(TARGET_USE_FANCY_MATH_387
16014 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16015 || TARGET_MIX_SSE_I387)
16016 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16017 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16018 && (TARGET_ROUND || !flag_trapping_math || flag_fp_int_builtin_inexact))"
16020 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16021 && (TARGET_ROUND || !flag_trapping_math || flag_fp_int_builtin_inexact))
16024 emit_insn (gen_sse4_1_round<mode>2
16025 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>
16027 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16029 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16030 ix86_expand_floorceil (operands[0], operands[1], true);
16031 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16032 ix86_expand_floorceil (operands[0], operands[1], false);
16033 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16034 ix86_expand_trunc (operands[0], operands[1]);
16036 gcc_unreachable ();
16040 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16041 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
16042 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16043 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
16044 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16045 ix86_expand_truncdf_32 (operands[0], operands[1]);
16047 gcc_unreachable ();
16051 emit_insn (gen_frndint<mode>2_<rounding> (operands[0], operands[1]));
16055 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16056 (define_insn_and_split "frndintxf2_mask_pm"
16057 [(set (match_operand:XF 0 "register_operand")
16058 (unspec:XF [(match_operand:XF 1 "register_operand")]
16059 UNSPEC_FRNDINT_MASK_PM))
16060 (clobber (reg:CC FLAGS_REG))]
16061 "TARGET_USE_FANCY_MATH_387
16062 && flag_unsafe_math_optimizations
16063 && can_create_pseudo_p ()"
16068 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
16070 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16071 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
16073 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
16074 operands[2], operands[3]));
16077 [(set_attr "type" "frndint")
16078 (set_attr "i387_cw" "mask_pm")
16079 (set_attr "mode" "XF")])
16081 (define_insn "frndintxf2_mask_pm_i387"
16082 [(set (match_operand:XF 0 "register_operand" "=f")
16083 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16084 UNSPEC_FRNDINT_MASK_PM))
16085 (use (match_operand:HI 2 "memory_operand" "m"))
16086 (use (match_operand:HI 3 "memory_operand" "m"))]
16087 "TARGET_USE_FANCY_MATH_387
16088 && flag_unsafe_math_optimizations"
16089 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16090 [(set_attr "type" "frndint")
16091 (set_attr "i387_cw" "mask_pm")
16092 (set_attr "mode" "XF")])
16094 (define_expand "nearbyintxf2"
16095 [(parallel [(set (match_operand:XF 0 "register_operand")
16096 (unspec:XF [(match_operand:XF 1 "register_operand")]
16097 UNSPEC_FRNDINT_MASK_PM))
16098 (clobber (reg:CC FLAGS_REG))])]
16099 "TARGET_USE_FANCY_MATH_387
16100 && flag_unsafe_math_optimizations")
16102 (define_expand "nearbyint<mode>2"
16103 [(use (match_operand:MODEF 0 "register_operand"))
16104 (use (match_operand:MODEF 1 "register_operand"))]
16105 "TARGET_USE_FANCY_MATH_387
16106 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16107 || TARGET_MIX_SSE_I387)
16108 && flag_unsafe_math_optimizations"
16110 rtx op0 = gen_reg_rtx (XFmode);
16111 rtx op1 = gen_reg_rtx (XFmode);
16113 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16114 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16116 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16120 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16121 (define_insn_and_split "*fist<mode>2_<rounding>_1"
16122 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16123 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16125 (clobber (reg:CC FLAGS_REG))]
16126 "TARGET_USE_FANCY_MATH_387
16127 && flag_unsafe_math_optimizations
16128 && can_create_pseudo_p ()"
16133 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16135 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16136 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16137 if (memory_operand (operands[0], VOIDmode))
16138 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
16139 operands[2], operands[3]));
16142 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16143 emit_insn (gen_fist<mode>2_<rounding>_with_temp
16144 (operands[0], operands[1], operands[2],
16145 operands[3], operands[4]));
16149 [(set_attr "type" "fistp")
16150 (set_attr "i387_cw" "<rounding>")
16151 (set_attr "mode" "<MODE>")])
16153 (define_insn "fistdi2_<rounding>"
16154 [(set (match_operand:DI 0 "memory_operand" "=m")
16155 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16157 (use (match_operand:HI 2 "memory_operand" "m"))
16158 (use (match_operand:HI 3 "memory_operand" "m"))
16159 (clobber (match_scratch:XF 4 "=&1f"))]
16160 "TARGET_USE_FANCY_MATH_387
16161 && flag_unsafe_math_optimizations"
16162 "* return output_fix_trunc (insn, operands, false);"
16163 [(set_attr "type" "fistp")
16164 (set_attr "i387_cw" "<rounding>")
16165 (set_attr "mode" "DI")])
16167 (define_insn "fistdi2_<rounding>_with_temp"
16168 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16169 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16171 (use (match_operand:HI 2 "memory_operand" "m,m"))
16172 (use (match_operand:HI 3 "memory_operand" "m,m"))
16173 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
16174 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16175 "TARGET_USE_FANCY_MATH_387
16176 && flag_unsafe_math_optimizations"
16178 [(set_attr "type" "fistp")
16179 (set_attr "i387_cw" "<rounding>")
16180 (set_attr "mode" "DI")])
16183 [(set (match_operand:DI 0 "register_operand")
16184 (unspec:DI [(match_operand:XF 1 "register_operand")]
16186 (use (match_operand:HI 2 "memory_operand"))
16187 (use (match_operand:HI 3 "memory_operand"))
16188 (clobber (match_operand:DI 4 "memory_operand"))
16189 (clobber (match_scratch 5))]
16191 [(parallel [(set (match_dup 4)
16192 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16193 (use (match_dup 2))
16194 (use (match_dup 3))
16195 (clobber (match_dup 5))])
16196 (set (match_dup 0) (match_dup 4))])
16199 [(set (match_operand:DI 0 "memory_operand")
16200 (unspec:DI [(match_operand:XF 1 "register_operand")]
16202 (use (match_operand:HI 2 "memory_operand"))
16203 (use (match_operand:HI 3 "memory_operand"))
16204 (clobber (match_operand:DI 4 "memory_operand"))
16205 (clobber (match_scratch 5))]
16207 [(parallel [(set (match_dup 0)
16208 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16209 (use (match_dup 2))
16210 (use (match_dup 3))
16211 (clobber (match_dup 5))])])
16213 (define_insn "fist<mode>2_<rounding>"
16214 [(set (match_operand:SWI24 0 "memory_operand" "=m")
16215 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16217 (use (match_operand:HI 2 "memory_operand" "m"))
16218 (use (match_operand:HI 3 "memory_operand" "m"))]
16219 "TARGET_USE_FANCY_MATH_387
16220 && flag_unsafe_math_optimizations"
16221 "* return output_fix_trunc (insn, operands, false);"
16222 [(set_attr "type" "fistp")
16223 (set_attr "i387_cw" "<rounding>")
16224 (set_attr "mode" "<MODE>")])
16226 (define_insn "fist<mode>2_<rounding>_with_temp"
16227 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
16228 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
16230 (use (match_operand:HI 2 "memory_operand" "m,m"))
16231 (use (match_operand:HI 3 "memory_operand" "m,m"))
16232 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
16233 "TARGET_USE_FANCY_MATH_387
16234 && flag_unsafe_math_optimizations"
16236 [(set_attr "type" "fistp")
16237 (set_attr "i387_cw" "<rounding>")
16238 (set_attr "mode" "<MODE>")])
16241 [(set (match_operand:SWI24 0 "register_operand")
16242 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16244 (use (match_operand:HI 2 "memory_operand"))
16245 (use (match_operand:HI 3 "memory_operand"))
16246 (clobber (match_operand:SWI24 4 "memory_operand"))]
16248 [(parallel [(set (match_dup 4)
16249 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16250 (use (match_dup 2))
16251 (use (match_dup 3))])
16252 (set (match_dup 0) (match_dup 4))])
16255 [(set (match_operand:SWI24 0 "memory_operand")
16256 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16258 (use (match_operand:HI 2 "memory_operand"))
16259 (use (match_operand:HI 3 "memory_operand"))
16260 (clobber (match_operand:SWI24 4 "memory_operand"))]
16262 [(parallel [(set (match_dup 0)
16263 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16264 (use (match_dup 2))
16265 (use (match_dup 3))])])
16267 (define_expand "l<rounding_insn>xf<mode>2"
16268 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16269 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16271 (clobber (reg:CC FLAGS_REG))])]
16272 "TARGET_USE_FANCY_MATH_387
16273 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16274 && flag_unsafe_math_optimizations")
16276 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
16277 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
16278 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16280 (clobber (reg:CC FLAGS_REG))])]
16281 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16282 && !flag_trapping_math"
16284 if (TARGET_64BIT && optimize_insn_for_size_p ())
16287 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16288 ix86_expand_lfloorceil (operands[0], operands[1], true);
16289 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16290 ix86_expand_lfloorceil (operands[0], operands[1], false);
16292 gcc_unreachable ();
16297 (define_insn "fxam<mode>2_i387"
16298 [(set (match_operand:HI 0 "register_operand" "=a")
16300 [(match_operand:X87MODEF 1 "register_operand" "f")]
16302 "TARGET_USE_FANCY_MATH_387"
16303 "fxam\n\tfnstsw\t%0"
16304 [(set_attr "type" "multi")
16305 (set_attr "length" "4")
16306 (set_attr "unit" "i387")
16307 (set_attr "mode" "<MODE>")])
16309 (define_insn_and_split "fxam<mode>2_i387_with_temp"
16310 [(set (match_operand:HI 0 "register_operand")
16312 [(match_operand:MODEF 1 "memory_operand")]
16314 "TARGET_USE_FANCY_MATH_387
16315 && can_create_pseudo_p ()"
16318 [(set (match_dup 2)(match_dup 1))
16320 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
16322 operands[2] = gen_reg_rtx (<MODE>mode);
16324 MEM_VOLATILE_P (operands[1]) = 1;
16326 [(set_attr "type" "multi")
16327 (set_attr "unit" "i387")
16328 (set_attr "mode" "<MODE>")])
16330 (define_expand "isinfxf2"
16331 [(use (match_operand:SI 0 "register_operand"))
16332 (use (match_operand:XF 1 "register_operand"))]
16333 "TARGET_USE_FANCY_MATH_387
16334 && ix86_libc_has_function (function_c99_misc)"
16336 rtx mask = GEN_INT (0x45);
16337 rtx val = GEN_INT (0x05);
16339 rtx scratch = gen_reg_rtx (HImode);
16340 rtx res = gen_reg_rtx (QImode);
16342 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16344 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
16345 emit_insn (gen_cmpqi_ext_3 (scratch, val));
16346 ix86_expand_setcc (res, EQ,
16347 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
16348 emit_insn (gen_zero_extendqisi2 (operands[0], res));
16352 (define_expand "isinf<mode>2"
16353 [(use (match_operand:SI 0 "register_operand"))
16354 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
16355 "TARGET_USE_FANCY_MATH_387
16356 && ix86_libc_has_function (function_c99_misc)
16357 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16359 rtx mask = GEN_INT (0x45);
16360 rtx val = GEN_INT (0x05);
16362 rtx scratch = gen_reg_rtx (HImode);
16363 rtx res = gen_reg_rtx (QImode);
16365 /* Remove excess precision by forcing value through memory. */
16366 if (memory_operand (operands[1], VOIDmode))
16367 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
16370 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16372 emit_move_insn (temp, operands[1]);
16373 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
16376 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
16377 emit_insn (gen_cmpqi_ext_3 (scratch, val));
16378 ix86_expand_setcc (res, EQ,
16379 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
16380 emit_insn (gen_zero_extendqisi2 (operands[0], res));
16384 (define_expand "signbittf2"
16385 [(use (match_operand:SI 0 "register_operand"))
16386 (use (match_operand:TF 1 "register_operand"))]
16391 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
16392 rtx scratch = gen_reg_rtx (QImode);
16394 emit_insn (gen_ptesttf2 (operands[1], mask));
16395 ix86_expand_setcc (scratch, NE,
16396 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
16398 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
16402 emit_insn (gen_sse_movmskps (operands[0],
16403 gen_lowpart (V4SFmode, operands[1])));
16404 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
16409 (define_expand "signbitxf2"
16410 [(use (match_operand:SI 0 "register_operand"))
16411 (use (match_operand:XF 1 "register_operand"))]
16412 "TARGET_USE_FANCY_MATH_387"
16414 rtx scratch = gen_reg_rtx (HImode);
16416 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16417 emit_insn (gen_andsi3 (operands[0],
16418 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16422 (define_insn "movmsk_df"
16423 [(set (match_operand:SI 0 "register_operand" "=r")
16425 [(match_operand:DF 1 "register_operand" "x")]
16427 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
16428 "%vmovmskpd\t{%1, %0|%0, %1}"
16429 [(set_attr "type" "ssemov")
16430 (set_attr "prefix" "maybe_vex")
16431 (set_attr "mode" "DF")])
16433 ;; Use movmskpd in SSE mode to avoid store forwarding stall
16434 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
16435 (define_expand "signbitdf2"
16436 [(use (match_operand:SI 0 "register_operand"))
16437 (use (match_operand:DF 1 "register_operand"))]
16438 "TARGET_USE_FANCY_MATH_387
16439 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
16441 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
16443 emit_insn (gen_movmsk_df (operands[0], operands[1]));
16444 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
16448 rtx scratch = gen_reg_rtx (HImode);
16450 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
16451 emit_insn (gen_andsi3 (operands[0],
16452 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16457 (define_expand "signbitsf2"
16458 [(use (match_operand:SI 0 "register_operand"))
16459 (use (match_operand:SF 1 "register_operand"))]
16460 "TARGET_USE_FANCY_MATH_387
16461 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
16463 rtx scratch = gen_reg_rtx (HImode);
16465 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
16466 emit_insn (gen_andsi3 (operands[0],
16467 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16471 ;; Block operation instructions
16474 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16477 [(set_attr "length" "1")
16478 (set_attr "length_immediate" "0")
16479 (set_attr "modrm" "0")])
16481 (define_expand "movmem<mode>"
16482 [(use (match_operand:BLK 0 "memory_operand"))
16483 (use (match_operand:BLK 1 "memory_operand"))
16484 (use (match_operand:SWI48 2 "nonmemory_operand"))
16485 (use (match_operand:SWI48 3 "const_int_operand"))
16486 (use (match_operand:SI 4 "const_int_operand"))
16487 (use (match_operand:SI 5 "const_int_operand"))
16488 (use (match_operand:SI 6 ""))
16489 (use (match_operand:SI 7 ""))
16490 (use (match_operand:SI 8 ""))]
16493 if (ix86_expand_set_or_movmem (operands[0], operands[1],
16494 operands[2], NULL, operands[3],
16495 operands[4], operands[5],
16496 operands[6], operands[7],
16497 operands[8], false))
16503 ;; Most CPUs don't like single string operations
16504 ;; Handle this case here to simplify previous expander.
16506 (define_expand "strmov"
16507 [(set (match_dup 4) (match_operand 3 "memory_operand"))
16508 (set (match_operand 1 "memory_operand") (match_dup 4))
16509 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
16510 (clobber (reg:CC FLAGS_REG))])
16511 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
16512 (clobber (reg:CC FLAGS_REG))])]
16515 /* Can't use this for non-default address spaces. */
16516 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
16519 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16521 /* If .md ever supports :P for Pmode, these can be directly
16522 in the pattern above. */
16523 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16524 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16526 /* Can't use this if the user has appropriated esi or edi. */
16527 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16528 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16530 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16531 operands[2], operands[3],
16532 operands[5], operands[6]));
16536 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16539 (define_expand "strmov_singleop"
16540 [(parallel [(set (match_operand 1 "memory_operand")
16541 (match_operand 3 "memory_operand"))
16542 (set (match_operand 0 "register_operand")
16544 (set (match_operand 2 "register_operand")
16545 (match_operand 5))])]
16549 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16552 (define_insn "*strmovdi_rex_1"
16553 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16554 (mem:DI (match_operand:P 3 "register_operand" "1")))
16555 (set (match_operand:P 0 "register_operand" "=D")
16556 (plus:P (match_dup 2)
16558 (set (match_operand:P 1 "register_operand" "=S")
16559 (plus:P (match_dup 3)
16562 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16563 && ix86_check_no_addr_space (insn)"
16565 [(set_attr "type" "str")
16566 (set_attr "memory" "both")
16567 (set_attr "mode" "DI")])
16569 (define_insn "*strmovsi_1"
16570 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16571 (mem:SI (match_operand:P 3 "register_operand" "1")))
16572 (set (match_operand:P 0 "register_operand" "=D")
16573 (plus:P (match_dup 2)
16575 (set (match_operand:P 1 "register_operand" "=S")
16576 (plus:P (match_dup 3)
16578 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16579 && ix86_check_no_addr_space (insn)"
16581 [(set_attr "type" "str")
16582 (set_attr "memory" "both")
16583 (set_attr "mode" "SI")])
16585 (define_insn "*strmovhi_1"
16586 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16587 (mem:HI (match_operand:P 3 "register_operand" "1")))
16588 (set (match_operand:P 0 "register_operand" "=D")
16589 (plus:P (match_dup 2)
16591 (set (match_operand:P 1 "register_operand" "=S")
16592 (plus:P (match_dup 3)
16594 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16595 && ix86_check_no_addr_space (insn)"
16597 [(set_attr "type" "str")
16598 (set_attr "memory" "both")
16599 (set_attr "mode" "HI")])
16601 (define_insn "*strmovqi_1"
16602 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16603 (mem:QI (match_operand:P 3 "register_operand" "1")))
16604 (set (match_operand:P 0 "register_operand" "=D")
16605 (plus:P (match_dup 2)
16607 (set (match_operand:P 1 "register_operand" "=S")
16608 (plus:P (match_dup 3)
16610 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16611 && ix86_check_no_addr_space (insn)"
16613 [(set_attr "type" "str")
16614 (set_attr "memory" "both")
16615 (set (attr "prefix_rex")
16617 (match_test "<P:MODE>mode == DImode")
16619 (const_string "*")))
16620 (set_attr "mode" "QI")])
16622 (define_expand "rep_mov"
16623 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16624 (set (match_operand 0 "register_operand")
16626 (set (match_operand 2 "register_operand")
16628 (set (match_operand 1 "memory_operand")
16629 (match_operand 3 "memory_operand"))
16630 (use (match_dup 4))])]
16634 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16637 (define_insn "*rep_movdi_rex64"
16638 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16639 (set (match_operand:P 0 "register_operand" "=D")
16640 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16642 (match_operand:P 3 "register_operand" "0")))
16643 (set (match_operand:P 1 "register_operand" "=S")
16644 (plus:P (ashift:P (match_dup 5) (const_int 3))
16645 (match_operand:P 4 "register_operand" "1")))
16646 (set (mem:BLK (match_dup 3))
16647 (mem:BLK (match_dup 4)))
16648 (use (match_dup 5))]
16650 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16651 && ix86_check_no_addr_space (insn)"
16653 [(set_attr "type" "str")
16654 (set_attr "prefix_rep" "1")
16655 (set_attr "memory" "both")
16656 (set_attr "mode" "DI")])
16658 (define_insn "*rep_movsi"
16659 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16660 (set (match_operand:P 0 "register_operand" "=D")
16661 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16663 (match_operand:P 3 "register_operand" "0")))
16664 (set (match_operand:P 1 "register_operand" "=S")
16665 (plus:P (ashift:P (match_dup 5) (const_int 2))
16666 (match_operand:P 4 "register_operand" "1")))
16667 (set (mem:BLK (match_dup 3))
16668 (mem:BLK (match_dup 4)))
16669 (use (match_dup 5))]
16670 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16671 && ix86_check_no_addr_space (insn)"
16672 "%^rep{%;} movs{l|d}"
16673 [(set_attr "type" "str")
16674 (set_attr "prefix_rep" "1")
16675 (set_attr "memory" "both")
16676 (set_attr "mode" "SI")])
16678 (define_insn "*rep_movqi"
16679 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16680 (set (match_operand:P 0 "register_operand" "=D")
16681 (plus:P (match_operand:P 3 "register_operand" "0")
16682 (match_operand:P 5 "register_operand" "2")))
16683 (set (match_operand:P 1 "register_operand" "=S")
16684 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16685 (set (mem:BLK (match_dup 3))
16686 (mem:BLK (match_dup 4)))
16687 (use (match_dup 5))]
16688 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16689 && ix86_check_no_addr_space (insn)"
16691 [(set_attr "type" "str")
16692 (set_attr "prefix_rep" "1")
16693 (set_attr "memory" "both")
16694 (set_attr "mode" "QI")])
16696 (define_expand "setmem<mode>"
16697 [(use (match_operand:BLK 0 "memory_operand"))
16698 (use (match_operand:SWI48 1 "nonmemory_operand"))
16699 (use (match_operand:QI 2 "nonmemory_operand"))
16700 (use (match_operand 3 "const_int_operand"))
16701 (use (match_operand:SI 4 "const_int_operand"))
16702 (use (match_operand:SI 5 "const_int_operand"))
16703 (use (match_operand:SI 6 ""))
16704 (use (match_operand:SI 7 ""))
16705 (use (match_operand:SI 8 ""))]
16708 if (ix86_expand_set_or_movmem (operands[0], NULL,
16709 operands[1], operands[2],
16710 operands[3], operands[4],
16711 operands[5], operands[6],
16712 operands[7], operands[8], true))
16718 ;; Most CPUs don't like single string operations
16719 ;; Handle this case here to simplify previous expander.
16721 (define_expand "strset"
16722 [(set (match_operand 1 "memory_operand")
16723 (match_operand 2 "register_operand"))
16724 (parallel [(set (match_operand 0 "register_operand")
16726 (clobber (reg:CC FLAGS_REG))])]
16729 /* Can't use this for non-default address spaces. */
16730 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
16733 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16734 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16736 /* If .md ever supports :P for Pmode, this can be directly
16737 in the pattern above. */
16738 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16739 GEN_INT (GET_MODE_SIZE (GET_MODE
16741 /* Can't use this if the user has appropriated eax or edi. */
16742 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16743 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16745 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16751 (define_expand "strset_singleop"
16752 [(parallel [(set (match_operand 1 "memory_operand")
16753 (match_operand 2 "register_operand"))
16754 (set (match_operand 0 "register_operand")
16756 (unspec [(const_int 0)] UNSPEC_STOS)])]
16760 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16763 (define_insn "*strsetdi_rex_1"
16764 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16765 (match_operand:DI 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)]
16771 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16772 && ix86_check_no_addr_space (insn)"
16774 [(set_attr "type" "str")
16775 (set_attr "memory" "store")
16776 (set_attr "mode" "DI")])
16778 (define_insn "*strsetsi_1"
16779 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16780 (match_operand:SI 2 "register_operand" "a"))
16781 (set (match_operand:P 0 "register_operand" "=D")
16782 (plus:P (match_dup 1)
16784 (unspec [(const_int 0)] UNSPEC_STOS)]
16785 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16786 && ix86_check_no_addr_space (insn)"
16788 [(set_attr "type" "str")
16789 (set_attr "memory" "store")
16790 (set_attr "mode" "SI")])
16792 (define_insn "*strsethi_1"
16793 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16794 (match_operand:HI 2 "register_operand" "a"))
16795 (set (match_operand:P 0 "register_operand" "=D")
16796 (plus:P (match_dup 1)
16798 (unspec [(const_int 0)] UNSPEC_STOS)]
16799 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16800 && ix86_check_no_addr_space (insn)"
16802 [(set_attr "type" "str")
16803 (set_attr "memory" "store")
16804 (set_attr "mode" "HI")])
16806 (define_insn "*strsetqi_1"
16807 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16808 (match_operand:QI 2 "register_operand" "a"))
16809 (set (match_operand:P 0 "register_operand" "=D")
16810 (plus:P (match_dup 1)
16812 (unspec [(const_int 0)] UNSPEC_STOS)]
16813 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16814 && ix86_check_no_addr_space (insn)"
16816 [(set_attr "type" "str")
16817 (set_attr "memory" "store")
16818 (set (attr "prefix_rex")
16820 (match_test "<P:MODE>mode == DImode")
16822 (const_string "*")))
16823 (set_attr "mode" "QI")])
16825 (define_expand "rep_stos"
16826 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16827 (set (match_operand 0 "register_operand")
16829 (set (match_operand 2 "memory_operand") (const_int 0))
16830 (use (match_operand 3 "register_operand"))
16831 (use (match_dup 1))])]
16835 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16838 (define_insn "*rep_stosdi_rex64"
16839 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16840 (set (match_operand:P 0 "register_operand" "=D")
16841 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16843 (match_operand:P 3 "register_operand" "0")))
16844 (set (mem:BLK (match_dup 3))
16846 (use (match_operand:DI 2 "register_operand" "a"))
16847 (use (match_dup 4))]
16849 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16850 && ix86_check_no_addr_space (insn)"
16852 [(set_attr "type" "str")
16853 (set_attr "prefix_rep" "1")
16854 (set_attr "memory" "store")
16855 (set_attr "mode" "DI")])
16857 (define_insn "*rep_stossi"
16858 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16859 (set (match_operand:P 0 "register_operand" "=D")
16860 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16862 (match_operand:P 3 "register_operand" "0")))
16863 (set (mem:BLK (match_dup 3))
16865 (use (match_operand:SI 2 "register_operand" "a"))
16866 (use (match_dup 4))]
16867 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16868 && ix86_check_no_addr_space (insn)"
16869 "%^rep{%;} stos{l|d}"
16870 [(set_attr "type" "str")
16871 (set_attr "prefix_rep" "1")
16872 (set_attr "memory" "store")
16873 (set_attr "mode" "SI")])
16875 (define_insn "*rep_stosqi"
16876 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16877 (set (match_operand:P 0 "register_operand" "=D")
16878 (plus:P (match_operand:P 3 "register_operand" "0")
16879 (match_operand:P 4 "register_operand" "1")))
16880 (set (mem:BLK (match_dup 3))
16882 (use (match_operand:QI 2 "register_operand" "a"))
16883 (use (match_dup 4))]
16884 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16885 && ix86_check_no_addr_space (insn)"
16887 [(set_attr "type" "str")
16888 (set_attr "prefix_rep" "1")
16889 (set_attr "memory" "store")
16890 (set (attr "prefix_rex")
16892 (match_test "<P:MODE>mode == DImode")
16894 (const_string "*")))
16895 (set_attr "mode" "QI")])
16897 (define_expand "cmpstrnsi"
16898 [(set (match_operand:SI 0 "register_operand")
16899 (compare:SI (match_operand:BLK 1 "general_operand")
16900 (match_operand:BLK 2 "general_operand")))
16901 (use (match_operand 3 "general_operand"))
16902 (use (match_operand 4 "immediate_operand"))]
16905 rtx addr1, addr2, out, outlow, count, countreg, align;
16907 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16910 /* Can't use this if the user has appropriated ecx, esi or edi. */
16911 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16914 /* One of the strings must be a constant. If so, expand_builtin_strncmp()
16915 will have rewritten the length arg to be the minimum of the const string
16916 length and the actual length arg. If both strings are the same and
16917 shorter than the length arg, repz cmpsb will not stop at the 0 byte and
16918 will incorrectly base the results on chars past the 0 byte. */
16919 tree t1 = MEM_EXPR (operands[1]);
16920 tree t2 = MEM_EXPR (operands[2]);
16921 if (!((t1 && TREE_CODE (t1) == MEM_REF
16922 && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR
16923 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST)
16924 || (t2 && TREE_CODE (t2) == MEM_REF
16925 && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR
16926 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST)))
16931 out = gen_reg_rtx (SImode);
16933 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16934 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16935 if (addr1 != XEXP (operands[1], 0))
16936 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16937 if (addr2 != XEXP (operands[2], 0))
16938 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16940 count = operands[3];
16941 countreg = ix86_zero_extend_to_Pmode (count);
16943 /* %%% Iff we are testing strict equality, we can use known alignment
16944 to good advantage. This may be possible with combine, particularly
16945 once cc0 is dead. */
16946 align = operands[4];
16948 if (CONST_INT_P (count))
16950 if (INTVAL (count) == 0)
16952 emit_move_insn (operands[0], const0_rtx);
16955 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16956 operands[1], operands[2]));
16960 rtx (*gen_cmp) (rtx, rtx);
16962 gen_cmp = (TARGET_64BIT
16963 ? gen_cmpdi_1 : gen_cmpsi_1);
16965 emit_insn (gen_cmp (countreg, countreg));
16966 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16967 operands[1], operands[2]));
16970 outlow = gen_lowpart (QImode, out);
16971 emit_insn (gen_cmpintqi (outlow));
16972 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16974 if (operands[0] != out)
16975 emit_move_insn (operands[0], out);
16980 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16982 (define_expand "cmpintqi"
16983 [(set (match_dup 1)
16984 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16986 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16987 (parallel [(set (match_operand:QI 0 "register_operand")
16988 (minus:QI (match_dup 1)
16990 (clobber (reg:CC FLAGS_REG))])]
16993 operands[1] = gen_reg_rtx (QImode);
16994 operands[2] = gen_reg_rtx (QImode);
16997 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16998 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
17000 (define_expand "cmpstrnqi_nz_1"
17001 [(parallel [(set (reg:CC FLAGS_REG)
17002 (compare:CC (match_operand 4 "memory_operand")
17003 (match_operand 5 "memory_operand")))
17004 (use (match_operand 2 "register_operand"))
17005 (use (match_operand:SI 3 "immediate_operand"))
17006 (clobber (match_operand 0 "register_operand"))
17007 (clobber (match_operand 1 "register_operand"))
17008 (clobber (match_dup 2))])]
17012 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17015 (define_insn "*cmpstrnqi_nz_1"
17016 [(set (reg:CC FLAGS_REG)
17017 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17018 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
17019 (use (match_operand:P 6 "register_operand" "2"))
17020 (use (match_operand:SI 3 "immediate_operand" "i"))
17021 (clobber (match_operand:P 0 "register_operand" "=S"))
17022 (clobber (match_operand:P 1 "register_operand" "=D"))
17023 (clobber (match_operand:P 2 "register_operand" "=c"))]
17024 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17025 && ix86_check_no_addr_space (insn)"
17027 [(set_attr "type" "str")
17028 (set_attr "mode" "QI")
17029 (set (attr "prefix_rex")
17031 (match_test "<P:MODE>mode == DImode")
17033 (const_string "*")))
17034 (set_attr "prefix_rep" "1")])
17036 ;; The same, but the count is not known to not be zero.
17038 (define_expand "cmpstrnqi_1"
17039 [(parallel [(set (reg:CC FLAGS_REG)
17040 (if_then_else:CC (ne (match_operand 2 "register_operand")
17042 (compare:CC (match_operand 4 "memory_operand")
17043 (match_operand 5 "memory_operand"))
17045 (use (match_operand:SI 3 "immediate_operand"))
17046 (use (reg:CC FLAGS_REG))
17047 (clobber (match_operand 0 "register_operand"))
17048 (clobber (match_operand 1 "register_operand"))
17049 (clobber (match_dup 2))])]
17053 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17056 (define_insn "*cmpstrnqi_1"
17057 [(set (reg:CC FLAGS_REG)
17058 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
17060 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17061 (mem:BLK (match_operand:P 5 "register_operand" "1")))
17063 (use (match_operand:SI 3 "immediate_operand" "i"))
17064 (use (reg:CC FLAGS_REG))
17065 (clobber (match_operand:P 0 "register_operand" "=S"))
17066 (clobber (match_operand:P 1 "register_operand" "=D"))
17067 (clobber (match_operand:P 2 "register_operand" "=c"))]
17068 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17069 && ix86_check_no_addr_space (insn)"
17071 [(set_attr "type" "str")
17072 (set_attr "mode" "QI")
17073 (set (attr "prefix_rex")
17075 (match_test "<P:MODE>mode == DImode")
17077 (const_string "*")))
17078 (set_attr "prefix_rep" "1")])
17080 (define_expand "strlen<mode>"
17081 [(set (match_operand:P 0 "register_operand")
17082 (unspec:P [(match_operand:BLK 1 "general_operand")
17083 (match_operand:QI 2 "immediate_operand")
17084 (match_operand 3 "immediate_operand")]
17088 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17094 (define_expand "strlenqi_1"
17095 [(parallel [(set (match_operand 0 "register_operand")
17097 (clobber (match_operand 1 "register_operand"))
17098 (clobber (reg:CC FLAGS_REG))])]
17102 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17105 (define_insn "*strlenqi_1"
17106 [(set (match_operand:P 0 "register_operand" "=&c")
17107 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
17108 (match_operand:QI 2 "register_operand" "a")
17109 (match_operand:P 3 "immediate_operand" "i")
17110 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
17111 (clobber (match_operand:P 1 "register_operand" "=D"))
17112 (clobber (reg:CC FLAGS_REG))]
17113 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17114 && ix86_check_no_addr_space (insn)"
17115 "%^repnz{%;} scasb"
17116 [(set_attr "type" "str")
17117 (set_attr "mode" "QI")
17118 (set (attr "prefix_rex")
17120 (match_test "<P:MODE>mode == DImode")
17122 (const_string "*")))
17123 (set_attr "prefix_rep" "1")])
17125 ;; Peephole optimizations to clean up after cmpstrn*. This should be
17126 ;; handled in combine, but it is not currently up to the task.
17127 ;; When used for their truth value, the cmpstrn* expanders generate
17136 ;; The intermediate three instructions are unnecessary.
17138 ;; This one handles cmpstrn*_nz_1...
17141 (set (reg:CC FLAGS_REG)
17142 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17143 (mem:BLK (match_operand 5 "register_operand"))))
17144 (use (match_operand 6 "register_operand"))
17145 (use (match_operand:SI 3 "immediate_operand"))
17146 (clobber (match_operand 0 "register_operand"))
17147 (clobber (match_operand 1 "register_operand"))
17148 (clobber (match_operand 2 "register_operand"))])
17149 (set (match_operand:QI 7 "register_operand")
17150 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17151 (set (match_operand:QI 8 "register_operand")
17152 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17153 (set (reg FLAGS_REG)
17154 (compare (match_dup 7) (match_dup 8)))
17156 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17158 (set (reg:CC FLAGS_REG)
17159 (compare:CC (mem:BLK (match_dup 4))
17160 (mem:BLK (match_dup 5))))
17161 (use (match_dup 6))
17162 (use (match_dup 3))
17163 (clobber (match_dup 0))
17164 (clobber (match_dup 1))
17165 (clobber (match_dup 2))])])
17167 ;; ...and this one handles cmpstrn*_1.
17170 (set (reg:CC FLAGS_REG)
17171 (if_then_else:CC (ne (match_operand 6 "register_operand")
17173 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17174 (mem:BLK (match_operand 5 "register_operand")))
17176 (use (match_operand:SI 3 "immediate_operand"))
17177 (use (reg:CC FLAGS_REG))
17178 (clobber (match_operand 0 "register_operand"))
17179 (clobber (match_operand 1 "register_operand"))
17180 (clobber (match_operand 2 "register_operand"))])
17181 (set (match_operand:QI 7 "register_operand")
17182 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17183 (set (match_operand:QI 8 "register_operand")
17184 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17185 (set (reg FLAGS_REG)
17186 (compare (match_dup 7) (match_dup 8)))
17188 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17190 (set (reg:CC FLAGS_REG)
17191 (if_then_else:CC (ne (match_dup 6)
17193 (compare:CC (mem:BLK (match_dup 4))
17194 (mem:BLK (match_dup 5)))
17196 (use (match_dup 3))
17197 (use (reg:CC FLAGS_REG))
17198 (clobber (match_dup 0))
17199 (clobber (match_dup 1))
17200 (clobber (match_dup 2))])])
17202 ;; Conditional move instructions.
17204 (define_expand "mov<mode>cc"
17205 [(set (match_operand:SWIM 0 "register_operand")
17206 (if_then_else:SWIM (match_operand 1 "comparison_operator")
17207 (match_operand:SWIM 2 "<general_operand>")
17208 (match_operand:SWIM 3 "<general_operand>")))]
17210 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
17212 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17213 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17214 ;; So just document what we're doing explicitly.
17216 (define_expand "x86_mov<mode>cc_0_m1"
17218 [(set (match_operand:SWI48 0 "register_operand")
17219 (if_then_else:SWI48
17220 (match_operator:SWI48 2 "ix86_carry_flag_operator"
17221 [(match_operand 1 "flags_reg_operand")
17225 (clobber (reg:CC FLAGS_REG))])])
17227 (define_insn "*x86_mov<mode>cc_0_m1"
17228 [(set (match_operand:SWI48 0 "register_operand" "=r")
17229 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17230 [(reg FLAGS_REG) (const_int 0)])
17233 (clobber (reg:CC FLAGS_REG))]
17235 "sbb{<imodesuffix>}\t%0, %0"
17236 ; Since we don't have the proper number of operands for an alu insn,
17237 ; fill in all the blanks.
17238 [(set_attr "type" "alu")
17239 (set_attr "modrm_class" "op0")
17240 (set_attr "use_carry" "1")
17241 (set_attr "pent_pair" "pu")
17242 (set_attr "memory" "none")
17243 (set_attr "imm_disp" "false")
17244 (set_attr "mode" "<MODE>")
17245 (set_attr "length_immediate" "0")])
17247 (define_insn "*x86_mov<mode>cc_0_m1_se"
17248 [(set (match_operand:SWI48 0 "register_operand" "=r")
17249 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17250 [(reg FLAGS_REG) (const_int 0)])
17253 (clobber (reg:CC FLAGS_REG))]
17255 "sbb{<imodesuffix>}\t%0, %0"
17256 [(set_attr "type" "alu")
17257 (set_attr "modrm_class" "op0")
17258 (set_attr "use_carry" "1")
17259 (set_attr "pent_pair" "pu")
17260 (set_attr "memory" "none")
17261 (set_attr "imm_disp" "false")
17262 (set_attr "mode" "<MODE>")
17263 (set_attr "length_immediate" "0")])
17265 (define_insn "*x86_mov<mode>cc_0_m1_neg"
17266 [(set (match_operand:SWI48 0 "register_operand" "=r")
17267 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17268 [(reg FLAGS_REG) (const_int 0)])))
17269 (clobber (reg:CC FLAGS_REG))]
17271 "sbb{<imodesuffix>}\t%0, %0"
17272 [(set_attr "type" "alu")
17273 (set_attr "modrm_class" "op0")
17274 (set_attr "use_carry" "1")
17275 (set_attr "pent_pair" "pu")
17276 (set_attr "memory" "none")
17277 (set_attr "imm_disp" "false")
17278 (set_attr "mode" "<MODE>")
17279 (set_attr "length_immediate" "0")])
17281 (define_insn "*mov<mode>cc_noc"
17282 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
17283 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17284 [(reg FLAGS_REG) (const_int 0)])
17285 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
17286 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
17287 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17289 cmov%O2%C1\t{%2, %0|%0, %2}
17290 cmov%O2%c1\t{%3, %0|%0, %3}"
17291 [(set_attr "type" "icmov")
17292 (set_attr "mode" "<MODE>")])
17294 (define_insn "*movsicc_noc_zext"
17295 [(set (match_operand:DI 0 "register_operand" "=r,r")
17296 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17297 [(reg FLAGS_REG) (const_int 0)])
17299 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
17301 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
17303 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17305 cmov%O2%C1\t{%2, %k0|%k0, %2}
17306 cmov%O2%c1\t{%3, %k0|%k0, %3}"
17307 [(set_attr "type" "icmov")
17308 (set_attr "mode" "SI")])
17310 ;; Don't do conditional moves with memory inputs. This splitter helps
17311 ;; register starved x86_32 by forcing inputs into registers before reload.
17313 [(set (match_operand:SWI248 0 "register_operand")
17314 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17315 [(reg FLAGS_REG) (const_int 0)])
17316 (match_operand:SWI248 2 "nonimmediate_operand")
17317 (match_operand:SWI248 3 "nonimmediate_operand")))]
17318 "!TARGET_64BIT && TARGET_CMOVE
17319 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17320 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17321 && can_create_pseudo_p ()
17322 && optimize_insn_for_speed_p ()"
17323 [(set (match_dup 0)
17324 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17326 if (MEM_P (operands[2]))
17327 operands[2] = force_reg (<MODE>mode, operands[2]);
17328 if (MEM_P (operands[3]))
17329 operands[3] = force_reg (<MODE>mode, operands[3]);
17332 (define_insn "*movqicc_noc"
17333 [(set (match_operand:QI 0 "register_operand" "=r,r")
17334 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17335 [(reg FLAGS_REG) (const_int 0)])
17336 (match_operand:QI 2 "register_operand" "r,0")
17337 (match_operand:QI 3 "register_operand" "0,r")))]
17338 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17340 [(set_attr "type" "icmov")
17341 (set_attr "mode" "QI")])
17344 [(set (match_operand:SWI12 0 "register_operand")
17345 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
17346 [(reg FLAGS_REG) (const_int 0)])
17347 (match_operand:SWI12 2 "register_operand")
17348 (match_operand:SWI12 3 "register_operand")))]
17349 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
17350 && reload_completed"
17351 [(set (match_dup 0)
17352 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17354 operands[0] = gen_lowpart (SImode, operands[0]);
17355 operands[2] = gen_lowpart (SImode, operands[2]);
17356 operands[3] = gen_lowpart (SImode, operands[3]);
17359 ;; Don't do conditional moves with memory inputs
17361 [(match_scratch:SWI248 4 "r")
17362 (set (match_operand:SWI248 0 "register_operand")
17363 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17364 [(reg FLAGS_REG) (const_int 0)])
17365 (match_operand:SWI248 2 "nonimmediate_operand")
17366 (match_operand:SWI248 3 "nonimmediate_operand")))]
17367 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17368 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17369 && optimize_insn_for_speed_p ()"
17370 [(set (match_dup 4) (match_dup 5))
17372 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17374 if (MEM_P (operands[2]))
17376 operands[5] = operands[2];
17377 operands[2] = operands[4];
17379 else if (MEM_P (operands[3]))
17381 operands[5] = operands[3];
17382 operands[3] = operands[4];
17385 gcc_unreachable ();
17389 [(match_scratch:SI 4 "r")
17390 (set (match_operand:DI 0 "register_operand")
17391 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17392 [(reg FLAGS_REG) (const_int 0)])
17394 (match_operand:SI 2 "nonimmediate_operand"))
17396 (match_operand:SI 3 "nonimmediate_operand"))))]
17398 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17399 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17400 && optimize_insn_for_speed_p ()"
17401 [(set (match_dup 4) (match_dup 5))
17403 (if_then_else:DI (match_dup 1)
17404 (zero_extend:DI (match_dup 2))
17405 (zero_extend:DI (match_dup 3))))]
17407 if (MEM_P (operands[2]))
17409 operands[5] = operands[2];
17410 operands[2] = operands[4];
17412 else if (MEM_P (operands[3]))
17414 operands[5] = operands[3];
17415 operands[3] = operands[4];
17418 gcc_unreachable ();
17421 (define_expand "mov<mode>cc"
17422 [(set (match_operand:X87MODEF 0 "register_operand")
17423 (if_then_else:X87MODEF
17424 (match_operand 1 "comparison_operator")
17425 (match_operand:X87MODEF 2 "register_operand")
17426 (match_operand:X87MODEF 3 "register_operand")))]
17427 "(TARGET_80387 && TARGET_CMOVE)
17428 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17429 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
17431 (define_insn "*movxfcc_1"
17432 [(set (match_operand:XF 0 "register_operand" "=f,f")
17433 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17434 [(reg FLAGS_REG) (const_int 0)])
17435 (match_operand:XF 2 "register_operand" "f,0")
17436 (match_operand:XF 3 "register_operand" "0,f")))]
17437 "TARGET_80387 && TARGET_CMOVE"
17439 fcmov%F1\t{%2, %0|%0, %2}
17440 fcmov%f1\t{%3, %0|%0, %3}"
17441 [(set_attr "type" "fcmov")
17442 (set_attr "mode" "XF")])
17444 (define_insn "*movdfcc_1"
17445 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
17446 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17447 [(reg FLAGS_REG) (const_int 0)])
17448 (match_operand:DF 2 "nonimmediate_operand"
17450 (match_operand:DF 3 "nonimmediate_operand"
17451 "0 ,f,0 ,rm,0, rm")))]
17452 "TARGET_80387 && TARGET_CMOVE
17453 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17455 fcmov%F1\t{%2, %0|%0, %2}
17456 fcmov%f1\t{%3, %0|%0, %3}
17459 cmov%O2%C1\t{%2, %0|%0, %2}
17460 cmov%O2%c1\t{%3, %0|%0, %3}"
17461 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
17462 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
17463 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
17466 [(set (match_operand:DF 0 "general_reg_operand")
17467 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17468 [(reg FLAGS_REG) (const_int 0)])
17469 (match_operand:DF 2 "nonimmediate_operand")
17470 (match_operand:DF 3 "nonimmediate_operand")))]
17471 "!TARGET_64BIT && reload_completed"
17472 [(set (match_dup 2)
17473 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
17475 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
17477 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
17478 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
17481 (define_insn "*movsfcc_1_387"
17482 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
17483 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17484 [(reg FLAGS_REG) (const_int 0)])
17485 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
17486 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
17487 "TARGET_80387 && TARGET_CMOVE
17488 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17490 fcmov%F1\t{%2, %0|%0, %2}
17491 fcmov%f1\t{%3, %0|%0, %3}
17492 cmov%O2%C1\t{%2, %0|%0, %2}
17493 cmov%O2%c1\t{%3, %0|%0, %3}"
17494 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17495 (set_attr "mode" "SF,SF,SI,SI")])
17497 ;; Don't do conditional moves with memory inputs. This splitter helps
17498 ;; register starved x86_32 by forcing inputs into registers before reload.
17500 [(set (match_operand:MODEF 0 "register_operand")
17501 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
17502 [(reg FLAGS_REG) (const_int 0)])
17503 (match_operand:MODEF 2 "nonimmediate_operand")
17504 (match_operand:MODEF 3 "nonimmediate_operand")))]
17505 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17506 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17507 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17508 && can_create_pseudo_p ()
17509 && optimize_insn_for_speed_p ()"
17510 [(set (match_dup 0)
17511 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17513 if (MEM_P (operands[2]))
17514 operands[2] = force_reg (<MODE>mode, operands[2]);
17515 if (MEM_P (operands[3]))
17516 operands[3] = force_reg (<MODE>mode, operands[3]);
17519 ;; Don't do conditional moves with memory inputs
17521 [(match_scratch:MODEF 4 "r")
17522 (set (match_operand:MODEF 0 "general_reg_operand")
17523 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
17524 [(reg FLAGS_REG) (const_int 0)])
17525 (match_operand:MODEF 2 "nonimmediate_operand")
17526 (match_operand:MODEF 3 "nonimmediate_operand")))]
17527 "(<MODE>mode != DFmode || TARGET_64BIT)
17528 && TARGET_80387 && TARGET_CMOVE
17529 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17530 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17531 && optimize_insn_for_speed_p ()"
17532 [(set (match_dup 4) (match_dup 5))
17534 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17536 if (MEM_P (operands[2]))
17538 operands[5] = operands[2];
17539 operands[2] = operands[4];
17541 else if (MEM_P (operands[3]))
17543 operands[5] = operands[3];
17544 operands[3] = operands[4];
17547 gcc_unreachable ();
17550 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
17551 ;; the scalar versions to have only XMM registers as operands.
17553 ;; XOP conditional move
17554 (define_insn "*xop_pcmov_<mode>"
17555 [(set (match_operand:MODEF 0 "register_operand" "=x")
17556 (if_then_else:MODEF
17557 (match_operand:MODEF 1 "register_operand" "x")
17558 (match_operand:MODEF 2 "register_operand" "x")
17559 (match_operand:MODEF 3 "register_operand" "x")))]
17561 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
17562 [(set_attr "type" "sse4arg")])
17564 ;; These versions of the min/max patterns are intentionally ignorant of
17565 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17566 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17567 ;; are undefined in this condition, we're certain this is correct.
17569 (define_insn "<code><mode>3"
17570 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17572 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
17573 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
17574 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17576 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
17577 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17578 [(set_attr "isa" "noavx,avx")
17579 (set_attr "prefix" "orig,vex")
17580 (set_attr "type" "sseadd")
17581 (set_attr "mode" "<MODE>")])
17583 ;; These versions of the min/max patterns implement exactly the operations
17584 ;; min = (op1 < op2 ? op1 : op2)
17585 ;; max = (!(op1 < op2) ? op1 : op2)
17586 ;; Their operands are not commutative, and thus they may be used in the
17587 ;; presence of -0.0 and NaN.
17589 (define_insn "*ieee_s<ieee_maxmin><mode>3"
17590 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17592 [(match_operand:MODEF 1 "register_operand" "0,v")
17593 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
17595 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17597 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
17598 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17599 [(set_attr "isa" "noavx,avx")
17600 (set_attr "prefix" "orig,maybe_evex")
17601 (set_attr "type" "sseadd")
17602 (set_attr "mode" "<MODE>")])
17604 ;; Make two stack loads independent:
17606 ;; fld %st(0) -> fld bb
17607 ;; fmul bb fmul %st(1), %st
17609 ;; Actually we only match the last two instructions for simplicity.
17612 [(set (match_operand 0 "fp_register_operand")
17613 (match_operand 1 "fp_register_operand"))
17615 (match_operator 2 "binary_fp_operator"
17617 (match_operand 3 "memory_operand")]))]
17618 "REGNO (operands[0]) != REGNO (operands[1])"
17619 [(set (match_dup 0) (match_dup 3))
17622 [(match_dup 5) (match_dup 4)]))]
17624 operands[4] = operands[0];
17625 operands[5] = operands[1];
17627 /* The % modifier is not operational anymore in peephole2's, so we have to
17628 swap the operands manually in the case of addition and multiplication. */
17629 if (COMMUTATIVE_ARITH_P (operands[2]))
17630 std::swap (operands[4], operands[5]);
17634 [(set (match_operand 0 "fp_register_operand")
17635 (match_operand 1 "fp_register_operand"))
17637 (match_operator 2 "binary_fp_operator"
17638 [(match_operand 3 "memory_operand")
17640 "REGNO (operands[0]) != REGNO (operands[1])"
17641 [(set (match_dup 0) (match_dup 3))
17644 [(match_dup 4) (match_dup 5)]))]
17646 operands[4] = operands[0];
17647 operands[5] = operands[1];
17649 /* The % modifier is not operational anymore in peephole2's, so we have to
17650 swap the operands manually in the case of addition and multiplication. */
17651 if (COMMUTATIVE_ARITH_P (operands[2]))
17652 std::swap (operands[4], operands[5]);
17655 ;; Conditional addition patterns
17656 (define_expand "add<mode>cc"
17657 [(match_operand:SWI 0 "register_operand")
17658 (match_operand 1 "ordered_comparison_operator")
17659 (match_operand:SWI 2 "register_operand")
17660 (match_operand:SWI 3 "const_int_operand")]
17662 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17664 ;; Misc patterns (?)
17666 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17667 ;; Otherwise there will be nothing to keep
17669 ;; [(set (reg ebp) (reg esp))]
17670 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17671 ;; (clobber (eflags)]
17672 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17674 ;; in proper program order.
17676 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
17677 [(set (match_operand:P 0 "register_operand" "=r,r")
17678 (plus:P (match_operand:P 1 "register_operand" "0,r")
17679 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17680 (clobber (reg:CC FLAGS_REG))
17681 (clobber (mem:BLK (scratch)))]
17684 switch (get_attr_type (insn))
17687 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17690 gcc_assert (rtx_equal_p (operands[0], operands[1]));
17691 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17692 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17694 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17697 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17698 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17701 [(set (attr "type")
17702 (cond [(and (eq_attr "alternative" "0")
17703 (not (match_test "TARGET_OPT_AGU")))
17704 (const_string "alu")
17705 (match_operand:<MODE> 2 "const0_operand")
17706 (const_string "imov")
17708 (const_string "lea")))
17709 (set (attr "length_immediate")
17710 (cond [(eq_attr "type" "imov")
17712 (and (eq_attr "type" "alu")
17713 (match_operand 2 "const128_operand"))
17716 (const_string "*")))
17717 (set_attr "mode" "<MODE>")])
17719 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
17720 [(set (match_operand:P 0 "register_operand" "=r")
17721 (minus:P (match_operand:P 1 "register_operand" "0")
17722 (match_operand:P 2 "register_operand" "r")))
17723 (clobber (reg:CC FLAGS_REG))
17724 (clobber (mem:BLK (scratch)))]
17726 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17727 [(set_attr "type" "alu")
17728 (set_attr "mode" "<MODE>")])
17730 (define_insn "allocate_stack_worker_probe_<mode>"
17731 [(set (match_operand:P 0 "register_operand" "=a")
17732 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17733 UNSPECV_STACK_PROBE))
17734 (clobber (reg:CC FLAGS_REG))]
17735 "ix86_target_stack_probe ()"
17736 "call\t___chkstk_ms"
17737 [(set_attr "type" "multi")
17738 (set_attr "length" "5")])
17740 (define_expand "allocate_stack"
17741 [(match_operand 0 "register_operand")
17742 (match_operand 1 "general_operand")]
17743 "ix86_target_stack_probe ()"
17747 #ifndef CHECK_STACK_LIMIT
17748 #define CHECK_STACK_LIMIT 0
17751 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17752 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17756 rtx (*insn) (rtx, rtx);
17758 x = copy_to_mode_reg (Pmode, operands[1]);
17760 insn = (TARGET_64BIT
17761 ? gen_allocate_stack_worker_probe_di
17762 : gen_allocate_stack_worker_probe_si);
17764 emit_insn (insn (x, x));
17767 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17768 stack_pointer_rtx, 0, OPTAB_DIRECT);
17770 if (x != stack_pointer_rtx)
17771 emit_move_insn (stack_pointer_rtx, x);
17773 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17777 (define_expand "probe_stack"
17778 [(match_operand 0 "memory_operand")]
17781 rtx (*insn) (rtx, rtx)
17782 = (GET_MODE (operands[0]) == DImode
17783 ? gen_probe_stack_di : gen_probe_stack_si);
17785 emit_insn (insn (operands[0], const0_rtx));
17789 ;; Use OR for stack probes, this is shorter.
17790 (define_insn "probe_stack_<mode>"
17791 [(set (match_operand:W 0 "memory_operand" "=m")
17792 (unspec:W [(match_operand:W 1 "const0_operand")]
17793 UNSPEC_PROBE_STACK))
17794 (clobber (reg:CC FLAGS_REG))]
17796 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
17797 [(set_attr "type" "alu1")
17798 (set_attr "mode" "<MODE>")
17799 (set_attr "length_immediate" "1")])
17801 (define_insn "adjust_stack_and_probe<mode>"
17802 [(set (match_operand:P 0 "register_operand" "=r")
17803 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17804 UNSPECV_PROBE_STACK_RANGE))
17805 (set (reg:P SP_REG)
17806 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17807 (clobber (reg:CC FLAGS_REG))
17808 (clobber (mem:BLK (scratch)))]
17810 "* return output_adjust_stack_and_probe (operands[0]);"
17811 [(set_attr "type" "multi")])
17813 (define_insn "probe_stack_range<mode>"
17814 [(set (match_operand:P 0 "register_operand" "=r")
17815 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17816 (match_operand:P 2 "const_int_operand" "n")]
17817 UNSPECV_PROBE_STACK_RANGE))
17818 (clobber (reg:CC FLAGS_REG))]
17820 "* return output_probe_stack_range (operands[0], operands[2]);"
17821 [(set_attr "type" "multi")])
17823 (define_expand "builtin_setjmp_receiver"
17824 [(label_ref (match_operand 0))]
17825 "!TARGET_64BIT && flag_pic"
17831 rtx_code_label *label_rtx = gen_label_rtx ();
17832 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17833 xops[0] = xops[1] = pic_offset_table_rtx;
17834 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17835 ix86_expand_binary_operator (MINUS, SImode, xops);
17839 emit_insn (gen_set_got (pic_offset_table_rtx));
17843 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17844 ;; Do not split instructions with mask registers.
17846 [(set (match_operand 0 "general_reg_operand")
17847 (match_operator 3 "promotable_binary_operator"
17848 [(match_operand 1 "general_reg_operand")
17849 (match_operand 2 "aligned_operand")]))
17850 (clobber (reg:CC FLAGS_REG))]
17851 "! TARGET_PARTIAL_REG_STALL && reload_completed
17852 && ((GET_MODE (operands[0]) == HImode
17853 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17854 /* ??? next two lines just !satisfies_constraint_K (...) */
17855 || !CONST_INT_P (operands[2])
17856 || satisfies_constraint_K (operands[2])))
17857 || (GET_MODE (operands[0]) == QImode
17858 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17859 [(parallel [(set (match_dup 0)
17860 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17861 (clobber (reg:CC FLAGS_REG))])]
17863 operands[0] = gen_lowpart (SImode, operands[0]);
17864 operands[1] = gen_lowpart (SImode, operands[1]);
17865 if (GET_CODE (operands[3]) != ASHIFT)
17866 operands[2] = gen_lowpart (SImode, operands[2]);
17867 operands[3] = shallow_copy_rtx (operands[3]);
17868 PUT_MODE (operands[3], SImode);
17871 ; Promote the QImode tests, as i386 has encoding of the AND
17872 ; instruction with 32-bit sign-extended immediate and thus the
17873 ; instruction size is unchanged, except in the %eax case for
17874 ; which it is increased by one byte, hence the ! optimize_size.
17876 [(set (match_operand 0 "flags_reg_operand")
17877 (match_operator 2 "compare_operator"
17878 [(and (match_operand 3 "aligned_operand")
17879 (match_operand 4 "const_int_operand"))
17881 (set (match_operand 1 "register_operand")
17882 (and (match_dup 3) (match_dup 4)))]
17883 "! TARGET_PARTIAL_REG_STALL && reload_completed
17884 && optimize_insn_for_speed_p ()
17885 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17886 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17887 /* Ensure that the operand will remain sign-extended immediate. */
17888 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17889 [(parallel [(set (match_dup 0)
17890 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17893 (and:SI (match_dup 3) (match_dup 4)))])]
17896 = gen_int_mode (INTVAL (operands[4])
17897 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17898 operands[1] = gen_lowpart (SImode, operands[1]);
17899 operands[3] = gen_lowpart (SImode, operands[3]);
17902 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17903 ; the TEST instruction with 32-bit sign-extended immediate and thus
17904 ; the instruction size would at least double, which is not what we
17905 ; want even with ! optimize_size.
17907 [(set (match_operand 0 "flags_reg_operand")
17908 (match_operator 1 "compare_operator"
17909 [(and (match_operand:HI 2 "aligned_operand")
17910 (match_operand:HI 3 "const_int_operand"))
17912 "! TARGET_PARTIAL_REG_STALL && reload_completed
17913 && ! TARGET_FAST_PREFIX
17914 && optimize_insn_for_speed_p ()
17915 /* Ensure that the operand will remain sign-extended immediate. */
17916 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17917 [(set (match_dup 0)
17918 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17922 = gen_int_mode (INTVAL (operands[3])
17923 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17924 operands[2] = gen_lowpart (SImode, operands[2]);
17928 [(set (match_operand 0 "register_operand")
17929 (neg (match_operand 1 "register_operand")))
17930 (clobber (reg:CC FLAGS_REG))]
17931 "! TARGET_PARTIAL_REG_STALL && reload_completed
17932 && (GET_MODE (operands[0]) == HImode
17933 || (GET_MODE (operands[0]) == QImode
17934 && (TARGET_PROMOTE_QImode
17935 || optimize_insn_for_size_p ())))"
17936 [(parallel [(set (match_dup 0)
17937 (neg:SI (match_dup 1)))
17938 (clobber (reg:CC FLAGS_REG))])]
17940 operands[0] = gen_lowpart (SImode, operands[0]);
17941 operands[1] = gen_lowpart (SImode, operands[1]);
17944 ;; Do not split instructions with mask regs.
17946 [(set (match_operand 0 "general_reg_operand")
17947 (not (match_operand 1 "general_reg_operand")))]
17948 "! TARGET_PARTIAL_REG_STALL && reload_completed
17949 && (GET_MODE (operands[0]) == HImode
17950 || (GET_MODE (operands[0]) == QImode
17951 && (TARGET_PROMOTE_QImode
17952 || optimize_insn_for_size_p ())))"
17953 [(set (match_dup 0)
17954 (not:SI (match_dup 1)))]
17956 operands[0] = gen_lowpart (SImode, operands[0]);
17957 operands[1] = gen_lowpart (SImode, operands[1]);
17960 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17961 ;; transform a complex memory operation into two memory to register operations.
17963 ;; Don't push memory operands
17965 [(set (match_operand:SWI 0 "push_operand")
17966 (match_operand:SWI 1 "memory_operand"))
17967 (match_scratch:SWI 2 "<r>")]
17968 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17969 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17970 [(set (match_dup 2) (match_dup 1))
17971 (set (match_dup 0) (match_dup 2))])
17973 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17976 [(set (match_operand:SF 0 "push_operand")
17977 (match_operand:SF 1 "memory_operand"))
17978 (match_scratch:SF 2 "r")]
17979 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17980 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17981 [(set (match_dup 2) (match_dup 1))
17982 (set (match_dup 0) (match_dup 2))])
17984 ;; Don't move an immediate directly to memory when the instruction
17985 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17987 [(match_scratch:SWI124 1 "<r>")
17988 (set (match_operand:SWI124 0 "memory_operand")
17990 "optimize_insn_for_speed_p ()
17991 && ((<MODE>mode == HImode
17992 && TARGET_LCP_STALL)
17993 || (!TARGET_USE_MOV0
17994 && TARGET_SPLIT_LONG_MOVES
17995 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17996 && peep2_regno_dead_p (0, FLAGS_REG)"
17997 [(parallel [(set (match_dup 2) (const_int 0))
17998 (clobber (reg:CC FLAGS_REG))])
17999 (set (match_dup 0) (match_dup 1))]
18000 "operands[2] = gen_lowpart (SImode, operands[1]);")
18003 [(match_scratch:SWI124 2 "<r>")
18004 (set (match_operand:SWI124 0 "memory_operand")
18005 (match_operand:SWI124 1 "immediate_operand"))]
18006 "optimize_insn_for_speed_p ()
18007 && ((<MODE>mode == HImode
18008 && TARGET_LCP_STALL)
18009 || (TARGET_SPLIT_LONG_MOVES
18010 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
18011 [(set (match_dup 2) (match_dup 1))
18012 (set (match_dup 0) (match_dup 2))])
18014 ;; Don't compare memory with zero, load and use a test instead.
18016 [(set (match_operand 0 "flags_reg_operand")
18017 (match_operator 1 "compare_operator"
18018 [(match_operand:SI 2 "memory_operand")
18020 (match_scratch:SI 3 "r")]
18021 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
18022 [(set (match_dup 3) (match_dup 2))
18023 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
18025 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18026 ;; Don't split NOTs with a displacement operand, because resulting XOR
18027 ;; will not be pairable anyway.
18029 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18030 ;; represented using a modRM byte. The XOR replacement is long decoded,
18031 ;; so this split helps here as well.
18033 ;; Note: Can't do this as a regular split because we can't get proper
18034 ;; lifetime information then.
18037 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
18038 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
18039 "optimize_insn_for_speed_p ()
18040 && ((TARGET_NOT_UNPAIRABLE
18041 && (!MEM_P (operands[0])
18042 || !memory_displacement_operand (operands[0], <MODE>mode)))
18043 || (TARGET_NOT_VECTORMODE
18044 && long_memory_operand (operands[0], <MODE>mode)))
18045 && peep2_regno_dead_p (0, FLAGS_REG)"
18046 [(parallel [(set (match_dup 0)
18047 (xor:SWI124 (match_dup 1) (const_int -1)))
18048 (clobber (reg:CC FLAGS_REG))])])
18050 ;; Non pairable "test imm, reg" instructions can be translated to
18051 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18052 ;; byte opcode instead of two, have a short form for byte operands),
18053 ;; so do it for other CPUs as well. Given that the value was dead,
18054 ;; this should not create any new dependencies. Pass on the sub-word
18055 ;; versions if we're concerned about partial register stalls.
18058 [(set (match_operand 0 "flags_reg_operand")
18059 (match_operator 1 "compare_operator"
18060 [(and:SI (match_operand:SI 2 "register_operand")
18061 (match_operand:SI 3 "immediate_operand"))
18063 "ix86_match_ccmode (insn, CCNOmode)
18064 && (REGNO (operands[2]) != AX_REG
18065 || satisfies_constraint_K (operands[3]))
18066 && peep2_reg_dead_p (1, operands[2])"
18068 [(set (match_dup 0)
18069 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18072 (and:SI (match_dup 2) (match_dup 3)))])])
18074 ;; We don't need to handle HImode case, because it will be promoted to SImode
18075 ;; on ! TARGET_PARTIAL_REG_STALL
18078 [(set (match_operand 0 "flags_reg_operand")
18079 (match_operator 1 "compare_operator"
18080 [(and:QI (match_operand:QI 2 "register_operand")
18081 (match_operand:QI 3 "immediate_operand"))
18083 "! TARGET_PARTIAL_REG_STALL
18084 && ix86_match_ccmode (insn, CCNOmode)
18085 && REGNO (operands[2]) != AX_REG
18086 && peep2_reg_dead_p (1, operands[2])"
18088 [(set (match_dup 0)
18089 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18092 (and:QI (match_dup 2) (match_dup 3)))])])
18095 [(set (match_operand 0 "flags_reg_operand")
18096 (match_operator 1 "compare_operator"
18099 (match_operand 2 "QIreg_operand")
18102 (match_operand 3 "const_int_operand"))
18104 "! TARGET_PARTIAL_REG_STALL
18105 && ix86_match_ccmode (insn, CCNOmode)
18106 && REGNO (operands[2]) != AX_REG
18107 && peep2_reg_dead_p (1, operands[2])"
18108 [(parallel [(set (match_dup 0)
18117 (set (zero_extract:SI (match_dup 2)
18125 (match_dup 3)))])])
18127 ;; Don't do logical operations with memory inputs.
18129 [(match_scratch:SWI 2 "<r>")
18130 (parallel [(set (match_operand:SWI 0 "register_operand")
18131 (match_operator:SWI 3 "arith_or_logical_operator"
18133 (match_operand:SWI 1 "memory_operand")]))
18134 (clobber (reg:CC FLAGS_REG))])]
18135 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18136 [(set (match_dup 2) (match_dup 1))
18137 (parallel [(set (match_dup 0)
18138 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18139 (clobber (reg:CC FLAGS_REG))])])
18142 [(match_scratch:SWI 2 "<r>")
18143 (parallel [(set (match_operand:SWI 0 "register_operand")
18144 (match_operator:SWI 3 "arith_or_logical_operator"
18145 [(match_operand:SWI 1 "memory_operand")
18147 (clobber (reg:CC FLAGS_REG))])]
18148 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18149 [(set (match_dup 2) (match_dup 1))
18150 (parallel [(set (match_dup 0)
18151 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18152 (clobber (reg:CC FLAGS_REG))])])
18154 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
18155 ;; the memory address refers to the destination of the load!
18158 [(set (match_operand:SWI 0 "general_reg_operand")
18159 (match_operand:SWI 1 "general_reg_operand"))
18160 (parallel [(set (match_dup 0)
18161 (match_operator:SWI 3 "commutative_operator"
18163 (match_operand:SWI 2 "memory_operand")]))
18164 (clobber (reg:CC FLAGS_REG))])]
18165 "REGNO (operands[0]) != REGNO (operands[1])
18166 && (<MODE>mode != QImode
18167 || any_QIreg_operand (operands[1], QImode))"
18168 [(set (match_dup 0) (match_dup 4))
18169 (parallel [(set (match_dup 0)
18170 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
18171 (clobber (reg:CC FLAGS_REG))])]
18172 "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
18175 [(set (match_operand 0 "mmx_reg_operand")
18176 (match_operand 1 "mmx_reg_operand"))
18178 (match_operator 3 "commutative_operator"
18180 (match_operand 2 "memory_operand")]))]
18181 "REGNO (operands[0]) != REGNO (operands[1])"
18182 [(set (match_dup 0) (match_dup 2))
18184 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18187 [(set (match_operand 0 "sse_reg_operand")
18188 (match_operand 1 "sse_reg_operand"))
18190 (match_operator 3 "commutative_operator"
18192 (match_operand 2 "memory_operand")]))]
18193 "REGNO (operands[0]) != REGNO (operands[1])"
18194 [(set (match_dup 0) (match_dup 2))
18196 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18198 ; Don't do logical operations with memory outputs
18200 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18201 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
18202 ; the same decoder scheduling characteristics as the original.
18205 [(match_scratch:SWI 2 "<r>")
18206 (parallel [(set (match_operand:SWI 0 "memory_operand")
18207 (match_operator:SWI 3 "arith_or_logical_operator"
18209 (match_operand:SWI 1 "<nonmemory_operand>")]))
18210 (clobber (reg:CC FLAGS_REG))])]
18211 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18212 [(set (match_dup 2) (match_dup 0))
18213 (parallel [(set (match_dup 2)
18214 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18215 (clobber (reg:CC FLAGS_REG))])
18216 (set (match_dup 0) (match_dup 2))])
18219 [(match_scratch:SWI 2 "<r>")
18220 (parallel [(set (match_operand:SWI 0 "memory_operand")
18221 (match_operator:SWI 3 "arith_or_logical_operator"
18222 [(match_operand:SWI 1 "<nonmemory_operand>")
18224 (clobber (reg:CC FLAGS_REG))])]
18225 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18226 [(set (match_dup 2) (match_dup 0))
18227 (parallel [(set (match_dup 2)
18228 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18229 (clobber (reg:CC FLAGS_REG))])
18230 (set (match_dup 0) (match_dup 2))])
18232 ;; Attempt to use arith or logical operations with memory outputs with
18233 ;; setting of flags.
18235 [(set (match_operand:SWI 0 "register_operand")
18236 (match_operand:SWI 1 "memory_operand"))
18237 (parallel [(set (match_dup 0)
18238 (match_operator:SWI 3 "plusminuslogic_operator"
18240 (match_operand:SWI 2 "<nonmemory_operand>")]))
18241 (clobber (reg:CC FLAGS_REG))])
18242 (set (match_dup 1) (match_dup 0))
18243 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18244 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18245 && peep2_reg_dead_p (4, operands[0])
18246 && !reg_overlap_mentioned_p (operands[0], operands[1])
18247 && !reg_overlap_mentioned_p (operands[0], operands[2])
18248 && (<MODE>mode != QImode
18249 || immediate_operand (operands[2], QImode)
18250 || any_QIreg_operand (operands[2], QImode))
18251 && ix86_match_ccmode (peep2_next_insn (3),
18252 (GET_CODE (operands[3]) == PLUS
18253 || GET_CODE (operands[3]) == MINUS)
18254 ? CCGOCmode : CCNOmode)"
18255 [(parallel [(set (match_dup 4) (match_dup 6))
18256 (set (match_dup 1) (match_dup 5))])]
18258 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18260 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18261 copy_rtx (operands[1]),
18264 = gen_rtx_COMPARE (GET_MODE (operands[4]),
18265 copy_rtx (operands[5]),
18269 ;; Likewise for instances where we have a lea pattern.
18271 [(set (match_operand:SWI 0 "register_operand")
18272 (match_operand:SWI 1 "memory_operand"))
18273 (set (match_operand:SWI 3 "register_operand")
18274 (plus:SWI (match_dup 0)
18275 (match_operand:SWI 2 "<nonmemory_operand>")))
18276 (set (match_dup 1) (match_dup 3))
18277 (set (reg FLAGS_REG) (compare (match_dup 3) (const_int 0)))]
18278 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18279 && peep2_reg_dead_p (4, operands[3])
18280 && (rtx_equal_p (operands[0], operands[3])
18281 || peep2_reg_dead_p (2, operands[0]))
18282 && !reg_overlap_mentioned_p (operands[0], operands[1])
18283 && !reg_overlap_mentioned_p (operands[3], operands[1])
18284 && !reg_overlap_mentioned_p (operands[0], operands[2])
18285 && (<MODE>mode != QImode
18286 || immediate_operand (operands[2], QImode)
18287 || any_QIreg_operand (operands[2], QImode))
18288 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
18289 [(parallel [(set (match_dup 4) (match_dup 6))
18290 (set (match_dup 1) (match_dup 5))])]
18292 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18294 = gen_rtx_PLUS (<MODE>mode,
18295 copy_rtx (operands[1]),
18298 = gen_rtx_COMPARE (GET_MODE (operands[4]),
18299 copy_rtx (operands[5]),
18304 [(parallel [(set (match_operand:SWI 0 "register_operand")
18305 (match_operator:SWI 2 "plusminuslogic_operator"
18307 (match_operand:SWI 1 "memory_operand")]))
18308 (clobber (reg:CC FLAGS_REG))])
18309 (set (match_dup 1) (match_dup 0))
18310 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18311 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18312 && GET_CODE (operands[2]) != MINUS
18313 && peep2_reg_dead_p (3, operands[0])
18314 && !reg_overlap_mentioned_p (operands[0], operands[1])
18315 && ix86_match_ccmode (peep2_next_insn (2),
18316 GET_CODE (operands[2]) == PLUS
18317 ? CCGOCmode : CCNOmode)"
18318 [(parallel [(set (match_dup 3) (match_dup 5))
18319 (set (match_dup 1) (match_dup 4))])]
18321 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
18323 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18324 copy_rtx (operands[1]),
18327 = gen_rtx_COMPARE (GET_MODE (operands[3]),
18328 copy_rtx (operands[4]),
18333 [(set (match_operand:SWI12 0 "register_operand")
18334 (match_operand:SWI12 1 "memory_operand"))
18335 (parallel [(set (match_operand:SI 4 "register_operand")
18336 (match_operator:SI 3 "plusminuslogic_operator"
18338 (match_operand:SI 2 "nonmemory_operand")]))
18339 (clobber (reg:CC FLAGS_REG))])
18340 (set (match_dup 1) (match_dup 0))
18341 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18342 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18343 && REGNO (operands[0]) == REGNO (operands[4])
18344 && peep2_reg_dead_p (4, operands[0])
18345 && (<MODE>mode != QImode
18346 || immediate_operand (operands[2], SImode)
18347 || any_QIreg_operand (operands[2], SImode))
18348 && !reg_overlap_mentioned_p (operands[0], operands[1])
18349 && !reg_overlap_mentioned_p (operands[0], operands[2])
18350 && ix86_match_ccmode (peep2_next_insn (3),
18351 (GET_CODE (operands[3]) == PLUS
18352 || GET_CODE (operands[3]) == MINUS)
18353 ? CCGOCmode : CCNOmode)"
18354 [(parallel [(set (match_dup 4) (match_dup 6))
18355 (set (match_dup 1) (match_dup 5))])]
18357 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18359 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18360 copy_rtx (operands[1]),
18361 gen_lowpart (<MODE>mode, operands[2]));
18363 = gen_rtx_COMPARE (GET_MODE (operands[4]),
18364 copy_rtx (operands[5]),
18368 ;; Attempt to always use XOR for zeroing registers (including FP modes).
18370 [(set (match_operand 0 "general_reg_operand")
18371 (match_operand 1 "const0_operand"))]
18372 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18373 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18374 && peep2_regno_dead_p (0, FLAGS_REG)"
18375 [(parallel [(set (match_dup 0) (const_int 0))
18376 (clobber (reg:CC FLAGS_REG))])]
18377 "operands[0] = gen_lowpart (word_mode, operands[0]);")
18380 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
18382 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18383 && peep2_regno_dead_p (0, FLAGS_REG)"
18384 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18385 (clobber (reg:CC FLAGS_REG))])])
18387 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
18389 [(set (match_operand:SWI248 0 "general_reg_operand")
18391 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
18392 && peep2_regno_dead_p (0, FLAGS_REG)"
18393 [(parallel [(set (match_dup 0) (const_int -1))
18394 (clobber (reg:CC FLAGS_REG))])]
18396 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
18397 operands[0] = gen_lowpart (SImode, operands[0]);
18400 ;; Attempt to convert simple lea to add/shift.
18401 ;; These can be created by move expanders.
18402 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
18403 ;; relevant lea instructions were already split.
18406 [(set (match_operand:SWI48 0 "register_operand")
18407 (plus:SWI48 (match_dup 0)
18408 (match_operand:SWI48 1 "<nonmemory_operand>")))]
18410 && peep2_regno_dead_p (0, FLAGS_REG)"
18411 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18412 (clobber (reg:CC FLAGS_REG))])])
18415 [(set (match_operand:SWI48 0 "register_operand")
18416 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
18419 && peep2_regno_dead_p (0, FLAGS_REG)"
18420 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18421 (clobber (reg:CC FLAGS_REG))])])
18424 [(set (match_operand:DI 0 "register_operand")
18426 (plus:SI (match_operand:SI 1 "register_operand")
18427 (match_operand:SI 2 "nonmemory_operand"))))]
18428 "TARGET_64BIT && !TARGET_OPT_AGU
18429 && REGNO (operands[0]) == REGNO (operands[1])
18430 && peep2_regno_dead_p (0, FLAGS_REG)"
18431 [(parallel [(set (match_dup 0)
18432 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
18433 (clobber (reg:CC FLAGS_REG))])])
18436 [(set (match_operand:DI 0 "register_operand")
18438 (plus:SI (match_operand:SI 1 "nonmemory_operand")
18439 (match_operand:SI 2 "register_operand"))))]
18440 "TARGET_64BIT && !TARGET_OPT_AGU
18441 && REGNO (operands[0]) == REGNO (operands[2])
18442 && peep2_regno_dead_p (0, FLAGS_REG)"
18443 [(parallel [(set (match_dup 0)
18444 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
18445 (clobber (reg:CC FLAGS_REG))])])
18448 [(set (match_operand:SWI48 0 "register_operand")
18449 (mult:SWI48 (match_dup 0)
18450 (match_operand:SWI48 1 "const_int_operand")))]
18451 "pow2p_hwi (INTVAL (operands[1]))
18452 && peep2_regno_dead_p (0, FLAGS_REG)"
18453 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
18454 (clobber (reg:CC FLAGS_REG))])]
18455 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18458 [(set (match_operand:DI 0 "register_operand")
18460 (mult:SI (match_operand:SI 1 "register_operand")
18461 (match_operand:SI 2 "const_int_operand"))))]
18463 && pow2p_hwi (INTVAL (operands[2]))
18464 && REGNO (operands[0]) == REGNO (operands[1])
18465 && peep2_regno_dead_p (0, FLAGS_REG)"
18466 [(parallel [(set (match_dup 0)
18467 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
18468 (clobber (reg:CC FLAGS_REG))])]
18469 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18471 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18472 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
18473 ;; On many CPUs it is also faster, since special hardware to avoid esp
18474 ;; dependencies is present.
18476 ;; While some of these conversions may be done using splitters, we use
18477 ;; peepholes in order to allow combine_stack_adjustments pass to see
18478 ;; nonobfuscated RTL.
18480 ;; Convert prologue esp subtractions to push.
18481 ;; We need register to push. In order to keep verify_flow_info happy we have
18483 ;; - use scratch and clobber it in order to avoid dependencies
18484 ;; - use already live register
18485 ;; We can't use the second way right now, since there is no reliable way how to
18486 ;; verify that given register is live. First choice will also most likely in
18487 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18488 ;; call clobbered registers are dead. We may want to use base pointer as an
18489 ;; alternative when no register is available later.
18492 [(match_scratch:W 1 "r")
18493 (parallel [(set (reg:P SP_REG)
18494 (plus:P (reg:P SP_REG)
18495 (match_operand:P 0 "const_int_operand")))
18496 (clobber (reg:CC FLAGS_REG))
18497 (clobber (mem:BLK (scratch)))])]
18498 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18499 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
18500 && !ix86_using_red_zone ()"
18501 [(clobber (match_dup 1))
18502 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18503 (clobber (mem:BLK (scratch)))])])
18506 [(match_scratch:W 1 "r")
18507 (parallel [(set (reg:P SP_REG)
18508 (plus:P (reg:P SP_REG)
18509 (match_operand:P 0 "const_int_operand")))
18510 (clobber (reg:CC FLAGS_REG))
18511 (clobber (mem:BLK (scratch)))])]
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 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18518 (clobber (mem:BLK (scratch)))])])
18520 ;; Convert esp subtractions to push.
18522 [(match_scratch:W 1 "r")
18523 (parallel [(set (reg:P SP_REG)
18524 (plus:P (reg:P SP_REG)
18525 (match_operand:P 0 "const_int_operand")))
18526 (clobber (reg:CC FLAGS_REG))])]
18527 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18528 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
18529 && !ix86_using_red_zone ()"
18530 [(clobber (match_dup 1))
18531 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
18534 [(match_scratch:W 1 "r")
18535 (parallel [(set (reg:P SP_REG)
18536 (plus:P (reg:P SP_REG)
18537 (match_operand:P 0 "const_int_operand")))
18538 (clobber (reg:CC FLAGS_REG))])]
18539 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
18540 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
18541 && !ix86_using_red_zone ()"
18542 [(clobber (match_dup 1))
18543 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18544 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
18546 ;; Convert epilogue deallocator to pop.
18548 [(match_scratch:W 1 "r")
18549 (parallel [(set (reg:P SP_REG)
18550 (plus:P (reg:P SP_REG)
18551 (match_operand:P 0 "const_int_operand")))
18552 (clobber (reg:CC FLAGS_REG))
18553 (clobber (mem:BLK (scratch)))])]
18554 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
18555 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
18556 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18557 (clobber (mem:BLK (scratch)))])])
18559 ;; Two pops case is tricky, since pop causes dependency
18560 ;; on destination register. We use two registers if available.
18562 [(match_scratch:W 1 "r")
18563 (match_scratch:W 2 "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 (clobber (mem:BLK (scratch)))])]
18569 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
18570 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18571 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18572 (clobber (mem:BLK (scratch)))])
18573 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
18576 [(match_scratch:W 1 "r")
18577 (parallel [(set (reg:P SP_REG)
18578 (plus:P (reg:P SP_REG)
18579 (match_operand:P 0 "const_int_operand")))
18580 (clobber (reg:CC FLAGS_REG))
18581 (clobber (mem:BLK (scratch)))])]
18582 "optimize_insn_for_size_p ()
18583 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18584 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18585 (clobber (mem:BLK (scratch)))])
18586 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18588 ;; Convert esp additions to pop.
18590 [(match_scratch:W 1 "r")
18591 (parallel [(set (reg:P SP_REG)
18592 (plus:P (reg:P SP_REG)
18593 (match_operand:P 0 "const_int_operand")))
18594 (clobber (reg:CC FLAGS_REG))])]
18595 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
18596 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18598 ;; Two pops case is tricky, since pop causes dependency
18599 ;; on destination register. We use two registers if available.
18601 [(match_scratch:W 1 "r")
18602 (match_scratch:W 2 "r")
18603 (parallel [(set (reg:P SP_REG)
18604 (plus:P (reg:P SP_REG)
18605 (match_operand:P 0 "const_int_operand")))
18606 (clobber (reg:CC FLAGS_REG))])]
18607 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18608 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18609 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
18612 [(match_scratch:W 1 "r")
18613 (parallel [(set (reg:P SP_REG)
18614 (plus:P (reg:P SP_REG)
18615 (match_operand:P 0 "const_int_operand")))
18616 (clobber (reg:CC FLAGS_REG))])]
18617 "optimize_insn_for_size_p ()
18618 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18619 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18620 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18622 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18623 ;; required and register dies. Similarly for 128 to -128.
18625 [(set (match_operand 0 "flags_reg_operand")
18626 (match_operator 1 "compare_operator"
18627 [(match_operand 2 "register_operand")
18628 (match_operand 3 "const_int_operand")]))]
18629 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
18630 && incdec_operand (operands[3], GET_MODE (operands[3])))
18631 || (!TARGET_FUSE_CMP_AND_BRANCH
18632 && INTVAL (operands[3]) == 128))
18633 && ix86_match_ccmode (insn, CCGCmode)
18634 && peep2_reg_dead_p (1, operands[2])"
18635 [(parallel [(set (match_dup 0)
18636 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18637 (clobber (match_dup 2))])])
18639 ;; Convert imul by three, five and nine into lea
18642 [(set (match_operand:SWI48 0 "register_operand")
18643 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
18644 (match_operand:SWI48 2 "const359_operand")))
18645 (clobber (reg:CC FLAGS_REG))])]
18646 "!TARGET_PARTIAL_REG_STALL
18647 || <MODE>mode == SImode
18648 || optimize_function_for_size_p (cfun)"
18649 [(set (match_dup 0)
18650 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
18652 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18656 [(set (match_operand:SWI48 0 "register_operand")
18657 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
18658 (match_operand:SWI48 2 "const359_operand")))
18659 (clobber (reg:CC FLAGS_REG))])]
18660 "optimize_insn_for_speed_p ()
18661 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
18662 [(set (match_dup 0) (match_dup 1))
18664 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
18666 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18668 ;; imul $32bit_imm, mem, reg is vector decoded, while
18669 ;; imul $32bit_imm, reg, reg is direct decoded.
18671 [(match_scratch:SWI48 3 "r")
18672 (parallel [(set (match_operand:SWI48 0 "register_operand")
18673 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
18674 (match_operand:SWI48 2 "immediate_operand")))
18675 (clobber (reg:CC FLAGS_REG))])]
18676 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18677 && !satisfies_constraint_K (operands[2])"
18678 [(set (match_dup 3) (match_dup 1))
18679 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
18680 (clobber (reg:CC FLAGS_REG))])])
18683 [(match_scratch:SI 3 "r")
18684 (parallel [(set (match_operand:DI 0 "register_operand")
18686 (mult:SI (match_operand:SI 1 "memory_operand")
18687 (match_operand:SI 2 "immediate_operand"))))
18688 (clobber (reg:CC FLAGS_REG))])]
18690 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18691 && !satisfies_constraint_K (operands[2])"
18692 [(set (match_dup 3) (match_dup 1))
18693 (parallel [(set (match_dup 0)
18694 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18695 (clobber (reg:CC FLAGS_REG))])])
18697 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18698 ;; Convert it into imul reg, reg
18699 ;; It would be better to force assembler to encode instruction using long
18700 ;; immediate, but there is apparently no way to do so.
18702 [(parallel [(set (match_operand:SWI248 0 "register_operand")
18704 (match_operand:SWI248 1 "nonimmediate_operand")
18705 (match_operand:SWI248 2 "const_int_operand")))
18706 (clobber (reg:CC FLAGS_REG))])
18707 (match_scratch:SWI248 3 "r")]
18708 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18709 && satisfies_constraint_K (operands[2])"
18710 [(set (match_dup 3) (match_dup 2))
18711 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
18712 (clobber (reg:CC FLAGS_REG))])]
18714 if (!rtx_equal_p (operands[0], operands[1]))
18715 emit_move_insn (operands[0], operands[1]);
18718 ;; After splitting up read-modify operations, array accesses with memory
18719 ;; operands might end up in form:
18721 ;; movl 4(%esp), %edx
18723 ;; instead of pre-splitting:
18725 ;; addl 4(%esp), %eax
18727 ;; movl 4(%esp), %edx
18728 ;; leal (%edx,%eax,4), %eax
18731 [(match_scratch:W 5 "r")
18732 (parallel [(set (match_operand 0 "register_operand")
18733 (ashift (match_operand 1 "register_operand")
18734 (match_operand 2 "const_int_operand")))
18735 (clobber (reg:CC FLAGS_REG))])
18736 (parallel [(set (match_operand 3 "register_operand")
18737 (plus (match_dup 0)
18738 (match_operand 4 "x86_64_general_operand")))
18739 (clobber (reg:CC FLAGS_REG))])]
18740 "IN_RANGE (INTVAL (operands[2]), 1, 3)
18741 /* Validate MODE for lea. */
18742 && ((!TARGET_PARTIAL_REG_STALL
18743 && (GET_MODE (operands[0]) == QImode
18744 || GET_MODE (operands[0]) == HImode))
18745 || GET_MODE (operands[0]) == SImode
18746 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18747 && (rtx_equal_p (operands[0], operands[3])
18748 || peep2_reg_dead_p (2, operands[0]))
18749 /* We reorder load and the shift. */
18750 && !reg_overlap_mentioned_p (operands[0], operands[4])"
18751 [(set (match_dup 5) (match_dup 4))
18752 (set (match_dup 0) (match_dup 1))]
18754 machine_mode op1mode = GET_MODE (operands[1]);
18755 machine_mode mode = op1mode == DImode ? DImode : SImode;
18756 int scale = 1 << INTVAL (operands[2]);
18757 rtx index = gen_lowpart (word_mode, operands[1]);
18758 rtx base = gen_lowpart (word_mode, operands[5]);
18759 rtx dest = gen_lowpart (mode, operands[3]);
18761 operands[1] = gen_rtx_PLUS (word_mode, base,
18762 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
18763 if (mode != word_mode)
18764 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18766 operands[5] = base;
18767 if (op1mode != word_mode)
18768 operands[5] = gen_lowpart (op1mode, operands[5]);
18770 operands[0] = dest;
18773 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18774 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18775 ;; caught for use by garbage collectors and the like. Using an insn that
18776 ;; maps to SIGILL makes it more likely the program will rightfully die.
18777 ;; Keeping with tradition, "6" is in honor of #UD.
18778 (define_insn "trap"
18779 [(trap_if (const_int 1) (const_int 6))]
18782 #ifdef HAVE_AS_IX86_UD2
18785 return ASM_SHORT "0x0b0f";
18788 [(set_attr "length" "2")])
18790 (define_expand "prefetch"
18791 [(prefetch (match_operand 0 "address_operand")
18792 (match_operand:SI 1 "const_int_operand")
18793 (match_operand:SI 2 "const_int_operand"))]
18794 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18796 bool write = INTVAL (operands[1]) != 0;
18797 int locality = INTVAL (operands[2]);
18799 gcc_assert (IN_RANGE (locality, 0, 3));
18801 /* Use 3dNOW prefetch in case we are asking for write prefetch not
18802 supported by SSE counterpart (non-SSE2 athlon machines) or the
18803 SSE prefetch is not available (K6 machines). Otherwise use SSE
18804 prefetch as it allows specifying of locality. */
18808 if (TARGET_PREFETCHWT1)
18809 operands[2] = GEN_INT (MAX (locality, 2));
18810 else if (TARGET_PRFCHW)
18811 operands[2] = GEN_INT (3);
18812 else if (TARGET_3DNOW && !TARGET_SSE2)
18813 operands[2] = GEN_INT (3);
18814 else if (TARGET_PREFETCH_SSE)
18815 operands[1] = const0_rtx;
18818 gcc_assert (TARGET_3DNOW);
18819 operands[2] = GEN_INT (3);
18824 if (TARGET_PREFETCH_SSE)
18828 gcc_assert (TARGET_3DNOW);
18829 operands[2] = GEN_INT (3);
18834 (define_insn "*prefetch_sse"
18835 [(prefetch (match_operand 0 "address_operand" "p")
18837 (match_operand:SI 1 "const_int_operand"))]
18838 "TARGET_PREFETCH_SSE"
18840 static const char * const patterns[4] = {
18841 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18844 int locality = INTVAL (operands[1]);
18845 gcc_assert (IN_RANGE (locality, 0, 3));
18847 return patterns[locality];
18849 [(set_attr "type" "sse")
18850 (set_attr "atom_sse_attr" "prefetch")
18851 (set (attr "length_address")
18852 (symbol_ref "memory_address_length (operands[0], false)"))
18853 (set_attr "memory" "none")])
18855 (define_insn "*prefetch_3dnow"
18856 [(prefetch (match_operand 0 "address_operand" "p")
18857 (match_operand:SI 1 "const_int_operand" "n")
18859 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18861 if (INTVAL (operands[1]) == 0)
18862 return "prefetch\t%a0";
18864 return "prefetchw\t%a0";
18866 [(set_attr "type" "mmx")
18867 (set (attr "length_address")
18868 (symbol_ref "memory_address_length (operands[0], false)"))
18869 (set_attr "memory" "none")])
18871 (define_insn "*prefetch_prefetchwt1"
18872 [(prefetch (match_operand 0 "address_operand" "p")
18875 "TARGET_PREFETCHWT1"
18876 "prefetchwt1\t%a0";
18877 [(set_attr "type" "sse")
18878 (set (attr "length_address")
18879 (symbol_ref "memory_address_length (operands[0], false)"))
18880 (set_attr "memory" "none")])
18882 (define_expand "stack_protect_set"
18883 [(match_operand 0 "memory_operand")
18884 (match_operand 1 "memory_operand")]
18885 "TARGET_SSP_TLS_GUARD"
18887 rtx (*insn)(rtx, rtx);
18889 #ifdef TARGET_THREAD_SSP_OFFSET
18890 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18891 insn = (TARGET_LP64
18892 ? gen_stack_tls_protect_set_di
18893 : gen_stack_tls_protect_set_si);
18895 insn = (TARGET_LP64
18896 ? gen_stack_protect_set_di
18897 : gen_stack_protect_set_si);
18900 emit_insn (insn (operands[0], operands[1]));
18904 (define_insn "stack_protect_set_<mode>"
18905 [(set (match_operand:PTR 0 "memory_operand" "=m")
18906 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18908 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18909 (clobber (reg:CC FLAGS_REG))]
18910 "TARGET_SSP_TLS_GUARD"
18911 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18912 [(set_attr "type" "multi")])
18914 (define_insn "stack_tls_protect_set_<mode>"
18915 [(set (match_operand:PTR 0 "memory_operand" "=m")
18916 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
18917 UNSPEC_SP_TLS_SET))
18918 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18919 (clobber (reg:CC FLAGS_REG))]
18921 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18922 [(set_attr "type" "multi")])
18924 (define_expand "stack_protect_test"
18925 [(match_operand 0 "memory_operand")
18926 (match_operand 1 "memory_operand")
18928 "TARGET_SSP_TLS_GUARD"
18930 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18932 rtx (*insn)(rtx, rtx, rtx);
18934 #ifdef TARGET_THREAD_SSP_OFFSET
18935 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18936 insn = (TARGET_LP64
18937 ? gen_stack_tls_protect_test_di
18938 : gen_stack_tls_protect_test_si);
18940 insn = (TARGET_LP64
18941 ? gen_stack_protect_test_di
18942 : gen_stack_protect_test_si);
18945 emit_insn (insn (flags, operands[0], operands[1]));
18947 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18948 flags, const0_rtx, operands[2]));
18952 (define_insn "stack_protect_test_<mode>"
18953 [(set (match_operand:CCZ 0 "flags_reg_operand")
18954 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18955 (match_operand:PTR 2 "memory_operand" "m")]
18957 (clobber (match_scratch:PTR 3 "=&r"))]
18958 "TARGET_SSP_TLS_GUARD"
18959 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18960 [(set_attr "type" "multi")])
18962 (define_insn "stack_tls_protect_test_<mode>"
18963 [(set (match_operand:CCZ 0 "flags_reg_operand")
18964 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18965 (match_operand:PTR 2 "const_int_operand" "i")]
18966 UNSPEC_SP_TLS_TEST))
18967 (clobber (match_scratch:PTR 3 "=r"))]
18969 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18970 [(set_attr "type" "multi")])
18972 (define_insn "sse4_2_crc32<mode>"
18973 [(set (match_operand:SI 0 "register_operand" "=r")
18975 [(match_operand:SI 1 "register_operand" "0")
18976 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18978 "TARGET_SSE4_2 || TARGET_CRC32"
18979 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18980 [(set_attr "type" "sselog1")
18981 (set_attr "prefix_rep" "1")
18982 (set_attr "prefix_extra" "1")
18983 (set (attr "prefix_data16")
18984 (if_then_else (match_operand:HI 2)
18986 (const_string "*")))
18987 (set (attr "prefix_rex")
18988 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18990 (const_string "*")))
18991 (set_attr "mode" "SI")])
18993 (define_insn "sse4_2_crc32di"
18994 [(set (match_operand:DI 0 "register_operand" "=r")
18996 [(match_operand:DI 1 "register_operand" "0")
18997 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18999 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
19000 "crc32{q}\t{%2, %0|%0, %2}"
19001 [(set_attr "type" "sselog1")
19002 (set_attr "prefix_rep" "1")
19003 (set_attr "prefix_extra" "1")
19004 (set_attr "mode" "DI")])
19006 (define_insn "rdpmc"
19007 [(set (match_operand:DI 0 "register_operand" "=A")
19008 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19012 [(set_attr "type" "other")
19013 (set_attr "length" "2")])
19015 (define_insn "rdpmc_rex64"
19016 [(set (match_operand:DI 0 "register_operand" "=a")
19017 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19019 (set (match_operand:DI 1 "register_operand" "=d")
19020 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
19023 [(set_attr "type" "other")
19024 (set_attr "length" "2")])
19026 (define_insn "rdtsc"
19027 [(set (match_operand:DI 0 "register_operand" "=A")
19028 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19031 [(set_attr "type" "other")
19032 (set_attr "length" "2")])
19034 (define_insn "rdtsc_rex64"
19035 [(set (match_operand:DI 0 "register_operand" "=a")
19036 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
19037 (set (match_operand:DI 1 "register_operand" "=d")
19038 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19041 [(set_attr "type" "other")
19042 (set_attr "length" "2")])
19044 (define_insn "rdtscp"
19045 [(set (match_operand:DI 0 "register_operand" "=A")
19046 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19047 (set (match_operand:SI 1 "register_operand" "=c")
19048 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19051 [(set_attr "type" "other")
19052 (set_attr "length" "3")])
19054 (define_insn "rdtscp_rex64"
19055 [(set (match_operand:DI 0 "register_operand" "=a")
19056 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19057 (set (match_operand:DI 1 "register_operand" "=d")
19058 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19059 (set (match_operand:SI 2 "register_operand" "=c")
19060 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19063 [(set_attr "type" "other")
19064 (set_attr "length" "3")])
19066 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19068 ;; FXSR, XSAVE and XSAVEOPT instructions
19070 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19072 (define_insn "fxsave"
19073 [(set (match_operand:BLK 0 "memory_operand" "=m")
19074 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
19077 [(set_attr "type" "other")
19078 (set_attr "memory" "store")
19079 (set (attr "length")
19080 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19082 (define_insn "fxsave64"
19083 [(set (match_operand:BLK 0 "memory_operand" "=m")
19084 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
19085 "TARGET_64BIT && TARGET_FXSR"
19087 [(set_attr "type" "other")
19088 (set_attr "memory" "store")
19089 (set (attr "length")
19090 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19092 (define_insn "fxrstor"
19093 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19097 [(set_attr "type" "other")
19098 (set_attr "memory" "load")
19099 (set (attr "length")
19100 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19102 (define_insn "fxrstor64"
19103 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19104 UNSPECV_FXRSTOR64)]
19105 "TARGET_64BIT && TARGET_FXSR"
19107 [(set_attr "type" "other")
19108 (set_attr "memory" "load")
19109 (set (attr "length")
19110 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19112 (define_int_iterator ANY_XSAVE
19114 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
19115 (UNSPECV_XSAVEC "TARGET_XSAVEC")
19116 (UNSPECV_XSAVES "TARGET_XSAVES")])
19118 (define_int_iterator ANY_XSAVE64
19120 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
19121 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
19122 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
19124 (define_int_attr xsave
19125 [(UNSPECV_XSAVE "xsave")
19126 (UNSPECV_XSAVE64 "xsave64")
19127 (UNSPECV_XSAVEOPT "xsaveopt")
19128 (UNSPECV_XSAVEOPT64 "xsaveopt64")
19129 (UNSPECV_XSAVEC "xsavec")
19130 (UNSPECV_XSAVEC64 "xsavec64")
19131 (UNSPECV_XSAVES "xsaves")
19132 (UNSPECV_XSAVES64 "xsaves64")])
19134 (define_int_iterator ANY_XRSTOR
19136 (UNSPECV_XRSTORS "TARGET_XSAVES")])
19138 (define_int_iterator ANY_XRSTOR64
19140 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
19142 (define_int_attr xrstor
19143 [(UNSPECV_XRSTOR "xrstor")
19144 (UNSPECV_XRSTOR64 "xrstor")
19145 (UNSPECV_XRSTORS "xrstors")
19146 (UNSPECV_XRSTORS64 "xrstors")])
19148 (define_insn "<xsave>"
19149 [(set (match_operand:BLK 0 "memory_operand" "=m")
19150 (unspec_volatile:BLK
19151 [(match_operand:DI 1 "register_operand" "A")]
19153 "!TARGET_64BIT && TARGET_XSAVE"
19155 [(set_attr "type" "other")
19156 (set_attr "memory" "store")
19157 (set (attr "length")
19158 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19160 (define_insn "<xsave>_rex64"
19161 [(set (match_operand:BLK 0 "memory_operand" "=m")
19162 (unspec_volatile:BLK
19163 [(match_operand:SI 1 "register_operand" "a")
19164 (match_operand:SI 2 "register_operand" "d")]
19166 "TARGET_64BIT && TARGET_XSAVE"
19168 [(set_attr "type" "other")
19169 (set_attr "memory" "store")
19170 (set (attr "length")
19171 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19173 (define_insn "<xsave>"
19174 [(set (match_operand:BLK 0 "memory_operand" "=m")
19175 (unspec_volatile:BLK
19176 [(match_operand:SI 1 "register_operand" "a")
19177 (match_operand:SI 2 "register_operand" "d")]
19179 "TARGET_64BIT && TARGET_XSAVE"
19181 [(set_attr "type" "other")
19182 (set_attr "memory" "store")
19183 (set (attr "length")
19184 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19186 (define_insn "<xrstor>"
19187 [(unspec_volatile:BLK
19188 [(match_operand:BLK 0 "memory_operand" "m")
19189 (match_operand:DI 1 "register_operand" "A")]
19191 "!TARGET_64BIT && TARGET_XSAVE"
19193 [(set_attr "type" "other")
19194 (set_attr "memory" "load")
19195 (set (attr "length")
19196 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19198 (define_insn "<xrstor>_rex64"
19199 [(unspec_volatile:BLK
19200 [(match_operand:BLK 0 "memory_operand" "m")
19201 (match_operand:SI 1 "register_operand" "a")
19202 (match_operand:SI 2 "register_operand" "d")]
19204 "TARGET_64BIT && TARGET_XSAVE"
19206 [(set_attr "type" "other")
19207 (set_attr "memory" "load")
19208 (set (attr "length")
19209 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19211 (define_insn "<xrstor>64"
19212 [(unspec_volatile:BLK
19213 [(match_operand:BLK 0 "memory_operand" "m")
19214 (match_operand:SI 1 "register_operand" "a")
19215 (match_operand:SI 2 "register_operand" "d")]
19217 "TARGET_64BIT && TARGET_XSAVE"
19219 [(set_attr "type" "other")
19220 (set_attr "memory" "load")
19221 (set (attr "length")
19222 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19224 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19226 ;; Floating-point instructions for atomic compound assignments
19228 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19230 ; Clobber all floating-point registers on environment save and restore
19231 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
19232 (define_insn "fnstenv"
19233 [(set (match_operand:BLK 0 "memory_operand" "=m")
19234 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
19235 (clobber (reg:HI FPCR_REG))
19236 (clobber (reg:XF ST0_REG))
19237 (clobber (reg:XF ST1_REG))
19238 (clobber (reg:XF ST2_REG))
19239 (clobber (reg:XF ST3_REG))
19240 (clobber (reg:XF ST4_REG))
19241 (clobber (reg:XF ST5_REG))
19242 (clobber (reg:XF ST6_REG))
19243 (clobber (reg:XF ST7_REG))]
19246 [(set_attr "type" "other")
19247 (set_attr "memory" "store")
19248 (set (attr "length")
19249 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19251 (define_insn "fldenv"
19252 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19254 (clobber (reg:CCFP FPSR_REG))
19255 (clobber (reg:HI FPCR_REG))
19256 (clobber (reg:XF ST0_REG))
19257 (clobber (reg:XF ST1_REG))
19258 (clobber (reg:XF ST2_REG))
19259 (clobber (reg:XF ST3_REG))
19260 (clobber (reg:XF ST4_REG))
19261 (clobber (reg:XF ST5_REG))
19262 (clobber (reg:XF ST6_REG))
19263 (clobber (reg:XF ST7_REG))]
19266 [(set_attr "type" "other")
19267 (set_attr "memory" "load")
19268 (set (attr "length")
19269 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19271 (define_insn "fnstsw"
19272 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
19273 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
19276 [(set_attr "type" "other,other")
19277 (set_attr "memory" "none,store")
19278 (set (attr "length")
19279 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19281 (define_insn "fnclex"
19282 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
19285 [(set_attr "type" "other")
19286 (set_attr "memory" "none")
19287 (set_attr "length" "2")])
19289 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19291 ;; LWP instructions
19293 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19295 (define_expand "lwp_llwpcb"
19296 [(unspec_volatile [(match_operand 0 "register_operand")]
19297 UNSPECV_LLWP_INTRINSIC)]
19300 (define_insn "*lwp_llwpcb<mode>1"
19301 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
19302 UNSPECV_LLWP_INTRINSIC)]
19305 [(set_attr "type" "lwp")
19306 (set_attr "mode" "<MODE>")
19307 (set_attr "length" "5")])
19309 (define_expand "lwp_slwpcb"
19310 [(set (match_operand 0 "register_operand")
19311 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19316 insn = (Pmode == DImode
19318 : gen_lwp_slwpcbsi);
19320 emit_insn (insn (operands[0]));
19324 (define_insn "lwp_slwpcb<mode>"
19325 [(set (match_operand:P 0 "register_operand" "=r")
19326 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19329 [(set_attr "type" "lwp")
19330 (set_attr "mode" "<MODE>")
19331 (set_attr "length" "5")])
19333 (define_expand "lwp_lwpval<mode>3"
19334 [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
19335 (match_operand:SI 2 "nonimmediate_operand")
19336 (match_operand:SI 3 "const_int_operand")]
19337 UNSPECV_LWPVAL_INTRINSIC)]
19339 ;; Avoid unused variable warning.
19340 "(void) operands[0];")
19342 (define_insn "*lwp_lwpval<mode>3_1"
19343 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
19344 (match_operand:SI 1 "nonimmediate_operand" "rm")
19345 (match_operand:SI 2 "const_int_operand" "i")]
19346 UNSPECV_LWPVAL_INTRINSIC)]
19348 "lwpval\t{%2, %1, %0|%0, %1, %2}"
19349 [(set_attr "type" "lwp")
19350 (set_attr "mode" "<MODE>")
19351 (set (attr "length")
19352 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19354 (define_expand "lwp_lwpins<mode>3"
19355 [(set (reg:CCC FLAGS_REG)
19356 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
19357 (match_operand:SI 2 "nonimmediate_operand")
19358 (match_operand:SI 3 "const_int_operand")]
19359 UNSPECV_LWPINS_INTRINSIC))
19360 (set (match_operand:QI 0 "nonimmediate_operand")
19361 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
19364 (define_insn "*lwp_lwpins<mode>3_1"
19365 [(set (reg:CCC FLAGS_REG)
19366 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
19367 (match_operand:SI 1 "nonimmediate_operand" "rm")
19368 (match_operand:SI 2 "const_int_operand" "i")]
19369 UNSPECV_LWPINS_INTRINSIC))]
19371 "lwpins\t{%2, %1, %0|%0, %1, %2}"
19372 [(set_attr "type" "lwp")
19373 (set_attr "mode" "<MODE>")
19374 (set (attr "length")
19375 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19377 (define_int_iterator RDFSGSBASE
19381 (define_int_iterator WRFSGSBASE
19385 (define_int_attr fsgs
19386 [(UNSPECV_RDFSBASE "fs")
19387 (UNSPECV_RDGSBASE "gs")
19388 (UNSPECV_WRFSBASE "fs")
19389 (UNSPECV_WRGSBASE "gs")])
19391 (define_insn "rd<fsgs>base<mode>"
19392 [(set (match_operand:SWI48 0 "register_operand" "=r")
19393 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
19394 "TARGET_64BIT && TARGET_FSGSBASE"
19396 [(set_attr "type" "other")
19397 (set_attr "prefix_extra" "2")])
19399 (define_insn "wr<fsgs>base<mode>"
19400 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
19402 "TARGET_64BIT && TARGET_FSGSBASE"
19404 [(set_attr "type" "other")
19405 (set_attr "prefix_extra" "2")])
19407 (define_insn "rdrand<mode>_1"
19408 [(set (match_operand:SWI248 0 "register_operand" "=r")
19409 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
19410 (set (reg:CCC FLAGS_REG)
19411 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
19414 [(set_attr "type" "other")
19415 (set_attr "prefix_extra" "1")])
19417 (define_insn "rdseed<mode>_1"
19418 [(set (match_operand:SWI248 0 "register_operand" "=r")
19419 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
19420 (set (reg:CCC FLAGS_REG)
19421 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
19424 [(set_attr "type" "other")
19425 (set_attr "prefix_extra" "1")])
19427 (define_expand "pause"
19428 [(set (match_dup 0)
19429 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19432 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
19433 MEM_VOLATILE_P (operands[0]) = 1;
19436 ;; Use "rep; nop", instead of "pause", to support older assemblers.
19437 ;; They have the same encoding.
19438 (define_insn "*pause"
19439 [(set (match_operand:BLK 0)
19440 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19443 [(set_attr "length" "2")
19444 (set_attr "memory" "unknown")])
19446 (define_expand "xbegin"
19447 [(set (match_operand:SI 0 "register_operand")
19448 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
19451 rtx_code_label *label = gen_label_rtx ();
19453 /* xbegin is emitted as jump_insn, so reload won't be able
19454 to reload its operand. Force the value into AX hard register. */
19455 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
19456 emit_move_insn (ax_reg, constm1_rtx);
19458 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
19460 emit_label (label);
19461 LABEL_NUSES (label) = 1;
19463 emit_move_insn (operands[0], ax_reg);
19468 (define_insn "xbegin_1"
19470 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
19472 (label_ref (match_operand 1))
19474 (set (match_operand:SI 0 "register_operand" "+a")
19475 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
19478 [(set_attr "type" "other")
19479 (set_attr "length" "6")])
19481 (define_insn "xend"
19482 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
19485 [(set_attr "type" "other")
19486 (set_attr "length" "3")])
19488 (define_insn "xabort"
19489 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
19493 [(set_attr "type" "other")
19494 (set_attr "length" "3")])
19496 (define_expand "xtest"
19497 [(set (match_operand:QI 0 "register_operand")
19498 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
19501 emit_insn (gen_xtest_1 ());
19503 ix86_expand_setcc (operands[0], NE,
19504 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
19508 (define_insn "xtest_1"
19509 [(set (reg:CCZ FLAGS_REG)
19510 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
19513 [(set_attr "type" "other")
19514 (set_attr "length" "3")])
19516 (define_insn "clwb"
19517 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
19521 [(set_attr "type" "sse")
19522 (set_attr "atom_sse_attr" "fence")
19523 (set_attr "memory" "unknown")])
19525 (define_insn "clflushopt"
19526 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
19527 UNSPECV_CLFLUSHOPT)]
19528 "TARGET_CLFLUSHOPT"
19530 [(set_attr "type" "sse")
19531 (set_attr "atom_sse_attr" "fence")
19532 (set_attr "memory" "unknown")])
19534 ;; MONITORX and MWAITX
19535 (define_insn "mwaitx"
19536 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
19537 (match_operand:SI 1 "register_operand" "a")
19538 (match_operand:SI 2 "register_operand" "b")]
19541 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
19542 ;; Since 32bit register operands are implicitly zero extended to 64bit,
19543 ;; we only need to set up 32bit registers.
19545 [(set_attr "length" "3")])
19547 (define_insn "monitorx_<mode>"
19548 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
19549 (match_operand:SI 1 "register_operand" "c")
19550 (match_operand:SI 2 "register_operand" "d")]
19553 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
19554 ;; RCX and RDX are used. Since 32bit register operands are implicitly
19555 ;; zero extended to 64bit, we only need to set up 32bit registers.
19557 [(set (attr "length")
19558 (symbol_ref ("(Pmode != word_mode) + 3")))])
19561 (define_insn "clzero_<mode>"
19562 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
19566 [(set_attr "length" "3")
19567 (set_attr "memory" "unknown")])
19569 ;; MPX instructions
19571 (define_expand "<mode>_mk"
19572 [(set (match_operand:BND 0 "register_operand")
19576 [(match_operand:<bnd_ptr> 1 "register_operand")
19577 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
19581 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
19583 UNSPEC_BNDMK_ADDR);
19586 (define_insn "*<mode>_mk"
19587 [(set (match_operand:BND 0 "register_operand" "=w")
19589 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19591 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
19592 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
19593 UNSPEC_BNDMK_ADDR)])]
19596 "bndmk\t{%3, %0|%0, %3}"
19597 [(set_attr "type" "mpxmk")])
19599 (define_expand "mov<mode>"
19600 [(set (match_operand:BND 0 "general_operand")
19601 (match_operand:BND 1 "general_operand"))]
19603 "ix86_expand_move (<MODE>mode, operands); DONE;")
19605 (define_insn "*mov<mode>_internal_mpx"
19606 [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
19607 (match_operand:BND 1 "general_operand" "wm,w"))]
19609 "bndmov\t{%1, %0|%0, %1}"
19610 [(set_attr "type" "mpxmov")])
19612 (define_expand "<mode>_<bndcheck>"
19615 [(match_operand:BND 0 "register_operand")
19616 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
19618 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
19621 operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
19622 MEM_VOLATILE_P (operands[2]) = 1;
19625 (define_insn "*<mode>_<bndcheck>"
19627 [(match_operand:BND 0 "register_operand" "w")
19628 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
19629 (set (match_operand:BLK 2 "bnd_mem_operator")
19630 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))]
19632 "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
19633 [(set_attr "type" "mpxchk")])
19635 (define_expand "<mode>_ldx"
19637 [(set (match_operand:BND 0 "register_operand")
19641 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
19642 (match_operand:<bnd_ptr> 2 "register_operand")]))]
19644 (use (mem:BLK (match_dup 1)))])]
19647 /* Avoid registers which cannot be used as index. */
19648 if (!index_register_operand (operands[2], Pmode))
19649 operands[2] = copy_addr_to_reg (operands[2]);
19651 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
19653 UNSPEC_BNDLDX_ADDR);
19656 (define_insn "*<mode>_ldx"
19657 [(set (match_operand:BND 0 "register_operand" "=w")
19659 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19661 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
19662 (match_operand:<bnd_ptr> 2 "register_operand" "l")]
19663 UNSPEC_BNDLDX_ADDR)])]
19665 (use (mem:BLK (match_dup 1)))]
19667 "bndldx\t{%3, %0|%0, %3}"
19668 [(set_attr "type" "mpxld")])
19670 (define_expand "<mode>_stx"
19675 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
19676 (match_operand:<bnd_ptr> 1 "register_operand")]))
19677 (match_operand:BND 2 "register_operand")]
19680 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
19683 /* Avoid registers which cannot be used as index. */
19684 if (!index_register_operand (operands[1], Pmode))
19685 operands[1] = copy_addr_to_reg (operands[1]);
19687 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
19689 UNSPEC_BNDLDX_ADDR);
19690 operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
19691 MEM_VOLATILE_P (operands[4]) = 1;
19694 (define_insn "*<mode>_stx"
19696 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19698 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
19699 (match_operand:<bnd_ptr> 1 "register_operand" "l")]
19700 UNSPEC_BNDLDX_ADDR)])
19701 (match_operand:BND 2 "register_operand" "w")]
19703 (set (match_operand:BLK 4 "bnd_mem_operator")
19704 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))]
19706 "bndstx\t{%2, %3|%3, %2}"
19707 [(set_attr "type" "mpxst")])
19709 (define_insn "move_size_reloc_<mode>"
19710 [(set (match_operand:SWI48 0 "register_operand" "=r")
19712 [(match_operand:SWI48 1 "symbol_operand")]
19716 if (x86_64_immediate_size_operand (operands[1], VOIDmode))
19717 return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
19719 return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
19721 [(set_attr "type" "imov")
19722 (set_attr "mode" "<MODE>")])
19724 ;; RDPKRU and WRPKRU
19726 (define_expand "rdpkru"
19728 [(set (match_operand:SI 0 "register_operand")
19729 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
19730 (set (match_dup 2) (const_int 0))])]
19733 operands[1] = force_reg (SImode, const0_rtx);
19734 operands[2] = gen_reg_rtx (SImode);
19737 (define_insn "*rdpkru"
19738 [(set (match_operand:SI 0 "register_operand" "=a")
19739 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
19741 (set (match_operand:SI 1 "register_operand" "=d")
19745 [(set_attr "type" "other")])
19747 (define_expand "wrpkru"
19748 [(unspec_volatile:SI
19749 [(match_operand:SI 0 "register_operand")
19750 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
19753 operands[1] = force_reg (SImode, const0_rtx);
19754 operands[2] = force_reg (SImode, const0_rtx);
19757 (define_insn "*wrpkru"
19758 [(unspec_volatile:SI
19759 [(match_operand:SI 0 "register_operand" "a")
19760 (match_operand:SI 1 "register_operand" "d")
19761 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
19764 [(set_attr "type" "other")])
19768 (include "sync.md")