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
99 ;; Other random patterns
107 UNSPEC_LD_MPIC ; load_macho_picbase
109 UNSPEC_DIV_ALREADY_SPLIT
115 UNSPEC_INSN_FALSE_DEP
117 ;; For SSE/MMX support:
125 ;; Generic math support
127 UNSPEC_IEEE_MIN ; not commutative
128 UNSPEC_IEEE_MAX ; not commutative
130 ;; x87 Floating point
146 UNSPEC_FRNDINT_MASK_PM
150 ;; x87 Double output FP
184 ;; For AVX512F support
198 (define_c_enum "unspecv" [
201 UNSPECV_PROBE_STACK_RANGE
204 UNSPECV_SPLIT_STACK_RETURN
210 UNSPECV_LLWP_INTRINSIC
211 UNSPECV_SLWP_INTRINSIC
212 UNSPECV_LWPVAL_INTRINSIC
213 UNSPECV_LWPINS_INTRINSIC
235 ;; For atomic compound assignments.
241 ;; For RDRAND support
244 ;; For RDSEED support
258 ;; For PCOMMIT support
261 ;; For CLFLUSHOPT support
264 ;; For MONITORX and MWAITX support
268 ;; For CLZERO support
271 ;; For RDPKRU and WRPKRU support
275 ;; Constants to represent rounding modes in the ROUND instruction
284 ;; Constants to represent AVX512F embeded rounding
286 [(ROUND_NEAREST_INT 0)
294 ;; Constants to represent pcomtrue/pcomfalse variants
304 ;; Constants used in the XOP pperm instruction
306 [(PPERM_SRC 0x00) /* copy source */
307 (PPERM_INVERT 0x20) /* invert source */
308 (PPERM_REVERSE 0x40) /* bit reverse source */
309 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
310 (PPERM_ZERO 0x80) /* all 0's */
311 (PPERM_ONES 0xa0) /* all 1's */
312 (PPERM_SIGN 0xc0) /* propagate sign bit */
313 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
314 (PPERM_SRC1 0x00) /* use first source byte */
315 (PPERM_SRC2 0x10) /* use second source byte */
318 ;; Registers by name.
401 (FIRST_PSEUDO_REG 81)
404 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
407 ;; In C guard expressions, put expressions which may be compile-time
408 ;; constants first. This allows for better optimization. For
409 ;; example, write "TARGET_64BIT && reload_completed", not
410 ;; "reload_completed && TARGET_64BIT".
414 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
415 atom,slm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
416 bdver4,btver2,znver1"
417 (const (symbol_ref "ix86_schedule")))
419 ;; A basic instruction type. Refinements due to arguments to be
420 ;; provided in other attributes.
423 alu,alu1,negnot,imov,imovx,lea,
424 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
425 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
426 push,pop,call,callv,leave,
428 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
429 fxch,fistp,fisttp,frndint,
430 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
431 ssemul,sseimul,ssediv,sselog,sselog1,
432 sseishft,sseishft1,ssecmp,ssecomi,
433 ssecvt,ssecvt1,sseicvt,sseins,
434 sseshuf,sseshuf1,ssemuladd,sse4arg,
436 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
437 mpxmov,mpxmk,mpxchk,mpxld,mpxst"
438 (const_string "other"))
440 ;; Main data type used by the insn
442 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
444 (const_string "unknown"))
446 ;; The CPU unit operations uses.
447 (define_attr "unit" "integer,i387,sse,mmx,unknown"
448 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
449 fxch,fistp,fisttp,frndint")
450 (const_string "i387")
451 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
452 ssemul,sseimul,ssediv,sselog,sselog1,
453 sseishft,sseishft1,ssecmp,ssecomi,
454 ssecvt,ssecvt1,sseicvt,sseins,
455 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
457 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
459 (eq_attr "type" "other")
460 (const_string "unknown")]
461 (const_string "integer")))
463 ;; The minimum required alignment of vector mode memory operands of the SSE
464 ;; (non-VEX/EVEX) instruction in bits, if it is different from
465 ;; GET_MODE_ALIGNMENT of the operand, otherwise 0. If an instruction has
466 ;; multiple alternatives, this should be conservative maximum of those minimum
467 ;; required alignments.
468 (define_attr "ssememalign" "" (const_int 0))
470 ;; The (bounding maximum) length of an instruction immediate.
471 (define_attr "length_immediate" ""
472 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
473 bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
476 (eq_attr "unit" "i387,sse,mmx")
478 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
479 rotate,rotatex,rotate1,imul,icmp,push,pop")
480 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
481 (eq_attr "type" "imov,test")
482 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
483 (eq_attr "type" "call")
484 (if_then_else (match_operand 0 "constant_call_address_operand")
487 (eq_attr "type" "callv")
488 (if_then_else (match_operand 1 "constant_call_address_operand")
491 ;; We don't know the size before shorten_branches. Expect
492 ;; the instruction to fit for better scheduling.
493 (eq_attr "type" "ibr")
496 (symbol_ref "/* Update immediate_length and other attributes! */
497 gcc_unreachable (),1")))
499 ;; The (bounding maximum) length of an instruction address.
500 (define_attr "length_address" ""
501 (cond [(eq_attr "type" "str,other,multi,fxch")
503 (and (eq_attr "type" "call")
504 (match_operand 0 "constant_call_address_operand"))
506 (and (eq_attr "type" "callv")
507 (match_operand 1 "constant_call_address_operand"))
510 (symbol_ref "ix86_attr_length_address_default (insn)")))
512 ;; Set when length prefix is used.
513 (define_attr "prefix_data16" ""
514 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
516 (eq_attr "mode" "HI")
518 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
523 ;; Set when string REP prefix is used.
524 (define_attr "prefix_rep" ""
525 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
527 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
529 (and (eq_attr "type" "ibr,call,callv")
530 (match_test "ix86_bnd_prefixed_insn_p (insn)"))
535 ;; Set when 0f opcode prefix is used.
536 (define_attr "prefix_0f" ""
538 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
539 mpxmk,mpxmov,mpxchk,mpxld,mpxst")
540 (eq_attr "unit" "sse,mmx"))
544 ;; Set when REX opcode prefix is used.
545 (define_attr "prefix_rex" ""
546 (cond [(not (match_test "TARGET_64BIT"))
548 (and (eq_attr "mode" "DI")
549 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
550 (eq_attr "unit" "!mmx")))
552 (and (eq_attr "mode" "QI")
553 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
555 (match_test "x86_extended_reg_mentioned_p (insn)")
557 (and (eq_attr "type" "imovx")
558 (match_operand:QI 1 "ext_QIreg_operand"))
563 ;; There are also additional prefixes in 3DNOW, SSSE3.
564 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
565 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
566 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
567 (define_attr "prefix_extra" ""
568 (cond [(eq_attr "type" "ssemuladd,sse4arg")
570 (eq_attr "type" "sseiadd1,ssecvt1")
575 ;; Set when BND opcode prefix may be used.
576 (define_attr "maybe_prefix_bnd" "" (const_int 0))
578 ;; Prefix used: original, VEX or maybe VEX.
579 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
580 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
582 (eq_attr "mode" "XI,V16SF,V8DF")
583 (const_string "evex")
585 (const_string "orig")))
587 ;; VEX W bit is used.
588 (define_attr "prefix_vex_w" "" (const_int 0))
590 ;; The length of VEX prefix
591 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
592 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
593 ;; still prefix_0f 1, with prefix_extra 1.
594 (define_attr "length_vex" ""
595 (if_then_else (and (eq_attr "prefix_0f" "1")
596 (eq_attr "prefix_extra" "0"))
597 (if_then_else (eq_attr "prefix_vex_w" "1")
598 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
599 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
600 (if_then_else (eq_attr "prefix_vex_w" "1")
601 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
602 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
604 ;; 4-bytes evex prefix and 1 byte opcode.
605 (define_attr "length_evex" "" (const_int 5))
607 ;; Set when modrm byte is used.
608 (define_attr "modrm" ""
609 (cond [(eq_attr "type" "str,leave")
611 (eq_attr "unit" "i387")
613 (and (eq_attr "type" "incdec")
614 (and (not (match_test "TARGET_64BIT"))
615 (ior (match_operand:SI 1 "register_operand")
616 (match_operand:HI 1 "register_operand"))))
618 (and (eq_attr "type" "push")
619 (not (match_operand 1 "memory_operand")))
621 (and (eq_attr "type" "pop")
622 (not (match_operand 0 "memory_operand")))
624 (and (eq_attr "type" "imov")
625 (and (not (eq_attr "mode" "DI"))
626 (ior (and (match_operand 0 "register_operand")
627 (match_operand 1 "immediate_operand"))
628 (ior (and (match_operand 0 "ax_reg_operand")
629 (match_operand 1 "memory_displacement_only_operand"))
630 (and (match_operand 0 "memory_displacement_only_operand")
631 (match_operand 1 "ax_reg_operand"))))))
633 (and (eq_attr "type" "call")
634 (match_operand 0 "constant_call_address_operand"))
636 (and (eq_attr "type" "callv")
637 (match_operand 1 "constant_call_address_operand"))
639 (and (eq_attr "type" "alu,alu1,icmp,test")
640 (match_operand 0 "ax_reg_operand"))
641 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
645 (define_attr "modrm_class" "none,incdec,op0,op01,op02,pushpop,unknown"
646 (cond [(eq_attr "modrm" "0")
647 (const_string "none")
648 (eq_attr "type" "alu,imul,ishift")
649 (const_string "op02")
650 (eq_attr "type" "imov,imovx,lea,alu1,icmp")
651 (const_string "op01")
652 (eq_attr "type" "incdec")
653 (const_string "incdec")
654 (eq_attr "type" "push,pop")
655 (const_string "pushpop")]
656 (const_string "unknown")))
658 ;; The (bounding maximum) length of an instruction in bytes.
659 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
660 ;; Later we may want to split them and compute proper length as for
662 (define_attr "length" ""
663 (cond [(eq_attr "type" "other,multi,fistp,frndint")
665 (eq_attr "type" "fcmp")
667 (eq_attr "unit" "i387")
669 (plus (attr "prefix_data16")
670 (attr "length_address")))
671 (ior (eq_attr "prefix" "evex")
672 (and (ior (eq_attr "prefix" "maybe_evex")
673 (eq_attr "prefix" "maybe_vex"))
674 (match_test "TARGET_AVX512F")))
675 (plus (attr "length_evex")
676 (plus (attr "length_immediate")
678 (attr "length_address"))))
679 (ior (eq_attr "prefix" "vex")
680 (and (ior (eq_attr "prefix" "maybe_vex")
681 (eq_attr "prefix" "maybe_evex"))
682 (match_test "TARGET_AVX")))
683 (plus (attr "length_vex")
684 (plus (attr "length_immediate")
686 (attr "length_address"))))]
687 (plus (plus (attr "modrm")
688 (plus (attr "prefix_0f")
689 (plus (attr "prefix_rex")
690 (plus (attr "prefix_extra")
692 (plus (attr "prefix_rep")
693 (plus (attr "prefix_data16")
694 (plus (attr "length_immediate")
695 (attr "length_address")))))))
697 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
698 ;; `store' if there is a simple memory reference therein, or `unknown'
699 ;; if the instruction is complex.
701 (define_attr "memory" "none,load,store,both,unknown"
702 (cond [(eq_attr "type" "other,multi,str,lwp")
703 (const_string "unknown")
704 (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
705 (const_string "none")
706 (eq_attr "type" "fistp,leave")
707 (const_string "both")
708 (eq_attr "type" "frndint")
709 (const_string "load")
710 (eq_attr "type" "mpxld")
711 (const_string "load")
712 (eq_attr "type" "mpxst")
713 (const_string "store")
714 (eq_attr "type" "push")
715 (if_then_else (match_operand 1 "memory_operand")
716 (const_string "both")
717 (const_string "store"))
718 (eq_attr "type" "pop")
719 (if_then_else (match_operand 0 "memory_operand")
720 (const_string "both")
721 (const_string "load"))
722 (eq_attr "type" "setcc")
723 (if_then_else (match_operand 0 "memory_operand")
724 (const_string "store")
725 (const_string "none"))
726 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
727 (if_then_else (ior (match_operand 0 "memory_operand")
728 (match_operand 1 "memory_operand"))
729 (const_string "load")
730 (const_string "none"))
731 (eq_attr "type" "ibr")
732 (if_then_else (match_operand 0 "memory_operand")
733 (const_string "load")
734 (const_string "none"))
735 (eq_attr "type" "call")
736 (if_then_else (match_operand 0 "constant_call_address_operand")
737 (const_string "none")
738 (const_string "load"))
739 (eq_attr "type" "callv")
740 (if_then_else (match_operand 1 "constant_call_address_operand")
741 (const_string "none")
742 (const_string "load"))
743 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
744 (match_operand 1 "memory_operand"))
745 (const_string "both")
746 (and (match_operand 0 "memory_operand")
747 (match_operand 1 "memory_operand"))
748 (const_string "both")
749 (match_operand 0 "memory_operand")
750 (const_string "store")
751 (match_operand 1 "memory_operand")
752 (const_string "load")
754 "!alu1,negnot,ishift1,
755 imov,imovx,icmp,test,bitmanip,
757 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
758 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
759 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
760 (match_operand 2 "memory_operand"))
761 (const_string "load")
762 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
763 (match_operand 3 "memory_operand"))
764 (const_string "load")
766 (const_string "none")))
768 ;; Indicates if an instruction has both an immediate and a displacement.
770 (define_attr "imm_disp" "false,true,unknown"
771 (cond [(eq_attr "type" "other,multi")
772 (const_string "unknown")
773 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
774 (and (match_operand 0 "memory_displacement_operand")
775 (match_operand 1 "immediate_operand")))
776 (const_string "true")
777 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
778 (and (match_operand 0 "memory_displacement_operand")
779 (match_operand 2 "immediate_operand")))
780 (const_string "true")
782 (const_string "false")))
784 ;; Indicates if an FP operation has an integer source.
786 (define_attr "fp_int_src" "false,true"
787 (const_string "false"))
789 ;; Defines rounding mode of an FP operation.
791 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
792 (const_string "any"))
794 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
795 (define_attr "use_carry" "0,1" (const_string "0"))
797 ;; Define attribute to indicate unaligned ssemov insns
798 (define_attr "movu" "0,1" (const_string "0"))
800 ;; Used to control the "enabled" attribute on a per-instruction basis.
801 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
802 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
803 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
804 fma_avx512f,avx512bw,noavx512bw,avx512dq,noavx512dq,
806 (const_string "base"))
808 (define_attr "enabled" ""
809 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
810 (eq_attr "isa" "x64_sse4")
811 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
812 (eq_attr "isa" "x64_sse4_noavx")
813 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
814 (eq_attr "isa" "x64_avx")
815 (symbol_ref "TARGET_64BIT && TARGET_AVX")
816 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
817 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
818 (eq_attr "isa" "sse2_noavx")
819 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
820 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
821 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
822 (eq_attr "isa" "sse4_noavx")
823 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
824 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
825 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
826 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
827 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
828 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
829 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
830 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
831 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
832 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
833 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
834 (eq_attr "isa" "fma_avx512f")
835 (symbol_ref "TARGET_FMA || TARGET_AVX512F")
836 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
837 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
838 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
839 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
840 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
841 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
845 (define_attr "preferred_for_size" "" (const_int 1))
846 (define_attr "preferred_for_speed" "" (const_int 1))
848 ;; Describe a user's asm statement.
849 (define_asm_attributes
850 [(set_attr "length" "128")
851 (set_attr "type" "multi")])
853 (define_code_iterator plusminus [plus minus])
855 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
857 (define_code_iterator multdiv [mult div])
859 ;; Base name for define_insn
860 (define_code_attr plusminus_insn
861 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
862 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
864 ;; Base name for insn mnemonic.
865 (define_code_attr plusminus_mnemonic
866 [(plus "add") (ss_plus "adds") (us_plus "addus")
867 (minus "sub") (ss_minus "subs") (us_minus "subus")])
868 (define_code_attr multdiv_mnemonic
869 [(mult "mul") (div "div")])
871 ;; Mark commutative operators as such in constraints.
872 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
873 (minus "") (ss_minus "") (us_minus "")])
875 ;; Mapping of max and min
876 (define_code_iterator maxmin [smax smin umax umin])
878 ;; Mapping of signed max and min
879 (define_code_iterator smaxmin [smax smin])
881 ;; Mapping of unsigned max and min
882 (define_code_iterator umaxmin [umax umin])
884 ;; Base name for integer and FP insn mnemonic
885 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
886 (umax "maxu") (umin "minu")])
887 (define_code_attr maxmin_float [(smax "max") (smin "min")])
889 ;; Mapping of logic operators
890 (define_code_iterator any_logic [and ior xor])
891 (define_code_iterator any_or [ior xor])
892 (define_code_iterator fpint_logic [and xor])
894 ;; Base name for insn mnemonic.
895 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
897 ;; Mapping of logic-shift operators
898 (define_code_iterator any_lshift [ashift lshiftrt])
900 ;; Mapping of shift-right operators
901 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
903 ;; Mapping of all shift operators
904 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
906 ;; Base name for define_insn
907 (define_code_attr shift_insn
908 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
910 ;; Base name for insn mnemonic.
911 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
912 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
914 ;; Mask variant left right mnemonics
915 (define_code_attr mshift [(ashift "shiftl") (lshiftrt "shiftr")])
917 ;; Mapping of rotate operators
918 (define_code_iterator any_rotate [rotate rotatert])
920 ;; Base name for define_insn
921 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
923 ;; Base name for insn mnemonic.
924 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
926 ;; Mapping of abs neg operators
927 (define_code_iterator absneg [abs neg])
929 ;; Base name for x87 insn mnemonic.
930 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
932 ;; Used in signed and unsigned widening multiplications.
933 (define_code_iterator any_extend [sign_extend zero_extend])
935 ;; Prefix for insn menmonic.
936 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
938 ;; Prefix for define_insn
939 (define_code_attr u [(sign_extend "") (zero_extend "u")])
940 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
941 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
943 ;; Used in signed and unsigned truncations.
944 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
945 ;; Instruction suffix for truncations.
946 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
948 ;; Used in signed and unsigned fix.
949 (define_code_iterator any_fix [fix unsigned_fix])
950 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
952 ;; Used in signed and unsigned float.
953 (define_code_iterator any_float [float unsigned_float])
954 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
956 ;; All integer modes.
957 (define_mode_iterator SWI1248x [QI HI SI DI])
959 ;; All integer modes with AVX512BW/DQ.
960 (define_mode_iterator SWI1248_AVX512BWDQ
961 [(QI "TARGET_AVX512DQ") HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
963 ;; All integer modes without QImode.
964 (define_mode_iterator SWI248x [HI SI DI])
966 ;; All integer modes without QImode and HImode.
967 (define_mode_iterator SWI48x [SI DI])
969 ;; All integer modes without SImode and DImode.
970 (define_mode_iterator SWI12 [QI HI])
972 ;; All integer modes without DImode.
973 (define_mode_iterator SWI124 [QI HI SI])
975 ;; All integer modes without QImode and DImode.
976 (define_mode_iterator SWI24 [HI SI])
978 ;; Single word integer modes.
979 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
981 ;; Single word integer modes without QImode.
982 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
984 ;; Single word integer modes without QImode and HImode.
985 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
987 ;; All math-dependant single and double word integer modes.
988 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
989 (HI "TARGET_HIMODE_MATH")
990 SI DI (TI "TARGET_64BIT")])
992 ;; Math-dependant single word integer modes.
993 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
994 (HI "TARGET_HIMODE_MATH")
995 SI (DI "TARGET_64BIT")])
997 ;; Math-dependant integer modes without DImode.
998 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
999 (HI "TARGET_HIMODE_MATH")
1002 ;; Math-dependant integer modes with DImode.
1003 (define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH")
1004 (HI "TARGET_HIMODE_MATH")
1005 SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")])
1007 ;; Math-dependant single word integer modes without QImode.
1008 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1009 SI (DI "TARGET_64BIT")])
1011 ;; Double word integer modes.
1012 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1013 (TI "TARGET_64BIT")])
1015 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1016 ;; compile time constant, it is faster to use <MODE_SIZE> than
1017 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1018 ;; command line options just use GET_MODE_SIZE macro.
1019 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1020 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1021 (V16QI "16") (V32QI "32") (V64QI "64")
1022 (V8HI "16") (V16HI "32") (V32HI "64")
1023 (V4SI "16") (V8SI "32") (V16SI "64")
1024 (V2DI "16") (V4DI "32") (V8DI "64")
1025 (V1TI "16") (V2TI "32") (V4TI "64")
1026 (V2DF "16") (V4DF "32") (V8DF "64")
1027 (V4SF "16") (V8SF "32") (V16SF "64")])
1029 ;; Double word integer modes as mode attribute.
1030 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1031 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1033 ;; Half mode for double word integer modes.
1034 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1035 (DI "TARGET_64BIT")])
1038 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1039 (BND64 "TARGET_LP64")])
1041 ;; Pointer mode corresponding to bound mode.
1042 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1045 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1048 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1050 (UNSPEC_BNDCN "cn")])
1052 ;; Instruction suffix for integer modes.
1053 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1055 ;; Instruction suffix for masks.
1056 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1058 ;; Pointer size prefix for integer modes (Intel asm dialect)
1059 (define_mode_attr iptrsize [(QI "BYTE")
1064 ;; Register class for integer modes.
1065 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1067 ;; Immediate operand constraint for integer modes.
1068 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1070 ;; General operand constraint for word modes.
1071 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1073 ;; Immediate operand constraint for double integer modes.
1074 (define_mode_attr di [(SI "nF") (DI "e")])
1076 ;; Immediate operand constraint for shifts.
1077 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1079 ;; General operand predicate for integer modes.
1080 (define_mode_attr general_operand
1081 [(QI "general_operand")
1082 (HI "general_operand")
1083 (SI "x86_64_general_operand")
1084 (DI "x86_64_general_operand")
1085 (TI "x86_64_general_operand")])
1087 ;; General sign extend operand predicate for integer modes,
1088 ;; which disallows VOIDmode operands and thus it is suitable
1089 ;; for use inside sign_extend.
1090 (define_mode_attr general_sext_operand
1091 [(QI "sext_operand")
1093 (SI "x86_64_sext_operand")
1094 (DI "x86_64_sext_operand")])
1096 ;; General sign/zero extend operand predicate for integer modes.
1097 (define_mode_attr general_szext_operand
1098 [(QI "general_operand")
1099 (HI "general_operand")
1100 (SI "x86_64_szext_general_operand")
1101 (DI "x86_64_szext_general_operand")])
1103 ;; Immediate operand predicate for integer modes.
1104 (define_mode_attr immediate_operand
1105 [(QI "immediate_operand")
1106 (HI "immediate_operand")
1107 (SI "x86_64_immediate_operand")
1108 (DI "x86_64_immediate_operand")])
1110 ;; Nonmemory operand predicate for integer modes.
1111 (define_mode_attr nonmemory_operand
1112 [(QI "nonmemory_operand")
1113 (HI "nonmemory_operand")
1114 (SI "x86_64_nonmemory_operand")
1115 (DI "x86_64_nonmemory_operand")])
1117 ;; Operand predicate for shifts.
1118 (define_mode_attr shift_operand
1119 [(QI "nonimmediate_operand")
1120 (HI "nonimmediate_operand")
1121 (SI "nonimmediate_operand")
1122 (DI "shiftdi_operand")
1123 (TI "register_operand")])
1125 ;; Operand predicate for shift argument.
1126 (define_mode_attr shift_immediate_operand
1127 [(QI "const_1_to_31_operand")
1128 (HI "const_1_to_31_operand")
1129 (SI "const_1_to_31_operand")
1130 (DI "const_1_to_63_operand")])
1132 ;; Input operand predicate for arithmetic left shifts.
1133 (define_mode_attr ashl_input_operand
1134 [(QI "nonimmediate_operand")
1135 (HI "nonimmediate_operand")
1136 (SI "nonimmediate_operand")
1137 (DI "ashldi_input_operand")
1138 (TI "reg_or_pm1_operand")])
1140 ;; SSE and x87 SFmode and DFmode floating point modes
1141 (define_mode_iterator MODEF [SF DF])
1143 ;; All x87 floating point modes
1144 (define_mode_iterator X87MODEF [SF DF XF])
1146 ;; SSE instruction suffix for various modes
1147 (define_mode_attr ssemodesuffix
1148 [(SF "ss") (DF "sd")
1149 (V16SF "ps") (V8DF "pd")
1150 (V8SF "ps") (V4DF "pd")
1151 (V4SF "ps") (V2DF "pd")
1152 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1153 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1154 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1156 ;; SSE vector suffix for floating point modes
1157 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1159 ;; SSE vector mode corresponding to a scalar mode
1160 (define_mode_attr ssevecmode
1161 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1162 (define_mode_attr ssevecmodelower
1163 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1165 ;; Instruction suffix for REX 64bit operators.
1166 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1168 ;; This mode iterator allows :P to be used for patterns that operate on
1169 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1170 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1172 ;; This mode iterator allows :W to be used for patterns that operate on
1173 ;; word_mode sized quantities.
1174 (define_mode_iterator W
1175 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1177 ;; This mode iterator allows :PTR to be used for patterns that operate on
1178 ;; ptr_mode sized quantities.
1179 (define_mode_iterator PTR
1180 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1182 ;; Scheduling descriptions
1184 (include "pentium.md")
1187 (include "athlon.md")
1188 (include "bdver1.md")
1189 (include "bdver3.md")
1190 (include "btver2.md")
1191 (include "znver1.md")
1192 (include "geode.md")
1195 (include "core2.md")
1196 (include "haswell.md")
1199 ;; Operand and operator predicates and constraints
1201 (include "predicates.md")
1202 (include "constraints.md")
1205 ;; Compare and branch/compare and store instructions.
1207 (define_expand "cbranch<mode>4"
1208 [(set (reg:CC FLAGS_REG)
1209 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1210 (match_operand:SDWIM 2 "<general_operand>")))
1211 (set (pc) (if_then_else
1212 (match_operator 0 "ordered_comparison_operator"
1213 [(reg:CC FLAGS_REG) (const_int 0)])
1214 (label_ref (match_operand 3))
1218 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1219 operands[1] = force_reg (<MODE>mode, operands[1]);
1220 ix86_expand_branch (GET_CODE (operands[0]),
1221 operands[1], operands[2], operands[3]);
1225 (define_expand "cstore<mode>4"
1226 [(set (reg:CC FLAGS_REG)
1227 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1228 (match_operand:SWIM 3 "<general_operand>")))
1229 (set (match_operand:QI 0 "register_operand")
1230 (match_operator 1 "ordered_comparison_operator"
1231 [(reg:CC FLAGS_REG) (const_int 0)]))]
1234 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1235 operands[2] = force_reg (<MODE>mode, operands[2]);
1236 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1237 operands[2], operands[3]);
1241 (define_expand "cmp<mode>_1"
1242 [(set (reg:CC FLAGS_REG)
1243 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1244 (match_operand:SWI48 1 "<general_operand>")))])
1246 (define_insn "*cmp<mode>_ccno_1"
1247 [(set (reg FLAGS_REG)
1248 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1249 (match_operand:SWI 1 "const0_operand")))]
1250 "ix86_match_ccmode (insn, CCNOmode)"
1252 test{<imodesuffix>}\t%0, %0
1253 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1254 [(set_attr "type" "test,icmp")
1255 (set_attr "length_immediate" "0,1")
1256 (set_attr "modrm_class" "op0,unknown")
1257 (set_attr "mode" "<MODE>")])
1259 (define_insn "*cmp<mode>_1"
1260 [(set (reg FLAGS_REG)
1261 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1262 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1263 "ix86_match_ccmode (insn, CCmode)"
1264 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1265 [(set_attr "type" "icmp")
1266 (set_attr "mode" "<MODE>")])
1268 (define_insn "*cmp<mode>_minus_1"
1269 [(set (reg FLAGS_REG)
1271 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1272 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1274 "ix86_match_ccmode (insn, CCGOCmode)"
1275 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1276 [(set_attr "type" "icmp")
1277 (set_attr "mode" "<MODE>")])
1279 (define_insn "*cmpqi_ext_1"
1280 [(set (reg FLAGS_REG)
1282 (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1285 (match_operand 1 "ext_register_operand" "Q,Q")
1287 (const_int 8)) 0)))]
1288 "ix86_match_ccmode (insn, CCmode)"
1289 "cmp{b}\t{%h1, %0|%0, %h1}"
1290 [(set_attr "isa" "*,nox64")
1291 (set_attr "type" "icmp")
1292 (set_attr "mode" "QI")])
1294 (define_insn "*cmpqi_ext_2"
1295 [(set (reg FLAGS_REG)
1299 (match_operand 0 "ext_register_operand" "Q")
1302 (match_operand:QI 1 "const0_operand")))]
1303 "ix86_match_ccmode (insn, CCNOmode)"
1305 [(set_attr "type" "test")
1306 (set_attr "length_immediate" "0")
1307 (set_attr "mode" "QI")])
1309 (define_expand "cmpqi_ext_3"
1310 [(set (reg:CC FLAGS_REG)
1314 (match_operand 0 "ext_register_operand")
1317 (match_operand:QI 1 "const_int_operand")))])
1319 (define_insn "*cmpqi_ext_3"
1320 [(set (reg FLAGS_REG)
1324 (match_operand 0 "ext_register_operand" "Q,Q")
1327 (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1328 "ix86_match_ccmode (insn, CCmode)"
1329 "cmp{b}\t{%1, %h0|%h0, %1}"
1330 [(set_attr "isa" "*,nox64")
1331 (set_attr "type" "icmp")
1332 (set_attr "modrm" "1")
1333 (set_attr "mode" "QI")])
1335 (define_insn "*cmpqi_ext_4"
1336 [(set (reg FLAGS_REG)
1340 (match_operand 0 "ext_register_operand" "Q")
1345 (match_operand 1 "ext_register_operand" "Q")
1347 (const_int 8)) 0)))]
1348 "ix86_match_ccmode (insn, CCmode)"
1349 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1350 [(set_attr "type" "icmp")
1351 (set_attr "mode" "QI")])
1353 ;; These implement float point compares.
1354 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1355 ;; which would allow mix and match FP modes on the compares. Which is what
1356 ;; the old patterns did, but with many more of them.
1358 (define_expand "cbranchxf4"
1359 [(set (reg:CC FLAGS_REG)
1360 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1361 (match_operand:XF 2 "nonmemory_operand")))
1362 (set (pc) (if_then_else
1363 (match_operator 0 "ix86_fp_comparison_operator"
1366 (label_ref (match_operand 3))
1370 ix86_expand_branch (GET_CODE (operands[0]),
1371 operands[1], operands[2], operands[3]);
1375 (define_expand "cstorexf4"
1376 [(set (reg:CC FLAGS_REG)
1377 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1378 (match_operand:XF 3 "nonmemory_operand")))
1379 (set (match_operand:QI 0 "register_operand")
1380 (match_operator 1 "ix86_fp_comparison_operator"
1385 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1386 operands[2], operands[3]);
1390 (define_expand "cbranch<mode>4"
1391 [(set (reg:CC FLAGS_REG)
1392 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1393 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1394 (set (pc) (if_then_else
1395 (match_operator 0 "ix86_fp_comparison_operator"
1398 (label_ref (match_operand 3))
1400 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1402 ix86_expand_branch (GET_CODE (operands[0]),
1403 operands[1], operands[2], operands[3]);
1407 (define_expand "cstore<mode>4"
1408 [(set (reg:CC FLAGS_REG)
1409 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1410 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1411 (set (match_operand:QI 0 "register_operand")
1412 (match_operator 1 "ix86_fp_comparison_operator"
1415 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1417 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1418 operands[2], operands[3]);
1422 (define_expand "cbranchcc4"
1423 [(set (pc) (if_then_else
1424 (match_operator 0 "comparison_operator"
1425 [(match_operand 1 "flags_reg_operand")
1426 (match_operand 2 "const0_operand")])
1427 (label_ref (match_operand 3))
1431 ix86_expand_branch (GET_CODE (operands[0]),
1432 operands[1], operands[2], operands[3]);
1436 (define_expand "cstorecc4"
1437 [(set (match_operand:QI 0 "register_operand")
1438 (match_operator 1 "comparison_operator"
1439 [(match_operand 2 "flags_reg_operand")
1440 (match_operand 3 "const0_operand")]))]
1443 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1444 operands[2], operands[3]);
1449 ;; FP compares, step 1:
1450 ;; Set the FP condition codes.
1452 ;; CCFPmode compare with exceptions
1453 ;; CCFPUmode compare with no exceptions
1455 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1456 ;; used to manage the reg stack popping would not be preserved.
1458 (define_insn "*cmp<mode>_0_i387"
1459 [(set (match_operand:HI 0 "register_operand" "=a")
1462 (match_operand:X87MODEF 1 "register_operand" "f")
1463 (match_operand:X87MODEF 2 "const0_operand"))]
1466 "* return output_fp_compare (insn, operands, false, false);"
1467 [(set_attr "type" "multi")
1468 (set_attr "unit" "i387")
1469 (set_attr "mode" "<MODE>")])
1471 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1472 [(set (reg:CCFP FLAGS_REG)
1474 (match_operand:X87MODEF 1 "register_operand" "f")
1475 (match_operand:X87MODEF 2 "const0_operand")))
1476 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1477 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1479 "&& reload_completed"
1482 [(compare:CCFP (match_dup 1)(match_dup 2))]
1484 (set (reg:CC FLAGS_REG)
1485 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1487 [(set_attr "type" "multi")
1488 (set_attr "unit" "i387")
1489 (set_attr "mode" "<MODE>")])
1491 (define_insn "*cmpxf_i387"
1492 [(set (match_operand:HI 0 "register_operand" "=a")
1495 (match_operand:XF 1 "register_operand" "f")
1496 (match_operand:XF 2 "register_operand" "f"))]
1499 "* return output_fp_compare (insn, operands, false, false);"
1500 [(set_attr "type" "multi")
1501 (set_attr "unit" "i387")
1502 (set_attr "mode" "XF")])
1504 (define_insn_and_split "*cmpxf_cc_i387"
1505 [(set (reg:CCFP FLAGS_REG)
1507 (match_operand:XF 1 "register_operand" "f")
1508 (match_operand:XF 2 "register_operand" "f")))
1509 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1510 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1512 "&& reload_completed"
1515 [(compare:CCFP (match_dup 1)(match_dup 2))]
1517 (set (reg:CC FLAGS_REG)
1518 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1520 [(set_attr "type" "multi")
1521 (set_attr "unit" "i387")
1522 (set_attr "mode" "XF")])
1524 (define_insn "*cmp<mode>_i387"
1525 [(set (match_operand:HI 0 "register_operand" "=a")
1528 (match_operand:MODEF 1 "register_operand" "f")
1529 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1532 "* return output_fp_compare (insn, operands, false, false);"
1533 [(set_attr "type" "multi")
1534 (set_attr "unit" "i387")
1535 (set_attr "mode" "<MODE>")])
1537 (define_insn_and_split "*cmp<mode>_cc_i387"
1538 [(set (reg:CCFP FLAGS_REG)
1540 (match_operand:MODEF 1 "register_operand" "f")
1541 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1542 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1543 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1545 "&& reload_completed"
1548 [(compare:CCFP (match_dup 1)(match_dup 2))]
1550 (set (reg:CC FLAGS_REG)
1551 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1553 [(set_attr "type" "multi")
1554 (set_attr "unit" "i387")
1555 (set_attr "mode" "<MODE>")])
1557 (define_insn "*cmpu<mode>_i387"
1558 [(set (match_operand:HI 0 "register_operand" "=a")
1561 (match_operand:X87MODEF 1 "register_operand" "f")
1562 (match_operand:X87MODEF 2 "register_operand" "f"))]
1565 "* return output_fp_compare (insn, operands, false, true);"
1566 [(set_attr "type" "multi")
1567 (set_attr "unit" "i387")
1568 (set_attr "mode" "<MODE>")])
1570 (define_insn_and_split "*cmpu<mode>_cc_i387"
1571 [(set (reg:CCFPU FLAGS_REG)
1573 (match_operand:X87MODEF 1 "register_operand" "f")
1574 (match_operand:X87MODEF 2 "register_operand" "f")))
1575 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1576 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1578 "&& reload_completed"
1581 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1583 (set (reg:CC FLAGS_REG)
1584 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1586 [(set_attr "type" "multi")
1587 (set_attr "unit" "i387")
1588 (set_attr "mode" "<MODE>")])
1590 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1591 [(set (match_operand:HI 0 "register_operand" "=a")
1594 (match_operand:X87MODEF 1 "register_operand" "f")
1595 (match_operator:X87MODEF 3 "float_operator"
1596 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1599 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1600 || optimize_function_for_size_p (cfun))"
1601 "* return output_fp_compare (insn, operands, false, false);"
1602 [(set_attr "type" "multi")
1603 (set_attr "unit" "i387")
1604 (set_attr "fp_int_src" "true")
1605 (set_attr "mode" "<SWI24:MODE>")])
1607 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1608 [(set (reg:CCFP FLAGS_REG)
1610 (match_operand:X87MODEF 1 "register_operand" "f")
1611 (match_operator:X87MODEF 3 "float_operator"
1612 [(match_operand:SWI24 2 "memory_operand" "m")])))
1613 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1614 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1615 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1616 || optimize_function_for_size_p (cfun))"
1618 "&& reload_completed"
1623 (match_op_dup 3 [(match_dup 2)]))]
1625 (set (reg:CC FLAGS_REG)
1626 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1628 [(set_attr "type" "multi")
1629 (set_attr "unit" "i387")
1630 (set_attr "fp_int_src" "true")
1631 (set_attr "mode" "<SWI24:MODE>")])
1633 ;; FP compares, step 2
1634 ;; Move the fpsw to ax.
1636 (define_insn "x86_fnstsw_1"
1637 [(set (match_operand:HI 0 "register_operand" "=a")
1638 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1641 [(set_attr "length" "2")
1642 (set_attr "mode" "SI")
1643 (set_attr "unit" "i387")])
1645 ;; FP compares, step 3
1646 ;; Get ax into flags, general case.
1648 (define_insn "x86_sahf_1"
1649 [(set (reg:CC FLAGS_REG)
1650 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1654 #ifndef HAVE_AS_IX86_SAHF
1656 return ASM_BYTE "0x9e";
1661 [(set_attr "length" "1")
1662 (set_attr "athlon_decode" "vector")
1663 (set_attr "amdfam10_decode" "direct")
1664 (set_attr "bdver1_decode" "direct")
1665 (set_attr "mode" "SI")])
1667 ;; Pentium Pro can do steps 1 through 3 in one go.
1668 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1669 ;; (these i387 instructions set flags directly)
1671 (define_mode_iterator FPCMP [CCFP CCFPU])
1672 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1674 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1675 [(set (reg:FPCMP FLAGS_REG)
1677 (match_operand:MODEF 0 "register_operand" "f,v")
1678 (match_operand:MODEF 1 "nonimmediate_operand" "f,vm")))]
1679 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
1680 "* return output_fp_compare (insn, operands, true,
1681 <FPCMP:MODE>mode == CCFPUmode);"
1682 [(set_attr "type" "fcmp,ssecomi")
1683 (set_attr "prefix" "orig,maybe_vex")
1684 (set_attr "mode" "<MODEF:MODE>")
1685 (set_attr "prefix_rep" "*,0")
1686 (set (attr "prefix_data16")
1687 (cond [(eq_attr "alternative" "0")
1689 (eq_attr "mode" "DF")
1692 (const_string "0")))
1693 (set_attr "athlon_decode" "vector")
1694 (set_attr "amdfam10_decode" "direct")
1695 (set_attr "bdver1_decode" "double")
1696 (set_attr "znver1_decode" "double")
1697 (set (attr "enabled")
1698 (cond [(eq_attr "alternative" "0")
1699 (symbol_ref "TARGET_MIX_SSE_I387")
1701 (symbol_ref "true")))])
1703 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1704 [(set (reg:FPCMP FLAGS_REG)
1706 (match_operand:X87MODEF 0 "register_operand" "f")
1707 (match_operand:X87MODEF 1 "register_operand" "f")))]
1708 "TARGET_80387 && TARGET_CMOVE
1709 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1710 "* return output_fp_compare (insn, operands, true,
1711 <FPCMP:MODE>mode == CCFPUmode);"
1712 [(set_attr "type" "fcmp")
1713 (set_attr "mode" "<X87MODEF:MODE>")
1714 (set_attr "athlon_decode" "vector")
1715 (set_attr "amdfam10_decode" "direct")
1716 (set_attr "bdver1_decode" "double")
1717 (set_attr "znver1_decode" "double")])
1719 ;; Push/pop instructions.
1721 (define_insn "*push<mode>2"
1722 [(set (match_operand:DWI 0 "push_operand" "=<")
1723 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1726 [(set_attr "type" "multi")
1727 (set_attr "mode" "<MODE>")])
1730 [(set (match_operand:TI 0 "push_operand")
1731 (match_operand:TI 1 "general_operand"))]
1732 "TARGET_64BIT && reload_completed
1733 && !SSE_REG_P (operands[1])"
1735 "ix86_split_long_move (operands); DONE;")
1737 (define_insn "*pushdi2_rex64"
1738 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1739 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1744 [(set_attr "type" "push,multi")
1745 (set_attr "mode" "DI")])
1747 ;; Convert impossible pushes of immediate to existing instructions.
1748 ;; First try to get scratch register and go through it. In case this
1749 ;; fails, push sign extended lower part first and then overwrite
1750 ;; upper part by 32bit move.
1752 [(match_scratch:DI 2 "r")
1753 (set (match_operand:DI 0 "push_operand")
1754 (match_operand:DI 1 "immediate_operand"))]
1755 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1756 && !x86_64_immediate_operand (operands[1], DImode)"
1757 [(set (match_dup 2) (match_dup 1))
1758 (set (match_dup 0) (match_dup 2))])
1760 ;; We need to define this as both peepholer and splitter for case
1761 ;; peephole2 pass is not run.
1762 ;; "&& 1" is needed to keep it from matching the previous pattern.
1764 [(set (match_operand:DI 0 "push_operand")
1765 (match_operand:DI 1 "immediate_operand"))]
1766 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1767 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1768 [(set (match_dup 0) (match_dup 1))
1769 (set (match_dup 2) (match_dup 3))]
1771 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1773 operands[1] = gen_lowpart (DImode, operands[2]);
1774 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1779 [(set (match_operand:DI 0 "push_operand")
1780 (match_operand:DI 1 "immediate_operand"))]
1781 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1782 ? epilogue_completed : reload_completed)
1783 && !symbolic_operand (operands[1], DImode)
1784 && !x86_64_immediate_operand (operands[1], DImode)"
1785 [(set (match_dup 0) (match_dup 1))
1786 (set (match_dup 2) (match_dup 3))]
1788 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1790 operands[1] = gen_lowpart (DImode, operands[2]);
1791 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1796 [(set (match_operand:DI 0 "push_operand")
1797 (match_operand:DI 1 "general_operand"))]
1798 "!TARGET_64BIT && reload_completed
1799 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1801 "ix86_split_long_move (operands); DONE;")
1803 (define_insn "*pushsi2"
1804 [(set (match_operand:SI 0 "push_operand" "=<")
1805 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1808 [(set_attr "type" "push")
1809 (set_attr "mode" "SI")])
1811 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1812 ;; "push a byte/word". But actually we use pushl, which has the effect
1813 ;; of rounding the amount pushed up to a word.
1815 ;; For TARGET_64BIT we always round up to 8 bytes.
1816 (define_insn "*push<mode>2_rex64"
1817 [(set (match_operand:SWI124 0 "push_operand" "=X")
1818 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1821 [(set_attr "type" "push")
1822 (set_attr "mode" "DI")])
1824 (define_insn "*push<mode>2"
1825 [(set (match_operand:SWI12 0 "push_operand" "=X")
1826 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1829 [(set_attr "type" "push")
1830 (set_attr "mode" "SI")])
1832 (define_insn "*push<mode>2_prologue"
1833 [(set (match_operand:W 0 "push_operand" "=<")
1834 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1835 (clobber (mem:BLK (scratch)))]
1837 "push{<imodesuffix>}\t%1"
1838 [(set_attr "type" "push")
1839 (set_attr "mode" "<MODE>")])
1841 (define_insn "*pop<mode>1"
1842 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1843 (match_operand:W 1 "pop_operand" ">"))]
1845 "pop{<imodesuffix>}\t%0"
1846 [(set_attr "type" "pop")
1847 (set_attr "mode" "<MODE>")])
1849 (define_insn "*pop<mode>1_epilogue"
1850 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1851 (match_operand:W 1 "pop_operand" ">"))
1852 (clobber (mem:BLK (scratch)))]
1854 "pop{<imodesuffix>}\t%0"
1855 [(set_attr "type" "pop")
1856 (set_attr "mode" "<MODE>")])
1858 (define_insn "*pushfl<mode>2"
1859 [(set (match_operand:W 0 "push_operand" "=<")
1860 (match_operand:W 1 "flags_reg_operand"))]
1862 "pushf{<imodesuffix>}"
1863 [(set_attr "type" "push")
1864 (set_attr "mode" "<MODE>")])
1866 (define_insn "*popfl<mode>1"
1867 [(set (match_operand:W 0 "flags_reg_operand")
1868 (match_operand:W 1 "pop_operand" ">"))]
1870 "popf{<imodesuffix>}"
1871 [(set_attr "type" "pop")
1872 (set_attr "mode" "<MODE>")])
1875 ;; Reload patterns to support multi-word load/store
1876 ;; with non-offsetable address.
1877 (define_expand "reload_noff_store"
1878 [(parallel [(match_operand 0 "memory_operand" "=m")
1879 (match_operand 1 "register_operand" "r")
1880 (match_operand:DI 2 "register_operand" "=&r")])]
1883 rtx mem = operands[0];
1884 rtx addr = XEXP (mem, 0);
1886 emit_move_insn (operands[2], addr);
1887 mem = replace_equiv_address_nv (mem, operands[2]);
1889 emit_insn (gen_rtx_SET (mem, operands[1]));
1893 (define_expand "reload_noff_load"
1894 [(parallel [(match_operand 0 "register_operand" "=r")
1895 (match_operand 1 "memory_operand" "m")
1896 (match_operand:DI 2 "register_operand" "=r")])]
1899 rtx mem = operands[1];
1900 rtx addr = XEXP (mem, 0);
1902 emit_move_insn (operands[2], addr);
1903 mem = replace_equiv_address_nv (mem, operands[2]);
1905 emit_insn (gen_rtx_SET (operands[0], mem));
1909 ;; Move instructions.
1911 (define_expand "movxi"
1912 [(set (match_operand:XI 0 "nonimmediate_operand")
1913 (match_operand:XI 1 "general_operand"))]
1915 "ix86_expand_vector_move (XImode, operands); DONE;")
1917 (define_expand "movoi"
1918 [(set (match_operand:OI 0 "nonimmediate_operand")
1919 (match_operand:OI 1 "general_operand"))]
1921 "ix86_expand_vector_move (OImode, operands); DONE;")
1923 (define_expand "movti"
1924 [(set (match_operand:TI 0 "nonimmediate_operand")
1925 (match_operand:TI 1 "general_operand"))]
1926 "TARGET_64BIT || TARGET_SSE"
1929 ix86_expand_move (TImode, operands);
1931 ix86_expand_vector_move (TImode, operands);
1935 ;; This expands to what emit_move_complex would generate if we didn't
1936 ;; have a movti pattern. Having this avoids problems with reload on
1937 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1938 ;; to have around all the time.
1939 (define_expand "movcdi"
1940 [(set (match_operand:CDI 0 "nonimmediate_operand")
1941 (match_operand:CDI 1 "general_operand"))]
1944 if (push_operand (operands[0], CDImode))
1945 emit_move_complex_push (CDImode, operands[0], operands[1]);
1947 emit_move_complex_parts (operands[0], operands[1]);
1951 (define_expand "mov<mode>"
1952 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1953 (match_operand:SWI1248x 1 "general_operand"))]
1955 "ix86_expand_move (<MODE>mode, operands); DONE;")
1957 (define_insn "*mov<mode>_xor"
1958 [(set (match_operand:SWI48 0 "register_operand" "=r")
1959 (match_operand:SWI48 1 "const0_operand"))
1960 (clobber (reg:CC FLAGS_REG))]
1963 [(set_attr "type" "alu1")
1964 (set_attr "modrm_class" "op0")
1965 (set_attr "mode" "SI")
1966 (set_attr "length_immediate" "0")])
1968 (define_insn "*mov<mode>_or"
1969 [(set (match_operand:SWI48 0 "register_operand" "=r")
1970 (match_operand:SWI48 1 "const_int_operand"))
1971 (clobber (reg:CC FLAGS_REG))]
1973 && operands[1] == constm1_rtx"
1974 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1975 [(set_attr "type" "alu1")
1976 (set_attr "mode" "<MODE>")
1977 (set_attr "length_immediate" "1")])
1979 (define_insn "*movxi_internal_avx512f"
1980 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,m")
1981 (match_operand:XI 1 "vector_move_operand" "C ,vm,v"))]
1982 "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1984 switch (which_alternative)
1987 return standard_sse_constant_opcode (insn, operands[1]);
1990 if (misaligned_operand (operands[0], XImode)
1991 || misaligned_operand (operands[1], XImode))
1992 return "vmovdqu32\t{%1, %0|%0, %1}";
1994 return "vmovdqa32\t{%1, %0|%0, %1}";
1999 [(set_attr "type" "sselog1,ssemov,ssemov")
2000 (set_attr "prefix" "evex")
2001 (set_attr "mode" "XI")])
2003 (define_insn "*movoi_internal_avx"
2004 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,m")
2005 (match_operand:OI 1 "vector_move_operand" "C ,vm,v"))]
2006 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2008 switch (get_attr_type (insn))
2011 return standard_sse_constant_opcode (insn, operands[1]);
2014 if (misaligned_operand (operands[0], OImode)
2015 || misaligned_operand (operands[1], OImode))
2017 if (get_attr_mode (insn) == MODE_V8SF)
2018 return "vmovups\t{%1, %0|%0, %1}";
2019 else if (get_attr_mode (insn) == MODE_XI)
2020 return "vmovdqu32\t{%1, %0|%0, %1}";
2022 return "vmovdqu\t{%1, %0|%0, %1}";
2026 if (get_attr_mode (insn) == MODE_V8SF)
2027 return "vmovaps\t{%1, %0|%0, %1}";
2028 else if (get_attr_mode (insn) == MODE_XI)
2029 return "vmovdqa32\t{%1, %0|%0, %1}";
2031 return "vmovdqa\t{%1, %0|%0, %1}";
2038 [(set_attr "type" "sselog1,ssemov,ssemov")
2039 (set_attr "prefix" "vex")
2041 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2042 (match_operand 1 "ext_sse_reg_operand"))
2044 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2045 (const_string "V8SF")
2046 (and (eq_attr "alternative" "2")
2047 (match_test "TARGET_SSE_TYPELESS_STORES"))
2048 (const_string "V8SF")
2050 (const_string "OI")))])
2052 (define_insn "*movti_internal"
2053 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,m")
2054 (match_operand:TI 1 "general_operand" "riFo,re,C,vm,v"))]
2055 "(TARGET_64BIT || TARGET_SSE)
2056 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2058 switch (get_attr_type (insn))
2064 return standard_sse_constant_opcode (insn, operands[1]);
2067 /* TDmode values are passed as TImode on the stack. Moving them
2068 to stack may result in unaligned memory access. */
2069 if (misaligned_operand (operands[0], TImode)
2070 || misaligned_operand (operands[1], TImode))
2072 if (get_attr_mode (insn) == MODE_V4SF)
2073 return "%vmovups\t{%1, %0|%0, %1}";
2074 else if (get_attr_mode (insn) == MODE_XI)
2075 return "vmovdqu32\t{%1, %0|%0, %1}";
2077 return "%vmovdqu\t{%1, %0|%0, %1}";
2081 if (get_attr_mode (insn) == MODE_V4SF)
2082 return "%vmovaps\t{%1, %0|%0, %1}";
2083 else if (get_attr_mode (insn) == MODE_XI)
2084 return "vmovdqa32\t{%1, %0|%0, %1}";
2086 return "%vmovdqa\t{%1, %0|%0, %1}";
2093 [(set_attr "isa" "x64,x64,*,*,*")
2094 (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
2095 (set (attr "prefix")
2096 (if_then_else (eq_attr "type" "sselog1,ssemov")
2097 (const_string "maybe_vex")
2098 (const_string "orig")))
2100 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2101 (match_operand 1 "ext_sse_reg_operand"))
2103 (eq_attr "alternative" "0,1")
2105 (ior (not (match_test "TARGET_SSE2"))
2106 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2107 (const_string "V4SF")
2108 (and (eq_attr "alternative" "4")
2109 (match_test "TARGET_SSE_TYPELESS_STORES"))
2110 (const_string "V4SF")
2111 (match_test "TARGET_AVX")
2113 (match_test "optimize_function_for_size_p (cfun)")
2114 (const_string "V4SF")
2116 (const_string "TI")))])
2119 [(set (match_operand:TI 0 "nonimmediate_operand")
2120 (match_operand:TI 1 "general_operand"))]
2122 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2124 "ix86_split_long_move (operands); DONE;")
2126 (define_insn "*movdi_internal"
2127 [(set (match_operand:DI 0 "nonimmediate_operand"
2128 "=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")
2129 (match_operand:DI 1 "general_operand"
2130 "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"))]
2131 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2133 switch (get_attr_type (insn))
2136 return "kmovq\t{%1, %0|%0, %1}";
2142 return "pxor\t%0, %0";
2145 /* Handle broken assemblers that require movd instead of movq. */
2146 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2147 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2148 return "movd\t{%1, %0|%0, %1}";
2149 return "movq\t{%1, %0|%0, %1}";
2152 if (GENERAL_REG_P (operands[0]))
2153 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2155 return standard_sse_constant_opcode (insn, operands[1]);
2158 switch (get_attr_mode (insn))
2161 /* Handle broken assemblers that require movd instead of movq. */
2162 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2163 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2164 return "%vmovd\t{%1, %0|%0, %1}";
2165 return "%vmovq\t{%1, %0|%0, %1}";
2167 return "%vmovdqa\t{%1, %0|%0, %1}";
2169 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2172 gcc_assert (!TARGET_AVX);
2173 return "movlps\t{%1, %0|%0, %1}";
2175 return "%vmovaps\t{%1, %0|%0, %1}";
2182 if (SSE_REG_P (operands[0]))
2183 return "movq2dq\t{%1, %0|%0, %1}";
2185 return "movdq2q\t{%1, %0|%0, %1}";
2188 return "lea{q}\t{%E1, %0|%0, %E1}";
2191 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2192 if (get_attr_mode (insn) == MODE_SI)
2193 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2194 else if (which_alternative == 4)
2195 return "movabs{q}\t{%1, %0|%0, %1}";
2196 else if (ix86_use_lea_for_mov (insn, operands))
2197 return "lea{q}\t{%E1, %0|%0, %E1}";
2199 return "mov{q}\t{%1, %0|%0, %1}";
2206 (cond [(eq_attr "alternative" "0,1")
2207 (const_string "nox64")
2208 (eq_attr "alternative" "2,3,4,5,10,11,17,19,22,24")
2209 (const_string "x64")
2210 (eq_attr "alternative" "18")
2211 (const_string "x64_sse4")
2213 (const_string "*")))
2215 (cond [(eq_attr "alternative" "0,1")
2216 (const_string "multi")
2217 (eq_attr "alternative" "6")
2218 (const_string "mmx")
2219 (eq_attr "alternative" "7,8,9,10,11")
2220 (const_string "mmxmov")
2221 (eq_attr "alternative" "12,18")
2222 (const_string "sselog1")
2223 (eq_attr "alternative" "13,14,15,16,17,19")
2224 (const_string "ssemov")
2225 (eq_attr "alternative" "20,21")
2226 (const_string "ssecvt")
2227 (eq_attr "alternative" "22,23,24,25")
2228 (const_string "mskmov")
2229 (and (match_operand 0 "register_operand")
2230 (match_operand 1 "pic_32bit_operand"))
2231 (const_string "lea")
2233 (const_string "imov")))
2236 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2238 (const_string "*")))
2239 (set (attr "length_immediate")
2240 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2242 (eq_attr "alternative" "18")
2245 (const_string "*")))
2246 (set (attr "prefix_rex")
2247 (if_then_else (eq_attr "alternative" "10,11,17,18,19")
2249 (const_string "*")))
2250 (set (attr "prefix_extra")
2251 (if_then_else (eq_attr "alternative" "18")
2253 (const_string "*")))
2254 (set (attr "prefix")
2255 (if_then_else (eq_attr "type" "sselog1,ssemov")
2256 (const_string "maybe_vex")
2257 (const_string "orig")))
2258 (set (attr "prefix_data16")
2259 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2261 (const_string "*")))
2263 (cond [(eq_attr "alternative" "2")
2265 (eq_attr "alternative" "12,13")
2266 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2267 (match_operand 1 "ext_sse_reg_operand"))
2269 (ior (not (match_test "TARGET_SSE2"))
2270 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2271 (const_string "V4SF")
2272 (match_test "TARGET_AVX")
2274 (match_test "optimize_function_for_size_p (cfun)")
2275 (const_string "V4SF")
2277 (const_string "TI"))
2279 (and (eq_attr "alternative" "14,15,16")
2280 (not (match_test "TARGET_SSE2")))
2281 (const_string "V2SF")
2282 (eq_attr "alternative" "18")
2285 (const_string "DI")))
2286 (set (attr "enabled")
2287 (cond [(eq_attr "alternative" "15")
2289 (match_test "TARGET_STV && TARGET_SSE2")
2290 (symbol_ref "false")
2292 (eq_attr "alternative" "16")
2294 (match_test "TARGET_STV && TARGET_SSE2")
2296 (symbol_ref "false"))
2298 (const_string "*")))])
2301 [(set (match_operand:DI 0 "nonimmediate_operand")
2302 (match_operand:DI 1 "general_operand"))]
2303 "!TARGET_64BIT && reload_completed
2304 && !(MMX_REG_P (operands[0])
2305 || SSE_REG_P (operands[0])
2306 || MASK_REG_P (operands[0]))
2307 && !(MMX_REG_P (operands[1])
2308 || SSE_REG_P (operands[1])
2309 || MASK_REG_P (operands[1]))"
2311 "ix86_split_long_move (operands); DONE;")
2313 (define_insn "*movsi_internal"
2314 [(set (match_operand:SI 0 "nonimmediate_operand"
2315 "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k ,*rm")
2316 (match_operand:SI 1 "general_operand"
2317 "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r ,*krm,*k"))]
2318 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2320 switch (get_attr_type (insn))
2323 if (GENERAL_REG_P (operands[0]))
2324 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2326 return standard_sse_constant_opcode (insn, operands[1]);
2329 return "kmovd\t{%1, %0|%0, %1}";
2332 switch (get_attr_mode (insn))
2335 return "%vmovd\t{%1, %0|%0, %1}";
2337 return "%vmovdqa\t{%1, %0|%0, %1}";
2339 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2342 return "%vmovaps\t{%1, %0|%0, %1}";
2345 gcc_assert (!TARGET_AVX);
2346 return "movss\t{%1, %0|%0, %1}";
2353 return "pxor\t%0, %0";
2356 switch (get_attr_mode (insn))
2359 return "movq\t{%1, %0|%0, %1}";
2361 return "movd\t{%1, %0|%0, %1}";
2368 return "lea{l}\t{%E1, %0|%0, %E1}";
2371 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2372 if (ix86_use_lea_for_mov (insn, operands))
2373 return "lea{l}\t{%E1, %0|%0, %E1}";
2375 return "mov{l}\t{%1, %0|%0, %1}";
2382 (if_then_else (eq_attr "alternative" "11")
2383 (const_string "sse4")
2384 (const_string "*")))
2386 (cond [(eq_attr "alternative" "2")
2387 (const_string "mmx")
2388 (eq_attr "alternative" "3,4,5")
2389 (const_string "mmxmov")
2390 (eq_attr "alternative" "6,11")
2391 (const_string "sselog1")
2392 (eq_attr "alternative" "7,8,9,10,12")
2393 (const_string "ssemov")
2394 (eq_attr "alternative" "13,14")
2395 (const_string "mskmov")
2396 (and (match_operand 0 "register_operand")
2397 (match_operand 1 "pic_32bit_operand"))
2398 (const_string "lea")
2400 (const_string "imov")))
2401 (set (attr "length_immediate")
2402 (if_then_else (eq_attr "alternative" "11")
2404 (const_string "*")))
2405 (set (attr "prefix_extra")
2406 (if_then_else (eq_attr "alternative" "11")
2408 (const_string "*")))
2409 (set (attr "prefix")
2410 (if_then_else (eq_attr "type" "sselog1,ssemov")
2411 (const_string "maybe_vex")
2412 (const_string "orig")))
2413 (set (attr "prefix_data16")
2414 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2416 (const_string "*")))
2418 (cond [(eq_attr "alternative" "2,3")
2420 (eq_attr "alternative" "6,7")
2421 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2422 (match_operand 1 "ext_sse_reg_operand"))
2424 (ior (not (match_test "TARGET_SSE2"))
2425 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2426 (const_string "V4SF")
2427 (match_test "TARGET_AVX")
2429 (match_test "optimize_function_for_size_p (cfun)")
2430 (const_string "V4SF")
2432 (const_string "TI"))
2434 (and (eq_attr "alternative" "8,9")
2435 (not (match_test "TARGET_SSE2")))
2437 (eq_attr "alternative" "11")
2440 (const_string "SI")))])
2442 (define_insn "kmovw"
2443 [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2445 [(match_operand:HI 1 "nonimmediate_operand" "r,km")]
2447 "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2449 kmovw\t{%k1, %0|%0, %k1}
2450 kmovw\t{%1, %0|%0, %1}";
2451 [(set_attr "mode" "HI")
2452 (set_attr "type" "mskmov")
2453 (set_attr "prefix" "vex")])
2456 (define_insn "*movhi_internal"
2457 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k, r,m")
2458 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,r,km,k,k"))]
2459 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2461 switch (get_attr_type (insn))
2464 /* movzwl is faster than movw on p2 due to partial word stalls,
2465 though not as fast as an aligned movl. */
2466 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2469 switch (which_alternative)
2471 case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2472 case 5: /* FALLTHRU */
2473 case 7: return "kmovw\t{%1, %0|%0, %1}";
2474 case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2475 default: gcc_unreachable ();
2479 if (get_attr_mode (insn) == MODE_SI)
2480 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2482 return "mov{w}\t{%1, %0|%0, %1}";
2486 (cond [(eq_attr "alternative" "4,5,6,7")
2487 (const_string "mskmov")
2488 (match_test "optimize_function_for_size_p (cfun)")
2489 (const_string "imov")
2490 (and (eq_attr "alternative" "0")
2491 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2492 (not (match_test "TARGET_HIMODE_MATH"))))
2493 (const_string "imov")
2494 (and (eq_attr "alternative" "1,2")
2495 (match_operand:HI 1 "aligned_operand"))
2496 (const_string "imov")
2497 (and (match_test "TARGET_MOVX")
2498 (eq_attr "alternative" "0,2"))
2499 (const_string "imovx")
2501 (const_string "imov")))
2502 (set (attr "prefix")
2503 (if_then_else (eq_attr "alternative" "4,5,6,7")
2504 (const_string "vex")
2505 (const_string "orig")))
2507 (cond [(eq_attr "type" "imovx")
2509 (and (eq_attr "alternative" "1,2")
2510 (match_operand:HI 1 "aligned_operand"))
2512 (and (eq_attr "alternative" "0")
2513 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2514 (not (match_test "TARGET_HIMODE_MATH"))))
2517 (const_string "HI")))])
2519 ;; Situation is quite tricky about when to choose full sized (SImode) move
2520 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2521 ;; partial register dependency machines (such as AMD Athlon), where QImode
2522 ;; moves issue extra dependency and for partial register stalls machines
2523 ;; that don't use QImode patterns (and QImode move cause stall on the next
2526 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2527 ;; register stall machines with, where we use QImode instructions, since
2528 ;; partial register stall can be caused there. Then we use movzx.
2530 (define_insn "*movqi_internal"
2531 [(set (match_operand:QI 0 "nonimmediate_operand"
2532 "=q,q ,q ,r,r ,?r,m ,k,k,r ,m,k")
2533 (match_operand:QI 1 "general_operand"
2534 "q ,qn,qm,q,rn,qm,qn,r ,k,k,k,m"))]
2535 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2537 switch (get_attr_type (insn))
2540 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2541 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2544 switch (which_alternative)
2546 case 7: return TARGET_AVX512DQ ? "kmovb\t{%k1, %0|%0, %k1}"
2547 : "kmovw\t{%k1, %0|%0, %k1}";
2548 case 8: return TARGET_AVX512DQ ? "kmovb\t{%1, %0|%0, %1}"
2549 : "kmovw\t{%1, %0|%0, %1}";
2550 case 9: return TARGET_AVX512DQ ? "kmovb\t{%1, %k0|%k0, %1}"
2551 : "kmovw\t{%1, %k0|%k0, %1}";
2554 gcc_assert (TARGET_AVX512DQ);
2555 return "kmovb\t{%1, %0|%0, %1}";
2556 default: gcc_unreachable ();
2560 if (get_attr_mode (insn) == MODE_SI)
2561 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2563 return "mov{b}\t{%1, %0|%0, %1}";
2566 [(set_attr "isa" "*,*,*,*,*,*,*,*,*,*,avx512dq,avx512dq")
2568 (cond [(eq_attr "alternative" "7,8,9,10,11")
2569 (const_string "mskmov")
2570 (and (eq_attr "alternative" "5")
2571 (not (match_operand:QI 1 "aligned_operand")))
2572 (const_string "imovx")
2573 (match_test "optimize_function_for_size_p (cfun)")
2574 (const_string "imov")
2575 (and (eq_attr "alternative" "3")
2576 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2577 (not (match_test "TARGET_QIMODE_MATH"))))
2578 (const_string "imov")
2579 (eq_attr "alternative" "3,5")
2580 (const_string "imovx")
2581 (and (match_test "TARGET_MOVX")
2582 (eq_attr "alternative" "2"))
2583 (const_string "imovx")
2585 (const_string "imov")))
2586 (set (attr "prefix")
2587 (if_then_else (eq_attr "alternative" "7,8,9")
2588 (const_string "vex")
2589 (const_string "orig")))
2591 (cond [(eq_attr "alternative" "3,4,5")
2593 (eq_attr "alternative" "6")
2595 (eq_attr "type" "imovx")
2597 (and (eq_attr "type" "imov")
2598 (and (eq_attr "alternative" "0,1")
2599 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2600 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2601 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2603 ;; Avoid partial register stalls when not using QImode arithmetic
2604 (and (eq_attr "type" "imov")
2605 (and (eq_attr "alternative" "0,1")
2606 (and (match_test "TARGET_PARTIAL_REG_STALL")
2607 (not (match_test "TARGET_QIMODE_MATH")))))
2610 (const_string "QI")))])
2612 ;; Stores and loads of ax to arbitrary constant address.
2613 ;; We fake an second form of instruction to force reload to load address
2614 ;; into register when rax is not available
2615 (define_insn "*movabs<mode>_1"
2616 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2617 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2618 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2620 /* Recover the full memory rtx. */
2621 operands[0] = SET_DEST (PATTERN (insn));
2622 switch (which_alternative)
2625 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2627 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2632 [(set_attr "type" "imov")
2633 (set_attr "modrm" "0,*")
2634 (set_attr "length_address" "8,0")
2635 (set_attr "length_immediate" "0,*")
2636 (set_attr "memory" "store")
2637 (set_attr "mode" "<MODE>")])
2639 (define_insn "*movabs<mode>_2"
2640 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2641 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2642 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2644 /* Recover the full memory rtx. */
2645 operands[1] = SET_SRC (PATTERN (insn));
2646 switch (which_alternative)
2649 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2651 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2656 [(set_attr "type" "imov")
2657 (set_attr "modrm" "0,*")
2658 (set_attr "length_address" "8,0")
2659 (set_attr "length_immediate" "0")
2660 (set_attr "memory" "load")
2661 (set_attr "mode" "<MODE>")])
2663 (define_insn "*swap<mode>"
2664 [(set (match_operand:SWI48 0 "register_operand" "+r")
2665 (match_operand:SWI48 1 "register_operand" "+r"))
2669 "xchg{<imodesuffix>}\t%1, %0"
2670 [(set_attr "type" "imov")
2671 (set_attr "mode" "<MODE>")
2672 (set_attr "pent_pair" "np")
2673 (set_attr "athlon_decode" "vector")
2674 (set_attr "amdfam10_decode" "double")
2675 (set_attr "bdver1_decode" "double")])
2677 (define_insn "*swap<mode>_1"
2678 [(set (match_operand:SWI12 0 "register_operand" "+r")
2679 (match_operand:SWI12 1 "register_operand" "+r"))
2682 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2684 [(set_attr "type" "imov")
2685 (set_attr "mode" "SI")
2686 (set_attr "pent_pair" "np")
2687 (set_attr "athlon_decode" "vector")
2688 (set_attr "amdfam10_decode" "double")
2689 (set_attr "bdver1_decode" "double")])
2691 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2692 ;; is disabled for AMDFAM10
2693 (define_insn "*swap<mode>_2"
2694 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2695 (match_operand:SWI12 1 "register_operand" "+<r>"))
2698 "TARGET_PARTIAL_REG_STALL"
2699 "xchg{<imodesuffix>}\t%1, %0"
2700 [(set_attr "type" "imov")
2701 (set_attr "mode" "<MODE>")
2702 (set_attr "pent_pair" "np")
2703 (set_attr "athlon_decode" "vector")])
2705 (define_expand "movstrict<mode>"
2706 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2707 (match_operand:SWI12 1 "general_operand"))]
2710 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2712 if (SUBREG_P (operands[0])
2713 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2715 /* Don't generate memory->memory moves, go through a register */
2716 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2717 operands[1] = force_reg (<MODE>mode, operands[1]);
2720 (define_insn "*movstrict<mode>_1"
2721 [(set (strict_low_part
2722 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2723 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2724 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2725 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2726 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2727 [(set_attr "type" "imov")
2728 (set_attr "mode" "<MODE>")])
2730 (define_insn "*movstrict<mode>_xor"
2731 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2732 (match_operand:SWI12 1 "const0_operand"))
2733 (clobber (reg:CC FLAGS_REG))]
2735 "xor{<imodesuffix>}\t%0, %0"
2736 [(set_attr "type" "alu1")
2737 (set_attr "modrm_class" "op0")
2738 (set_attr "mode" "<MODE>")
2739 (set_attr "length_immediate" "0")])
2741 (define_expand "extv<mode>"
2742 [(set (match_operand:SWI24 0 "register_operand")
2743 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2744 (match_operand:SI 2 "const_int_operand")
2745 (match_operand:SI 3 "const_int_operand")))]
2748 /* Handle extractions from %ah et al. */
2749 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2752 if (! ext_register_operand (operands[1], VOIDmode))
2753 operands[1] = copy_to_reg (operands[1]);
2756 (define_insn "*extv<mode>"
2757 [(set (match_operand:SWI24 0 "register_operand" "=R")
2758 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2762 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2763 [(set_attr "type" "imovx")
2764 (set_attr "mode" "SI")])
2766 (define_insn "*extvqi"
2767 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2768 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2773 switch (get_attr_type (insn))
2776 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2778 return "mov{b}\t{%h1, %0|%0, %h1}";
2781 [(set_attr "isa" "*,*,nox64")
2783 (if_then_else (and (match_operand:QI 0 "register_operand")
2784 (ior (not (match_operand:QI 0 "QIreg_operand"))
2785 (match_test "TARGET_MOVX")))
2786 (const_string "imovx")
2787 (const_string "imov")))
2789 (if_then_else (eq_attr "type" "imovx")
2791 (const_string "QI")))])
2793 (define_expand "extzv<mode>"
2794 [(set (match_operand:SWI248 0 "register_operand")
2795 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2796 (match_operand:SI 2 "const_int_operand")
2797 (match_operand:SI 3 "const_int_operand")))]
2800 if (ix86_expand_pextr (operands))
2803 /* Handle extractions from %ah et al. */
2804 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2807 if (! ext_register_operand (operands[1], VOIDmode))
2808 operands[1] = copy_to_reg (operands[1]);
2811 (define_insn "*extzv<mode>"
2812 [(set (match_operand:SWI248 0 "register_operand" "=R")
2813 (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2817 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2818 [(set_attr "type" "imovx")
2819 (set_attr "mode" "SI")])
2821 (define_insn "*extzvqi"
2822 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2824 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2829 switch (get_attr_type (insn))
2832 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2834 return "mov{b}\t{%h1, %0|%0, %h1}";
2837 [(set_attr "isa" "*,*,nox64")
2839 (if_then_else (and (match_operand:QI 0 "register_operand")
2840 (ior (not (match_operand:QI 0 "QIreg_operand"))
2841 (match_test "TARGET_MOVX")))
2842 (const_string "imovx")
2843 (const_string "imov")))
2845 (if_then_else (eq_attr "type" "imovx")
2847 (const_string "QI")))])
2849 (define_expand "insv<mode>"
2850 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
2851 (match_operand:SI 1 "const_int_operand")
2852 (match_operand:SI 2 "const_int_operand"))
2853 (match_operand:SWI248 3 "register_operand"))]
2858 if (ix86_expand_pinsr (operands))
2861 /* Handle insertions to %ah et al. */
2862 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
2867 if (!ext_register_operand (dst, VOIDmode))
2868 dst = copy_to_reg (dst);
2870 emit_insn (gen_insv<mode>_1 (dst, operands[3]));
2872 /* Fix up the destination if needed. */
2873 if (dst != operands[0])
2874 emit_move_insn (operands[0], dst);
2879 (define_insn "insv<mode>_1"
2880 [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
2883 (match_operand:SWI248 1 "general_x64nomem_operand" "Qn,m"))]
2886 if (CONST_INT_P (operands[1]))
2887 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
2888 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2890 [(set_attr "isa" "*,nox64")
2891 (set_attr "type" "imov")
2892 (set_attr "mode" "QI")])
2894 (define_insn "*insvqi"
2895 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2898 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2901 "mov{b}\t{%h1, %h0|%h0, %h1}"
2902 [(set_attr "type" "imov")
2903 (set_attr "mode" "QI")])
2905 ;; Floating point push instructions.
2907 (define_insn "*pushtf"
2908 [(set (match_operand:TF 0 "push_operand" "=<,<")
2909 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2910 "TARGET_64BIT || TARGET_SSE"
2912 /* This insn should be already split before reg-stack. */
2915 [(set_attr "isa" "*,x64")
2916 (set_attr "type" "multi")
2917 (set_attr "unit" "sse,*")
2918 (set_attr "mode" "TF,DI")])
2920 ;; %%% Kill this when call knows how to work this out.
2922 [(set (match_operand:TF 0 "push_operand")
2923 (match_operand:TF 1 "sse_reg_operand"))]
2924 "TARGET_SSE && reload_completed"
2925 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2926 (set (match_dup 0) (match_dup 1))]
2928 /* Preserve memory attributes. */
2929 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2932 (define_insn "*pushxf"
2933 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<")
2934 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF"))]
2937 /* This insn should be already split before reg-stack. */
2940 [(set_attr "type" "multi")
2941 (set_attr "unit" "i387,*,*,*")
2943 (cond [(eq_attr "alternative" "1,2,3")
2944 (if_then_else (match_test "TARGET_64BIT")
2946 (const_string "SI"))
2948 (const_string "XF")))
2949 (set (attr "preferred_for_size")
2950 (cond [(eq_attr "alternative" "1")
2951 (symbol_ref "false")]
2952 (symbol_ref "true")))])
2954 ;; %%% Kill this when call knows how to work this out.
2956 [(set (match_operand:XF 0 "push_operand")
2957 (match_operand:XF 1 "fp_register_operand"))]
2959 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2960 (set (match_dup 0) (match_dup 1))]
2962 operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2963 /* Preserve memory attributes. */
2964 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2967 (define_insn "*pushdf"
2968 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
2969 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmF,x"))]
2972 /* This insn should be already split before reg-stack. */
2975 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
2976 (set_attr "type" "multi")
2977 (set_attr "unit" "i387,*,*,*,*,sse")
2978 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
2979 (set (attr "preferred_for_size")
2980 (cond [(eq_attr "alternative" "1")
2981 (symbol_ref "false")]
2982 (symbol_ref "true")))
2983 (set (attr "preferred_for_speed")
2984 (cond [(eq_attr "alternative" "1")
2985 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
2986 (symbol_ref "true")))])
2988 ;; %%% Kill this when call knows how to work this out.
2990 [(set (match_operand:DF 0 "push_operand")
2991 (match_operand:DF 1 "any_fp_register_operand"))]
2993 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2994 (set (match_dup 0) (match_dup 1))]
2996 /* Preserve memory attributes. */
2997 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3000 (define_insn "*pushsf_rex64"
3001 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3002 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3005 /* Anything else should be already split before reg-stack. */
3006 gcc_assert (which_alternative == 1);
3007 return "push{q}\t%q1";
3009 [(set_attr "type" "multi,push,multi")
3010 (set_attr "unit" "i387,*,*")
3011 (set_attr "mode" "SF,DI,SF")])
3013 (define_insn "*pushsf"
3014 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3015 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3018 /* Anything else should be already split before reg-stack. */
3019 gcc_assert (which_alternative == 1);
3020 return "push{l}\t%1";
3022 [(set_attr "type" "multi,push,multi")
3023 (set_attr "unit" "i387,*,*")
3024 (set_attr "mode" "SF,SI,SF")])
3026 ;; %%% Kill this when call knows how to work this out.
3028 [(set (match_operand:SF 0 "push_operand")
3029 (match_operand:SF 1 "any_fp_register_operand"))]
3031 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3032 (set (match_dup 0) (match_dup 1))]
3034 rtx op = XEXP (operands[0], 0);
3035 if (GET_CODE (op) == PRE_DEC)
3037 gcc_assert (!TARGET_64BIT);
3042 op = XEXP (XEXP (op, 1), 1);
3043 gcc_assert (CONST_INT_P (op));
3046 /* Preserve memory attributes. */
3047 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3051 [(set (match_operand:SF 0 "push_operand")
3052 (match_operand:SF 1 "memory_operand"))]
3054 [(set (match_dup 0) (match_dup 2))]
3056 operands[2] = find_constant_src (curr_insn);
3058 if (operands[2] == NULL_RTX)
3063 [(set (match_operand 0 "push_operand")
3064 (match_operand 1 "general_operand"))]
3066 && (GET_MODE (operands[0]) == TFmode
3067 || GET_MODE (operands[0]) == XFmode
3068 || GET_MODE (operands[0]) == DFmode)
3069 && !ANY_FP_REG_P (operands[1])"
3071 "ix86_split_long_move (operands); DONE;")
3073 ;; Floating point move instructions.
3075 (define_expand "movtf"
3076 [(set (match_operand:TF 0 "nonimmediate_operand")
3077 (match_operand:TF 1 "nonimmediate_operand"))]
3078 "TARGET_64BIT || TARGET_SSE"
3079 "ix86_expand_move (TFmode, operands); DONE;")
3081 (define_expand "mov<mode>"
3082 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3083 (match_operand:X87MODEF 1 "general_operand"))]
3085 "ix86_expand_move (<MODE>mode, operands); DONE;")
3087 (define_insn "*movtf_internal"
3088 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
3089 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
3090 "(TARGET_64BIT || TARGET_SSE)
3091 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3092 && (!can_create_pseudo_p ()
3093 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3094 || !CONST_DOUBLE_P (operands[1])
3095 || (optimize_function_for_size_p (cfun)
3096 && standard_sse_constant_p (operands[1])
3097 && !memory_operand (operands[0], TFmode))
3098 || (!TARGET_MEMORY_MISMATCH_STALL
3099 && memory_operand (operands[0], TFmode)))"
3101 switch (get_attr_type (insn))
3104 return standard_sse_constant_opcode (insn, operands[1]);
3107 /* Handle misaligned load/store since we
3108 don't have movmisaligntf pattern. */
3109 if (misaligned_operand (operands[0], TFmode)
3110 || misaligned_operand (operands[1], TFmode))
3112 if (get_attr_mode (insn) == MODE_V4SF)
3113 return "%vmovups\t{%1, %0|%0, %1}";
3115 return "%vmovdqu\t{%1, %0|%0, %1}";
3119 if (get_attr_mode (insn) == MODE_V4SF)
3120 return "%vmovaps\t{%1, %0|%0, %1}";
3122 return "%vmovdqa\t{%1, %0|%0, %1}";
3132 [(set_attr "isa" "*,*,*,x64,x64")
3133 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3134 (set (attr "prefix")
3135 (if_then_else (eq_attr "type" "sselog1,ssemov")
3136 (const_string "maybe_vex")
3137 (const_string "orig")))
3139 (cond [(eq_attr "alternative" "3,4")
3141 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3142 (const_string "V4SF")
3143 (and (eq_attr "alternative" "2")
3144 (match_test "TARGET_SSE_TYPELESS_STORES"))
3145 (const_string "V4SF")
3146 (match_test "TARGET_AVX")
3148 (ior (not (match_test "TARGET_SSE2"))
3149 (match_test "optimize_function_for_size_p (cfun)"))
3150 (const_string "V4SF")
3152 (const_string "TI")))])
3155 [(set (match_operand:TF 0 "nonimmediate_operand")
3156 (match_operand:TF 1 "general_operand"))]
3158 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3160 "ix86_split_long_move (operands); DONE;")
3162 ;; Possible store forwarding (partial memory) stall
3163 ;; in alternatives 4, 6, 7 and 8.
3164 (define_insn "*movxf_internal"
3165 [(set (match_operand:XF 0 "nonimmediate_operand"
3166 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o")
3167 (match_operand:XF 1 "general_operand"
3168 "fm,f,G,roF,r , *roF,*r,F ,C,roF,rF"))]
3169 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3170 && (!can_create_pseudo_p ()
3171 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3172 || !CONST_DOUBLE_P (operands[1])
3173 || (optimize_function_for_size_p (cfun)
3174 && standard_80387_constant_p (operands[1]) > 0
3175 && !memory_operand (operands[0], XFmode))
3176 || (!TARGET_MEMORY_MISMATCH_STALL
3177 && memory_operand (operands[0], XFmode))
3178 || !TARGET_HARD_XF_REGS)"
3180 switch (get_attr_type (insn))
3183 if (which_alternative == 2)
3184 return standard_80387_constant_opcode (operands[1]);
3185 return output_387_reg_move (insn, operands);
3195 (cond [(eq_attr "alternative" "7")
3196 (const_string "nox64")
3197 (eq_attr "alternative" "8")
3198 (const_string "x64")
3200 (const_string "*")))
3202 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10")
3203 (const_string "multi")
3205 (const_string "fmov")))
3207 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10")
3208 (if_then_else (match_test "TARGET_64BIT")
3210 (const_string "SI"))
3212 (const_string "XF")))
3213 (set (attr "preferred_for_size")
3214 (cond [(eq_attr "alternative" "3,4")
3215 (symbol_ref "false")]
3216 (symbol_ref "true")))
3217 (set (attr "enabled")
3218 (cond [(eq_attr "alternative" "9,10")
3220 (match_test "TARGET_HARD_XF_REGS")
3221 (symbol_ref "false")
3223 (not (match_test "TARGET_HARD_XF_REGS"))
3224 (symbol_ref "false")
3226 (const_string "*")))])
3229 [(set (match_operand:XF 0 "nonimmediate_operand")
3230 (match_operand:XF 1 "general_operand"))]
3232 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3234 "ix86_split_long_move (operands); DONE;")
3236 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3237 (define_insn "*movdf_internal"
3238 [(set (match_operand:DF 0 "nonimmediate_operand"
3239 "=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")
3240 (match_operand:DF 1 "general_operand"
3241 "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"))]
3242 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3243 && (!can_create_pseudo_p ()
3244 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3245 || !CONST_DOUBLE_P (operands[1])
3246 || (optimize_function_for_size_p (cfun)
3247 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3248 && standard_80387_constant_p (operands[1]) > 0)
3249 || (TARGET_SSE2 && TARGET_SSE_MATH
3250 && standard_sse_constant_p (operands[1])))
3251 && !memory_operand (operands[0], DFmode))
3252 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3253 && memory_operand (operands[0], DFmode))
3254 || !TARGET_HARD_DF_REGS)"
3256 switch (get_attr_type (insn))
3259 if (which_alternative == 2)
3260 return standard_80387_constant_opcode (operands[1]);
3261 return output_387_reg_move (insn, operands);
3267 if (get_attr_mode (insn) == MODE_SI)
3268 return "mov{l}\t{%1, %k0|%k0, %1}";
3269 else if (which_alternative == 11)
3270 return "movabs{q}\t{%1, %0|%0, %1}";
3272 return "mov{q}\t{%1, %0|%0, %1}";
3275 return standard_sse_constant_opcode (insn, operands[1]);
3278 switch (get_attr_mode (insn))
3281 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3282 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3283 return "%vmovsd\t{%1, %0|%0, %1}";
3286 return "%vmovaps\t{%1, %0|%0, %1}";
3288 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3290 return "%vmovapd\t{%1, %0|%0, %1}";
3293 gcc_assert (!TARGET_AVX);
3294 return "movlps\t{%1, %0|%0, %1}";
3296 gcc_assert (!TARGET_AVX);
3297 return "movlpd\t{%1, %0|%0, %1}";
3300 /* Handle broken assemblers that require movd instead of movq. */
3301 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3302 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3303 return "%vmovd\t{%1, %0|%0, %1}";
3304 return "%vmovq\t{%1, %0|%0, %1}";
3315 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3316 (const_string "nox64")
3317 (eq_attr "alternative" "8,9,10,11,20,21,24,25")
3318 (const_string "x64")
3319 (eq_attr "alternative" "12,13,14,15")
3320 (const_string "sse2")
3322 (const_string "*")))
3324 (cond [(eq_attr "alternative" "0,1,2")
3325 (const_string "fmov")
3326 (eq_attr "alternative" "3,4,5,6,7,22,23")
3327 (const_string "multi")
3328 (eq_attr "alternative" "8,9,10,11,24,25")
3329 (const_string "imov")
3330 (eq_attr "alternative" "12,16")
3331 (const_string "sselog1")
3333 (const_string "ssemov")))
3335 (if_then_else (eq_attr "alternative" "11")
3337 (const_string "*")))
3338 (set (attr "length_immediate")
3339 (if_then_else (eq_attr "alternative" "11")
3341 (const_string "*")))
3342 (set (attr "prefix")
3343 (if_then_else (eq_attr "type" "sselog1,ssemov")
3344 (const_string "maybe_vex")
3345 (const_string "orig")))
3346 (set (attr "prefix_data16")
3348 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3349 (eq_attr "mode" "V1DF"))
3351 (const_string "*")))
3353 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3355 (eq_attr "alternative" "8,9,11,20,21,24,25")
3358 /* xorps is one byte shorter for non-AVX targets. */
3359 (eq_attr "alternative" "12,16")
3360 (cond [(not (match_test "TARGET_SSE2"))
3361 (const_string "V4SF")
3362 (match_test "TARGET_AVX512F")
3364 (match_test "TARGET_AVX")
3365 (const_string "V2DF")
3366 (match_test "optimize_function_for_size_p (cfun)")
3367 (const_string "V4SF")
3368 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3371 (const_string "V2DF"))
3373 /* For architectures resolving dependencies on
3374 whole SSE registers use movapd to break dependency
3375 chains, otherwise use short move to avoid extra work. */
3377 /* movaps is one byte shorter for non-AVX targets. */
3378 (eq_attr "alternative" "13,17")
3379 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3380 (match_operand 1 "ext_sse_reg_operand"))
3381 (const_string "V8DF")
3382 (ior (not (match_test "TARGET_SSE2"))
3383 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3384 (const_string "V4SF")
3385 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3386 (const_string "V2DF")
3387 (match_test "TARGET_AVX")
3389 (match_test "optimize_function_for_size_p (cfun)")
3390 (const_string "V4SF")
3392 (const_string "DF"))
3394 /* For architectures resolving dependencies on register
3395 parts we may avoid extra work to zero out upper part
3397 (eq_attr "alternative" "14,18")
3398 (cond [(not (match_test "TARGET_SSE2"))
3399 (const_string "V2SF")
3400 (match_test "TARGET_AVX")
3402 (match_test "TARGET_SSE_SPLIT_REGS")
3403 (const_string "V1DF")
3405 (const_string "DF"))
3407 (and (eq_attr "alternative" "15,19")
3408 (not (match_test "TARGET_SSE2")))
3409 (const_string "V2SF")
3411 (const_string "DF")))
3412 (set (attr "preferred_for_size")
3413 (cond [(eq_attr "alternative" "3,4")
3414 (symbol_ref "false")]
3415 (symbol_ref "true")))
3416 (set (attr "preferred_for_speed")
3417 (cond [(eq_attr "alternative" "3,4")
3418 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3419 (symbol_ref "true")))
3420 (set (attr "enabled")
3421 (cond [(eq_attr "alternative" "22,23,24,25")
3423 (match_test "TARGET_HARD_DF_REGS")
3424 (symbol_ref "false")
3426 (not (match_test "TARGET_HARD_DF_REGS"))
3427 (symbol_ref "false")
3429 (const_string "*")))])
3432 [(set (match_operand:DF 0 "nonimmediate_operand")
3433 (match_operand:DF 1 "general_operand"))]
3434 "!TARGET_64BIT && reload_completed
3435 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3437 "ix86_split_long_move (operands); DONE;")
3439 (define_insn "*movsf_internal"
3440 [(set (match_operand:SF 0 "nonimmediate_operand"
3441 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym,r ,m")
3442 (match_operand:SF 1 "general_operand"
3443 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r ,rmF,rF"))]
3444 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3445 && (!can_create_pseudo_p ()
3446 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3447 || !CONST_DOUBLE_P (operands[1])
3448 || (optimize_function_for_size_p (cfun)
3449 && ((!TARGET_SSE_MATH
3450 && standard_80387_constant_p (operands[1]) > 0)
3452 && standard_sse_constant_p (operands[1]))))
3453 || memory_operand (operands[0], SFmode)
3454 || !TARGET_HARD_SF_REGS)"
3456 switch (get_attr_type (insn))
3459 if (which_alternative == 2)
3460 return standard_80387_constant_opcode (operands[1]);
3461 return output_387_reg_move (insn, operands);
3464 return "mov{l}\t{%1, %0|%0, %1}";
3467 return standard_sse_constant_opcode (insn, operands[1]);
3470 switch (get_attr_mode (insn))
3473 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3474 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3475 return "%vmovss\t{%1, %0|%0, %1}";
3478 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3480 return "%vmovaps\t{%1, %0|%0, %1}";
3483 return "%vmovd\t{%1, %0|%0, %1}";
3490 switch (get_attr_mode (insn))
3493 return "movq\t{%1, %0|%0, %1}";
3495 return "movd\t{%1, %0|%0, %1}";
3506 (cond [(eq_attr "alternative" "0,1,2")
3507 (const_string "fmov")
3508 (eq_attr "alternative" "3,4,16,17")
3509 (const_string "imov")
3510 (eq_attr "alternative" "5")
3511 (const_string "sselog1")
3512 (eq_attr "alternative" "11,12,13,14,15")
3513 (const_string "mmxmov")
3515 (const_string "ssemov")))
3516 (set (attr "prefix")
3517 (if_then_else (eq_attr "type" "sselog1,ssemov")
3518 (const_string "maybe_vex")
3519 (const_string "orig")))
3520 (set (attr "prefix_data16")
3521 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3523 (const_string "*")))
3525 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3527 (eq_attr "alternative" "11")
3529 (eq_attr "alternative" "5")
3530 (cond [(not (match_test "TARGET_SSE2"))
3531 (const_string "V4SF")
3532 (match_test "TARGET_AVX512F")
3533 (const_string "V16SF")
3534 (match_test "TARGET_AVX")
3535 (const_string "V4SF")
3536 (match_test "optimize_function_for_size_p (cfun)")
3537 (const_string "V4SF")
3538 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3541 (const_string "V4SF"))
3543 /* For architectures resolving dependencies on
3544 whole SSE registers use APS move to break dependency
3545 chains, otherwise use short move to avoid extra work.
3547 Do the same for architectures resolving dependencies on
3548 the parts. While in DF mode it is better to always handle
3549 just register parts, the SF mode is different due to lack
3550 of instructions to load just part of the register. It is
3551 better to maintain the whole registers in single format
3552 to avoid problems on using packed logical operations. */
3553 (eq_attr "alternative" "6")
3554 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3555 (match_operand 1 "ext_sse_reg_operand"))
3556 (const_string "V16SF")
3557 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3558 (match_test "TARGET_SSE_SPLIT_REGS"))
3559 (const_string "V4SF")
3561 (const_string "SF"))
3563 (const_string "SF")))
3564 (set (attr "enabled")
3565 (cond [(eq_attr "alternative" "16,17")
3567 (match_test "TARGET_HARD_SF_REGS")
3568 (symbol_ref "false")
3570 (not (match_test "TARGET_HARD_SF_REGS"))
3571 (symbol_ref "false")
3573 (const_string "*")))])
3576 [(set (match_operand 0 "any_fp_register_operand")
3577 (match_operand 1 "memory_operand"))]
3579 && (GET_MODE (operands[0]) == TFmode
3580 || GET_MODE (operands[0]) == XFmode
3581 || GET_MODE (operands[0]) == DFmode
3582 || GET_MODE (operands[0]) == SFmode)"
3583 [(set (match_dup 0) (match_dup 2))]
3585 operands[2] = find_constant_src (curr_insn);
3587 if (operands[2] == NULL_RTX
3588 || (SSE_REGNO_P (REGNO (operands[0]))
3589 && !standard_sse_constant_p (operands[2]))
3590 || (STACK_REGNO_P (REGNO (operands[0]))
3591 && standard_80387_constant_p (operands[2]) < 1))
3596 [(set (match_operand 0 "any_fp_register_operand")
3597 (float_extend (match_operand 1 "memory_operand")))]
3599 && (GET_MODE (operands[0]) == TFmode
3600 || GET_MODE (operands[0]) == XFmode
3601 || GET_MODE (operands[0]) == DFmode)"
3602 [(set (match_dup 0) (match_dup 2))]
3604 operands[2] = find_constant_src (curr_insn);
3606 if (operands[2] == NULL_RTX
3607 || (SSE_REGNO_P (REGNO (operands[0]))
3608 && !standard_sse_constant_p (operands[2]))
3609 || (STACK_REGNO_P (REGNO (operands[0]))
3610 && standard_80387_constant_p (operands[2]) < 1))
3614 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3616 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3617 (match_operand:X87MODEF 1 "immediate_operand"))]
3619 && (standard_80387_constant_p (operands[1]) == 8
3620 || standard_80387_constant_p (operands[1]) == 9)"
3621 [(set (match_dup 0)(match_dup 1))
3623 (neg:X87MODEF (match_dup 0)))]
3625 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3626 operands[1] = CONST0_RTX (<MODE>mode);
3628 operands[1] = CONST1_RTX (<MODE>mode);
3631 (define_insn "swapxf"
3632 [(set (match_operand:XF 0 "register_operand" "+f")
3633 (match_operand:XF 1 "register_operand" "+f"))
3638 if (STACK_TOP_P (operands[0]))
3643 [(set_attr "type" "fxch")
3644 (set_attr "mode" "XF")])
3646 (define_insn "*swap<mode>"
3647 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3648 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3651 "TARGET_80387 || reload_completed"
3653 if (STACK_TOP_P (operands[0]))
3658 [(set_attr "type" "fxch")
3659 (set_attr "mode" "<MODE>")])
3661 ;; Zero extension instructions
3663 (define_expand "zero_extendsidi2"
3664 [(set (match_operand:DI 0 "nonimmediate_operand")
3665 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3667 (define_insn "*zero_extendsidi2"
3668 [(set (match_operand:DI 0 "nonimmediate_operand"
3669 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3671 (match_operand:SI 1 "x86_64_zext_operand"
3672 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))]
3675 switch (get_attr_type (insn))
3678 if (ix86_use_lea_for_mov (insn, operands))
3679 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3681 return "mov{l}\t{%1, %k0|%k0, %1}";
3687 return "movd\t{%1, %0|%0, %1}";
3690 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3693 if (GENERAL_REG_P (operands[0]))
3694 return "%vmovd\t{%1, %k0|%k0, %1}";
3696 return "%vmovd\t{%1, %0|%0, %1}";
3703 (cond [(eq_attr "alternative" "0,1,2")
3704 (const_string "nox64")
3705 (eq_attr "alternative" "3,7")
3706 (const_string "x64")
3707 (eq_attr "alternative" "8")
3708 (const_string "x64_sse4")
3709 (eq_attr "alternative" "10")
3710 (const_string "sse2")
3712 (const_string "*")))
3714 (cond [(eq_attr "alternative" "0,1,2,4")
3715 (const_string "multi")
3716 (eq_attr "alternative" "5,6")
3717 (const_string "mmxmov")
3718 (eq_attr "alternative" "7,9,10")
3719 (const_string "ssemov")
3720 (eq_attr "alternative" "8")
3721 (const_string "sselog1")
3723 (const_string "imovx")))
3724 (set (attr "prefix_extra")
3725 (if_then_else (eq_attr "alternative" "8")
3727 (const_string "*")))
3728 (set (attr "length_immediate")
3729 (if_then_else (eq_attr "alternative" "8")
3731 (const_string "*")))
3732 (set (attr "prefix")
3733 (if_then_else (eq_attr "type" "ssemov,sselog1")
3734 (const_string "maybe_vex")
3735 (const_string "orig")))
3736 (set (attr "prefix_0f")
3737 (if_then_else (eq_attr "type" "imovx")
3739 (const_string "*")))
3741 (cond [(eq_attr "alternative" "5,6")
3743 (eq_attr "alternative" "7,8,9")
3746 (const_string "SI")))])
3749 [(set (match_operand:DI 0 "memory_operand")
3750 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3752 [(set (match_dup 4) (const_int 0))]
3753 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3756 [(set (match_operand:DI 0 "register_operand")
3757 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3758 "!TARGET_64BIT && reload_completed
3759 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3760 && true_regnum (operands[0]) == true_regnum (operands[1])"
3761 [(set (match_dup 4) (const_int 0))]
3762 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3765 [(set (match_operand:DI 0 "nonimmediate_operand")
3766 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3767 "!TARGET_64BIT && reload_completed
3768 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3769 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3770 [(set (match_dup 3) (match_dup 1))
3771 (set (match_dup 4) (const_int 0))]
3772 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3774 (define_insn "zero_extend<mode>di2"
3775 [(set (match_operand:DI 0 "register_operand" "=r")
3777 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3779 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3780 [(set_attr "type" "imovx")
3781 (set_attr "mode" "SI")])
3783 (define_expand "zero_extend<mode>si2"
3784 [(set (match_operand:SI 0 "register_operand")
3785 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3788 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3790 operands[1] = force_reg (<MODE>mode, operands[1]);
3791 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3796 (define_insn_and_split "zero_extend<mode>si2_and"
3797 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3799 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3800 (clobber (reg:CC FLAGS_REG))]
3801 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3803 "&& reload_completed"
3804 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3805 (clobber (reg:CC FLAGS_REG))])]
3807 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3809 ix86_expand_clear (operands[0]);
3811 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3812 emit_insn (gen_movstrict<mode>
3813 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3817 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3819 [(set_attr "type" "alu1")
3820 (set_attr "mode" "SI")])
3822 (define_insn "*zero_extend<mode>si2"
3823 [(set (match_operand:SI 0 "register_operand" "=r")
3825 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3826 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3827 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3828 [(set_attr "type" "imovx")
3829 (set_attr "mode" "SI")])
3831 (define_expand "zero_extendqihi2"
3832 [(set (match_operand:HI 0 "register_operand")
3833 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3836 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3838 operands[1] = force_reg (QImode, operands[1]);
3839 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3844 (define_insn_and_split "zero_extendqihi2_and"
3845 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3846 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3847 (clobber (reg:CC FLAGS_REG))]
3848 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3850 "&& reload_completed"
3851 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3852 (clobber (reg:CC FLAGS_REG))])]
3854 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3856 ix86_expand_clear (operands[0]);
3858 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3859 emit_insn (gen_movstrictqi
3860 (gen_lowpart (QImode, operands[0]), operands[1]));
3864 operands[0] = gen_lowpart (SImode, operands[0]);
3866 [(set_attr "type" "alu1")
3867 (set_attr "mode" "SI")])
3869 ; zero extend to SImode to avoid partial register stalls
3870 (define_insn "*zero_extendqihi2"
3871 [(set (match_operand:HI 0 "register_operand" "=r")
3872 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3873 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3874 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3875 [(set_attr "type" "imovx")
3876 (set_attr "mode" "SI")])
3878 (define_insn_and_split "*zext<mode>_doubleword_and"
3879 [(set (match_operand:DI 0 "register_operand" "=&<r>")
3880 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3881 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
3882 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3884 "&& reload_completed && GENERAL_REG_P (operands[0])"
3885 [(set (match_dup 2) (const_int 0))]
3887 split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);
3889 emit_move_insn (operands[0], const0_rtx);
3891 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3892 emit_insn (gen_movstrict<mode>
3893 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3896 (define_insn_and_split "*zext<mode>_doubleword"
3897 [(set (match_operand:DI 0 "register_operand" "=r")
3898 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3899 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
3900 && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3902 "&& reload_completed && GENERAL_REG_P (operands[0])"
3903 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
3904 (set (match_dup 2) (const_int 0))]
3905 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
3907 (define_insn_and_split "*zextsi_doubleword"
3908 [(set (match_operand:DI 0 "register_operand" "=r")
3909 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3910 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
3912 "&& reload_completed && GENERAL_REG_P (operands[0])"
3913 [(set (match_dup 0) (match_dup 1))
3914 (set (match_dup 2) (const_int 0))]
3915 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
3917 ;; Sign extension instructions
3919 (define_expand "extendsidi2"
3920 [(set (match_operand:DI 0 "register_operand")
3921 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3926 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3931 (define_insn "*extendsidi2_rex64"
3932 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3933 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3937 movs{lq|x}\t{%1, %0|%0, %1}"
3938 [(set_attr "type" "imovx")
3939 (set_attr "mode" "DI")
3940 (set_attr "prefix_0f" "0")
3941 (set_attr "modrm" "0,1")])
3943 (define_insn "extendsidi2_1"
3944 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3945 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3946 (clobber (reg:CC FLAGS_REG))
3947 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3951 ;; Split the memory case. If the source register doesn't die, it will stay
3952 ;; this way, if it does die, following peephole2s take care of it.
3954 [(set (match_operand:DI 0 "memory_operand")
3955 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3956 (clobber (reg:CC FLAGS_REG))
3957 (clobber (match_operand:SI 2 "register_operand"))]
3961 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3963 emit_move_insn (operands[3], operands[1]);
3965 /* Generate a cltd if possible and doing so it profitable. */
3966 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3967 && true_regnum (operands[1]) == AX_REG
3968 && true_regnum (operands[2]) == DX_REG)
3970 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3974 emit_move_insn (operands[2], operands[1]);
3975 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3977 emit_move_insn (operands[4], operands[2]);
3981 ;; Peepholes for the case where the source register does die, after
3982 ;; being split with the above splitter.
3984 [(set (match_operand:SI 0 "memory_operand")
3985 (match_operand:SI 1 "register_operand"))
3986 (set (match_operand:SI 2 "register_operand") (match_dup 1))
3987 (parallel [(set (match_dup 2)
3988 (ashiftrt:SI (match_dup 2) (const_int 31)))
3989 (clobber (reg:CC FLAGS_REG))])
3990 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3991 "REGNO (operands[1]) != REGNO (operands[2])
3992 && peep2_reg_dead_p (2, operands[1])
3993 && peep2_reg_dead_p (4, operands[2])
3994 && !reg_mentioned_p (operands[2], operands[3])"
3995 [(set (match_dup 0) (match_dup 1))
3996 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3997 (clobber (reg:CC FLAGS_REG))])
3998 (set (match_dup 3) (match_dup 1))])
4001 [(set (match_operand:SI 0 "memory_operand")
4002 (match_operand:SI 1 "register_operand"))
4003 (parallel [(set (match_operand:SI 2 "register_operand")
4004 (ashiftrt:SI (match_dup 1) (const_int 31)))
4005 (clobber (reg:CC FLAGS_REG))])
4006 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4007 "/* cltd is shorter than sarl $31, %eax */
4008 !optimize_function_for_size_p (cfun)
4009 && true_regnum (operands[1]) == AX_REG
4010 && true_regnum (operands[2]) == DX_REG
4011 && peep2_reg_dead_p (2, operands[1])
4012 && peep2_reg_dead_p (3, operands[2])
4013 && !reg_mentioned_p (operands[2], operands[3])"
4014 [(set (match_dup 0) (match_dup 1))
4015 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4016 (clobber (reg:CC FLAGS_REG))])
4017 (set (match_dup 3) (match_dup 1))])
4019 ;; Extend to register case. Optimize case where source and destination
4020 ;; registers match and cases where we can use cltd.
4022 [(set (match_operand:DI 0 "register_operand")
4023 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4024 (clobber (reg:CC FLAGS_REG))
4025 (clobber (match_scratch:SI 2))]
4029 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4031 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4032 emit_move_insn (operands[3], operands[1]);
4034 /* Generate a cltd if possible and doing so it profitable. */
4035 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4036 && true_regnum (operands[3]) == AX_REG
4037 && true_regnum (operands[4]) == DX_REG)
4039 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4043 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4044 emit_move_insn (operands[4], operands[1]);
4046 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4050 (define_insn "extend<mode>di2"
4051 [(set (match_operand:DI 0 "register_operand" "=r")
4053 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4055 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4056 [(set_attr "type" "imovx")
4057 (set_attr "mode" "DI")])
4059 (define_insn "extendhisi2"
4060 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4061 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4064 switch (get_attr_prefix_0f (insn))
4067 return "{cwtl|cwde}";
4069 return "movs{wl|x}\t{%1, %0|%0, %1}";
4072 [(set_attr "type" "imovx")
4073 (set_attr "mode" "SI")
4074 (set (attr "prefix_0f")
4075 ;; movsx is short decodable while cwtl is vector decoded.
4076 (if_then_else (and (eq_attr "cpu" "!k6")
4077 (eq_attr "alternative" "0"))
4079 (const_string "1")))
4080 (set (attr "znver1_decode")
4081 (if_then_else (eq_attr "prefix_0f" "0")
4082 (const_string "double")
4083 (const_string "direct")))
4085 (if_then_else (eq_attr "prefix_0f" "0")
4087 (const_string "1")))])
4089 (define_insn "*extendhisi2_zext"
4090 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4093 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4096 switch (get_attr_prefix_0f (insn))
4099 return "{cwtl|cwde}";
4101 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4104 [(set_attr "type" "imovx")
4105 (set_attr "mode" "SI")
4106 (set (attr "prefix_0f")
4107 ;; movsx is short decodable while cwtl is vector decoded.
4108 (if_then_else (and (eq_attr "cpu" "!k6")
4109 (eq_attr "alternative" "0"))
4111 (const_string "1")))
4113 (if_then_else (eq_attr "prefix_0f" "0")
4115 (const_string "1")))])
4117 (define_insn "extendqisi2"
4118 [(set (match_operand:SI 0 "register_operand" "=r")
4119 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4121 "movs{bl|x}\t{%1, %0|%0, %1}"
4122 [(set_attr "type" "imovx")
4123 (set_attr "mode" "SI")])
4125 (define_insn "*extendqisi2_zext"
4126 [(set (match_operand:DI 0 "register_operand" "=r")
4128 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4130 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4131 [(set_attr "type" "imovx")
4132 (set_attr "mode" "SI")])
4134 (define_insn "extendqihi2"
4135 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4136 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4139 switch (get_attr_prefix_0f (insn))
4142 return "{cbtw|cbw}";
4144 return "movs{bw|x}\t{%1, %0|%0, %1}";
4147 [(set_attr "type" "imovx")
4148 (set_attr "mode" "HI")
4149 (set (attr "prefix_0f")
4150 ;; movsx is short decodable while cwtl is vector decoded.
4151 (if_then_else (and (eq_attr "cpu" "!k6")
4152 (eq_attr "alternative" "0"))
4154 (const_string "1")))
4156 (if_then_else (eq_attr "prefix_0f" "0")
4158 (const_string "1")))])
4160 ;; Conversions between float and double.
4162 ;; These are all no-ops in the model used for the 80387.
4163 ;; So just emit moves.
4165 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4167 [(set (match_operand:DF 0 "push_operand")
4168 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4170 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4171 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4174 [(set (match_operand:XF 0 "push_operand")
4175 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4177 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4178 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4179 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4181 (define_expand "extendsfdf2"
4182 [(set (match_operand:DF 0 "nonimmediate_operand")
4183 (float_extend:DF (match_operand:SF 1 "general_operand")))]
4184 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4186 /* ??? Needed for compress_float_constant since all fp constants
4187 are TARGET_LEGITIMATE_CONSTANT_P. */
4188 if (CONST_DOUBLE_P (operands[1]))
4190 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4191 && standard_80387_constant_p (operands[1]) > 0)
4193 operands[1] = simplify_const_unary_operation
4194 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4195 emit_move_insn_1 (operands[0], operands[1]);
4198 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4202 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4204 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4206 We do the conversion post reload to avoid producing of 128bit spills
4207 that might lead to ICE on 32bit target. The sequence unlikely combine
4210 [(set (match_operand:DF 0 "register_operand")
4212 (match_operand:SF 1 "nonimmediate_operand")))]
4213 "TARGET_USE_VECTOR_FP_CONVERTS
4214 && optimize_insn_for_speed_p ()
4215 && reload_completed && SSE_REG_P (operands[0])
4216 && (!EXT_REX_SSE_REG_P (operands[0])
4217 || TARGET_AVX512VL)"
4222 (parallel [(const_int 0) (const_int 1)]))))]
4224 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4225 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4226 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4227 Try to avoid move when unpacking can be done in source. */
4228 if (REG_P (operands[1]))
4230 /* If it is unsafe to overwrite upper half of source, we need
4231 to move to destination and unpack there. */
4232 if (((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4233 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4234 && true_regnum (operands[0]) != true_regnum (operands[1]))
4235 || (EXT_REX_SSE_REG_P (operands[1])
4236 && !TARGET_AVX512VL))
4238 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4239 emit_move_insn (tmp, operands[1]);
4242 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4243 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4244 =v, v, then vbroadcastss will be only needed for AVX512F without
4246 if (!EXT_REX_SSE_REGNO_P (true_regnum (operands[3])))
4247 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4251 rtx tmp = simplify_gen_subreg (V16SFmode, operands[3], V4SFmode, 0);
4252 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4256 emit_insn (gen_vec_setv4sf_0 (operands[3],
4257 CONST0_RTX (V4SFmode), operands[1]));
4260 ;; It's more profitable to split and then extend in the same register.
4262 [(set (match_operand:DF 0 "register_operand")
4264 (match_operand:SF 1 "memory_operand")))]
4265 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4266 && optimize_insn_for_speed_p ()
4267 && SSE_REG_P (operands[0])"
4268 [(set (match_dup 2) (match_dup 1))
4269 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4270 "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
4272 (define_insn "*extendsfdf2_mixed"
4273 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,v")
4275 (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4276 "TARGET_SSE2 && TARGET_SSE_MATH"
4278 switch (which_alternative)
4282 return output_387_reg_move (insn, operands);
4285 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4291 [(set_attr "type" "fmov,fmov,ssecvt")
4292 (set_attr "prefix" "orig,orig,maybe_vex")
4293 (set_attr "mode" "SF,XF,DF")
4294 (set (attr "enabled")
4295 (cond [(eq_attr "alternative" "0,1")
4296 (symbol_ref "TARGET_MIX_SSE_I387")
4298 (symbol_ref "true")))])
4300 (define_insn "*extendsfdf2_i387"
4301 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4302 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4304 "* return output_387_reg_move (insn, operands);"
4305 [(set_attr "type" "fmov")
4306 (set_attr "mode" "SF,XF")])
4308 (define_expand "extend<mode>xf2"
4309 [(set (match_operand:XF 0 "nonimmediate_operand")
4310 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4313 /* ??? Needed for compress_float_constant since all fp constants
4314 are TARGET_LEGITIMATE_CONSTANT_P. */
4315 if (CONST_DOUBLE_P (operands[1]))
4317 if (standard_80387_constant_p (operands[1]) > 0)
4319 operands[1] = simplify_const_unary_operation
4320 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4321 emit_move_insn_1 (operands[0], operands[1]);
4324 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4328 (define_insn "*extend<mode>xf2_i387"
4329 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4331 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4333 "* return output_387_reg_move (insn, operands);"
4334 [(set_attr "type" "fmov")
4335 (set_attr "mode" "<MODE>,XF")])
4337 ;; %%% This seems like bad news.
4338 ;; This cannot output into an f-reg because there is no way to be sure
4339 ;; of truncating in that case. Otherwise this is just like a simple move
4340 ;; insn. So we pretend we can output to a reg in order to get better
4341 ;; register preferencing, but we really use a stack slot.
4343 ;; Conversion from DFmode to SFmode.
4345 (define_expand "truncdfsf2"
4346 [(set (match_operand:SF 0 "nonimmediate_operand")
4348 (match_operand:DF 1 "nonimmediate_operand")))]
4349 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4351 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4353 else if (flag_unsafe_math_optimizations)
4357 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4358 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4363 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4365 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4367 We do the conversion post reload to avoid producing of 128bit spills
4368 that might lead to ICE on 32bit target. The sequence unlikely combine
4371 [(set (match_operand:SF 0 "register_operand")
4373 (match_operand:DF 1 "nonimmediate_operand")))]
4374 "TARGET_USE_VECTOR_FP_CONVERTS
4375 && optimize_insn_for_speed_p ()
4376 && reload_completed && SSE_REG_P (operands[0])
4377 && (!EXT_REX_SSE_REG_P (operands[0])
4378 || TARGET_AVX512VL)"
4381 (float_truncate:V2SF
4385 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4386 operands[3] = CONST0_RTX (V2SFmode);
4387 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4388 /* Use movsd for loading from memory, unpcklpd for registers.
4389 Try to avoid move when unpacking can be done in source, or SSE3
4390 movddup is available. */
4391 if (REG_P (operands[1]))
4394 && true_regnum (operands[0]) != true_regnum (operands[1])
4395 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4396 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4398 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4399 emit_move_insn (tmp, operands[1]);
4402 else if (!TARGET_SSE3)
4403 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4404 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4407 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4408 CONST0_RTX (DFmode)));
4411 ;; It's more profitable to split and then extend in the same register.
4413 [(set (match_operand:SF 0 "register_operand")
4415 (match_operand:DF 1 "memory_operand")))]
4416 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4417 && optimize_insn_for_speed_p ()
4418 && SSE_REG_P (operands[0])"
4419 [(set (match_dup 2) (match_dup 1))
4420 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4421 "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4423 (define_expand "truncdfsf2_with_temp"
4424 [(parallel [(set (match_operand:SF 0)
4425 (float_truncate:SF (match_operand:DF 1)))
4426 (clobber (match_operand:SF 2))])])
4428 ;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
4429 ;; because nothing we do there is unsafe.
4430 (define_insn "*truncdfsf_fast_mixed"
4431 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,v")
4433 (match_operand:DF 1 "nonimmediate_operand" "f ,vm")))]
4434 "TARGET_SSE2 && TARGET_SSE_MATH"
4436 switch (which_alternative)
4439 return output_387_reg_move (insn, operands);
4441 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4446 [(set_attr "type" "fmov,ssecvt")
4447 (set_attr "prefix" "orig,maybe_vex")
4448 (set_attr "mode" "SF")
4449 (set (attr "enabled")
4450 (cond [(eq_attr "alternative" "0")
4451 (symbol_ref "TARGET_MIX_SSE_I387
4452 && flag_unsafe_math_optimizations")
4454 (symbol_ref "true")))])
4456 (define_insn "*truncdfsf_fast_i387"
4457 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4459 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4460 "TARGET_80387 && flag_unsafe_math_optimizations"
4461 "* return output_387_reg_move (insn, operands);"
4462 [(set_attr "type" "fmov")
4463 (set_attr "mode" "SF")])
4465 (define_insn "*truncdfsf_mixed"
4466 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4468 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4469 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4470 "TARGET_MIX_SSE_I387"
4472 switch (which_alternative)
4475 return output_387_reg_move (insn, operands);
4477 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4483 [(set_attr "isa" "*,sse2,*,*,*")
4484 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4485 (set_attr "unit" "*,*,i387,i387,i387")
4486 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4487 (set_attr "mode" "SF")])
4489 (define_insn "*truncdfsf_i387"
4490 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4492 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4493 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4496 switch (which_alternative)
4499 return output_387_reg_move (insn, operands);
4505 [(set_attr "type" "fmov,multi,multi,multi")
4506 (set_attr "unit" "*,i387,i387,i387")
4507 (set_attr "mode" "SF")])
4509 (define_insn "*truncdfsf2_i387_1"
4510 [(set (match_operand:SF 0 "memory_operand" "=m")
4512 (match_operand:DF 1 "register_operand" "f")))]
4514 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4515 && !TARGET_MIX_SSE_I387"
4516 "* return output_387_reg_move (insn, operands);"
4517 [(set_attr "type" "fmov")
4518 (set_attr "mode" "SF")])
4521 [(set (match_operand:SF 0 "register_operand")
4523 (match_operand:DF 1 "fp_register_operand")))
4524 (clobber (match_operand 2))]
4526 [(set (match_dup 2) (match_dup 1))
4527 (set (match_dup 0) (match_dup 2))]
4528 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4530 ;; Conversion from XFmode to {SF,DF}mode
4532 (define_expand "truncxf<mode>2"
4533 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4534 (float_truncate:MODEF
4535 (match_operand:XF 1 "register_operand")))
4536 (clobber (match_dup 2))])]
4539 if (flag_unsafe_math_optimizations)
4541 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4542 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4543 if (reg != operands[0])
4544 emit_move_insn (operands[0], reg);
4548 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4551 (define_insn "*truncxfsf2_mixed"
4552 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4554 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4555 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4558 gcc_assert (!which_alternative);
4559 return output_387_reg_move (insn, operands);
4561 [(set_attr "type" "fmov,multi,multi,multi")
4562 (set_attr "unit" "*,i387,i387,i387")
4563 (set_attr "mode" "SF")])
4565 (define_insn "*truncxfdf2_mixed"
4566 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4568 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4569 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4572 gcc_assert (!which_alternative);
4573 return output_387_reg_move (insn, operands);
4575 [(set_attr "isa" "*,*,sse2,*")
4576 (set_attr "type" "fmov,multi,multi,multi")
4577 (set_attr "unit" "*,i387,i387,i387")
4578 (set_attr "mode" "DF")])
4580 (define_insn "truncxf<mode>2_i387_noop"
4581 [(set (match_operand:MODEF 0 "register_operand" "=f")
4582 (float_truncate:MODEF
4583 (match_operand:XF 1 "register_operand" "f")))]
4584 "TARGET_80387 && flag_unsafe_math_optimizations"
4585 "* return output_387_reg_move (insn, operands);"
4586 [(set_attr "type" "fmov")
4587 (set_attr "mode" "<MODE>")])
4589 (define_insn "*truncxf<mode>2_i387"
4590 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4591 (float_truncate:MODEF
4592 (match_operand:XF 1 "register_operand" "f")))]
4594 "* return output_387_reg_move (insn, operands);"
4595 [(set_attr "type" "fmov")
4596 (set_attr "mode" "<MODE>")])
4599 [(set (match_operand:MODEF 0 "register_operand")
4600 (float_truncate:MODEF
4601 (match_operand:XF 1 "register_operand")))
4602 (clobber (match_operand:MODEF 2 "memory_operand"))]
4603 "TARGET_80387 && reload_completed"
4604 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4605 (set (match_dup 0) (match_dup 2))])
4608 [(set (match_operand:MODEF 0 "memory_operand")
4609 (float_truncate:MODEF
4610 (match_operand:XF 1 "register_operand")))
4611 (clobber (match_operand:MODEF 2 "memory_operand"))]
4613 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4615 ;; Signed conversion to DImode.
4617 (define_expand "fix_truncxfdi2"
4618 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4619 (fix:DI (match_operand:XF 1 "register_operand")))
4620 (clobber (reg:CC FLAGS_REG))])]
4625 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4630 (define_expand "fix_trunc<mode>di2"
4631 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4632 (fix:DI (match_operand:MODEF 1 "register_operand")))
4633 (clobber (reg:CC FLAGS_REG))])]
4634 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4637 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4639 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4642 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4644 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4645 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4646 if (out != operands[0])
4647 emit_move_insn (operands[0], out);
4652 ;; Signed conversion to SImode.
4654 (define_expand "fix_truncxfsi2"
4655 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4656 (fix:SI (match_operand:XF 1 "register_operand")))
4657 (clobber (reg:CC FLAGS_REG))])]
4662 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4667 (define_expand "fix_trunc<mode>si2"
4668 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4669 (fix:SI (match_operand:MODEF 1 "register_operand")))
4670 (clobber (reg:CC FLAGS_REG))])]
4671 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4674 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4676 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4679 if (SSE_FLOAT_MODE_P (<MODE>mode))
4681 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4682 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4683 if (out != operands[0])
4684 emit_move_insn (operands[0], out);
4689 ;; Signed conversion to HImode.
4691 (define_expand "fix_trunc<mode>hi2"
4692 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4693 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4694 (clobber (reg:CC FLAGS_REG))])]
4696 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4700 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4705 ;; Unsigned conversion to SImode.
4707 (define_expand "fixuns_trunc<mode>si2"
4709 [(set (match_operand:SI 0 "register_operand")
4711 (match_operand:MODEF 1 "nonimmediate_operand")))
4713 (clobber (match_scratch:<ssevecmode> 3))
4714 (clobber (match_scratch:<ssevecmode> 4))])]
4715 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4717 machine_mode mode = <MODE>mode;
4718 machine_mode vecmode = <ssevecmode>mode;
4719 REAL_VALUE_TYPE TWO31r;
4722 if (optimize_insn_for_size_p ())
4725 real_ldexp (&TWO31r, &dconst1, 31);
4726 two31 = const_double_from_real_value (TWO31r, mode);
4727 two31 = ix86_build_const_vector (vecmode, true, two31);
4728 operands[2] = force_reg (vecmode, two31);
4731 (define_insn_and_split "*fixuns_trunc<mode>_1"
4732 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4734 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4735 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4736 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4737 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4738 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4739 && optimize_function_for_speed_p (cfun)"
4741 "&& reload_completed"
4744 ix86_split_convert_uns_si_sse (operands);
4748 ;; Unsigned conversion to HImode.
4749 ;; Without these patterns, we'll try the unsigned SI conversion which
4750 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4752 (define_expand "fixuns_trunc<mode>hi2"
4754 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4755 (set (match_operand:HI 0 "nonimmediate_operand")
4756 (subreg:HI (match_dup 2) 0))]
4757 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4758 "operands[2] = gen_reg_rtx (SImode);")
4760 ;; When SSE is available, it is always faster to use it!
4761 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4762 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4763 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
4764 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4765 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4766 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4767 [(set_attr "type" "sseicvt")
4768 (set_attr "prefix" "maybe_vex")
4769 (set (attr "prefix_rex")
4771 (match_test "<SWI48:MODE>mode == DImode")
4773 (const_string "*")))
4774 (set_attr "mode" "<MODEF:MODE>")
4775 (set_attr "athlon_decode" "double,vector")
4776 (set_attr "amdfam10_decode" "double,double")
4777 (set_attr "bdver1_decode" "double,double")])
4779 ;; Avoid vector decoded forms of the instruction.
4781 [(match_scratch:MODEF 2 "x")
4782 (set (match_operand:SWI48 0 "register_operand")
4783 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4784 "TARGET_AVOID_VECTOR_DECODE
4785 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4786 && optimize_insn_for_speed_p ()"
4787 [(set (match_dup 2) (match_dup 1))
4788 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4790 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4791 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4792 (fix:SWI248x (match_operand 1 "register_operand")))]
4793 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4795 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4796 && (TARGET_64BIT || <MODE>mode != DImode))
4798 && can_create_pseudo_p ()"
4803 if (memory_operand (operands[0], VOIDmode))
4804 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4807 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4808 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4814 [(set_attr "type" "fisttp")
4815 (set_attr "mode" "<MODE>")])
4817 (define_insn "fix_trunc<mode>_i387_fisttp"
4818 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4819 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4820 (clobber (match_scratch:XF 2 "=&1f"))]
4821 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4823 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4824 && (TARGET_64BIT || <MODE>mode != DImode))
4825 && TARGET_SSE_MATH)"
4826 "* return output_fix_trunc (insn, operands, true);"
4827 [(set_attr "type" "fisttp")
4828 (set_attr "mode" "<MODE>")])
4830 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4831 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4832 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4833 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4834 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4835 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4837 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4838 && (TARGET_64BIT || <MODE>mode != DImode))
4839 && TARGET_SSE_MATH)"
4841 [(set_attr "type" "fisttp")
4842 (set_attr "mode" "<MODE>")])
4845 [(set (match_operand:SWI248x 0 "register_operand")
4846 (fix:SWI248x (match_operand 1 "register_operand")))
4847 (clobber (match_operand:SWI248x 2 "memory_operand"))
4848 (clobber (match_scratch 3))]
4850 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4851 (clobber (match_dup 3))])
4852 (set (match_dup 0) (match_dup 2))])
4855 [(set (match_operand:SWI248x 0 "memory_operand")
4856 (fix:SWI248x (match_operand 1 "register_operand")))
4857 (clobber (match_operand:SWI248x 2 "memory_operand"))
4858 (clobber (match_scratch 3))]
4860 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4861 (clobber (match_dup 3))])])
4863 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4864 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4865 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4866 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4867 ;; function in i386.c.
4868 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4869 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4870 (fix:SWI248x (match_operand 1 "register_operand")))
4871 (clobber (reg:CC FLAGS_REG))]
4872 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4874 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4875 && (TARGET_64BIT || <MODE>mode != DImode))
4876 && can_create_pseudo_p ()"
4881 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4883 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4884 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4885 if (memory_operand (operands[0], VOIDmode))
4886 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4887 operands[2], operands[3]));
4890 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4891 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4892 operands[2], operands[3],
4897 [(set_attr "type" "fistp")
4898 (set_attr "i387_cw" "trunc")
4899 (set_attr "mode" "<MODE>")])
4901 (define_insn "fix_truncdi_i387"
4902 [(set (match_operand:DI 0 "memory_operand" "=m")
4903 (fix:DI (match_operand 1 "register_operand" "f")))
4904 (use (match_operand:HI 2 "memory_operand" "m"))
4905 (use (match_operand:HI 3 "memory_operand" "m"))
4906 (clobber (match_scratch:XF 4 "=&1f"))]
4907 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4909 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4910 "* return output_fix_trunc (insn, operands, false);"
4911 [(set_attr "type" "fistp")
4912 (set_attr "i387_cw" "trunc")
4913 (set_attr "mode" "DI")])
4915 (define_insn "fix_truncdi_i387_with_temp"
4916 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4917 (fix:DI (match_operand 1 "register_operand" "f,f")))
4918 (use (match_operand:HI 2 "memory_operand" "m,m"))
4919 (use (match_operand:HI 3 "memory_operand" "m,m"))
4920 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4921 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4922 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4924 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4926 [(set_attr "type" "fistp")
4927 (set_attr "i387_cw" "trunc")
4928 (set_attr "mode" "DI")])
4931 [(set (match_operand:DI 0 "register_operand")
4932 (fix:DI (match_operand 1 "register_operand")))
4933 (use (match_operand:HI 2 "memory_operand"))
4934 (use (match_operand:HI 3 "memory_operand"))
4935 (clobber (match_operand:DI 4 "memory_operand"))
4936 (clobber (match_scratch 5))]
4938 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4941 (clobber (match_dup 5))])
4942 (set (match_dup 0) (match_dup 4))])
4945 [(set (match_operand:DI 0 "memory_operand")
4946 (fix:DI (match_operand 1 "register_operand")))
4947 (use (match_operand:HI 2 "memory_operand"))
4948 (use (match_operand:HI 3 "memory_operand"))
4949 (clobber (match_operand:DI 4 "memory_operand"))
4950 (clobber (match_scratch 5))]
4952 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4955 (clobber (match_dup 5))])])
4957 (define_insn "fix_trunc<mode>_i387"
4958 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4959 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4960 (use (match_operand:HI 2 "memory_operand" "m"))
4961 (use (match_operand:HI 3 "memory_operand" "m"))]
4962 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4964 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4965 "* return output_fix_trunc (insn, operands, false);"
4966 [(set_attr "type" "fistp")
4967 (set_attr "i387_cw" "trunc")
4968 (set_attr "mode" "<MODE>")])
4970 (define_insn "fix_trunc<mode>_i387_with_temp"
4971 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4972 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4973 (use (match_operand:HI 2 "memory_operand" "m,m"))
4974 (use (match_operand:HI 3 "memory_operand" "m,m"))
4975 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4976 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4978 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4980 [(set_attr "type" "fistp")
4981 (set_attr "i387_cw" "trunc")
4982 (set_attr "mode" "<MODE>")])
4985 [(set (match_operand:SWI24 0 "register_operand")
4986 (fix:SWI24 (match_operand 1 "register_operand")))
4987 (use (match_operand:HI 2 "memory_operand"))
4988 (use (match_operand:HI 3 "memory_operand"))
4989 (clobber (match_operand:SWI24 4 "memory_operand"))]
4991 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4993 (use (match_dup 3))])
4994 (set (match_dup 0) (match_dup 4))])
4997 [(set (match_operand:SWI24 0 "memory_operand")
4998 (fix:SWI24 (match_operand 1 "register_operand")))
4999 (use (match_operand:HI 2 "memory_operand"))
5000 (use (match_operand:HI 3 "memory_operand"))
5001 (clobber (match_operand:SWI24 4 "memory_operand"))]
5003 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
5005 (use (match_dup 3))])])
5007 (define_insn "x86_fnstcw_1"
5008 [(set (match_operand:HI 0 "memory_operand" "=m")
5009 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5012 [(set (attr "length")
5013 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5014 (set_attr "mode" "HI")
5015 (set_attr "unit" "i387")
5016 (set_attr "bdver1_decode" "vector")])
5018 (define_insn "x86_fldcw_1"
5019 [(set (reg:HI FPCR_REG)
5020 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5023 [(set (attr "length")
5024 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5025 (set_attr "mode" "HI")
5026 (set_attr "unit" "i387")
5027 (set_attr "athlon_decode" "vector")
5028 (set_attr "amdfam10_decode" "vector")
5029 (set_attr "bdver1_decode" "vector")])
5031 ;; Conversion between fixed point and floating point.
5033 ;; Even though we only accept memory inputs, the backend _really_
5034 ;; wants to be able to do this between registers. Thankfully, LRA
5035 ;; will fix this up for us during register allocation.
5037 (define_insn "floathi<mode>2"
5038 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5039 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5041 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5042 || TARGET_MIX_SSE_I387)"
5044 [(set_attr "type" "fmov")
5045 (set_attr "mode" "<MODE>")
5046 (set_attr "znver1_decode" "double")
5047 (set_attr "fp_int_src" "true")])
5049 (define_insn "float<SWI48x:mode>xf2"
5050 [(set (match_operand:XF 0 "register_operand" "=f")
5051 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5054 [(set_attr "type" "fmov")
5055 (set_attr "mode" "XF")
5056 (set_attr "znver1_decode" "double")
5057 (set_attr "fp_int_src" "true")])
5059 (define_expand "float<SWI48:mode><MODEF:mode>2"
5060 [(set (match_operand:MODEF 0 "register_operand")
5061 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5062 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5064 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
5065 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5067 rtx reg = gen_reg_rtx (XFmode);
5068 rtx (*insn)(rtx, rtx);
5070 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
5072 if (<MODEF:MODE>mode == SFmode)
5073 insn = gen_truncxfsf2;
5074 else if (<MODEF:MODE>mode == DFmode)
5075 insn = gen_truncxfdf2;
5079 emit_insn (insn (operands[0], reg));
5084 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed"
5085 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5087 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5088 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5091 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5092 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5093 [(set_attr "type" "fmov,sseicvt,sseicvt")
5094 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5095 (set_attr "mode" "<MODEF:MODE>")
5096 (set (attr "prefix_rex")
5098 (and (eq_attr "prefix" "maybe_vex")
5099 (match_test "<SWI48:MODE>mode == DImode"))
5101 (const_string "*")))
5102 (set_attr "unit" "i387,*,*")
5103 (set_attr "athlon_decode" "*,double,direct")
5104 (set_attr "amdfam10_decode" "*,vector,double")
5105 (set_attr "bdver1_decode" "*,double,direct")
5106 (set_attr "znver1_decode" "double,*,*")
5107 (set_attr "fp_int_src" "true")
5108 (set (attr "enabled")
5109 (cond [(eq_attr "alternative" "0")
5110 (symbol_ref "TARGET_MIX_SSE_I387
5111 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5114 (symbol_ref "true")))
5115 (set (attr "preferred_for_speed")
5116 (cond [(eq_attr "alternative" "1")
5117 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5118 (symbol_ref "true")))])
5120 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
5121 [(set (match_operand:MODEF 0 "register_operand" "=f")
5122 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5123 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
5125 [(set_attr "type" "fmov")
5126 (set_attr "mode" "<MODEF:MODE>")
5127 (set_attr "znver1_decode" "double")
5128 (set_attr "fp_int_src" "true")])
5130 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5131 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5132 ;; alternative in sse2_loadld.
5134 [(set (match_operand:MODEF 0 "register_operand")
5135 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5136 "TARGET_SSE2 && TARGET_SSE_MATH
5137 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5138 && reload_completed && SSE_REG_P (operands[0])
5139 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5140 && (!EXT_REX_SSE_REG_P (operands[0])
5141 || TARGET_AVX512VL)"
5144 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5146 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5148 emit_insn (gen_sse2_loadld (operands[4],
5149 CONST0_RTX (V4SImode), operands[1]));
5151 if (<ssevecmode>mode == V4SFmode)
5152 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5154 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5158 ;; Avoid partial SSE register dependency stalls
5160 [(set (match_operand:MODEF 0 "register_operand")
5161 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5162 "TARGET_SSE2 && TARGET_SSE_MATH
5163 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5164 && optimize_function_for_speed_p (cfun)
5165 && reload_completed && SSE_REG_P (operands[0])
5166 && (!EXT_REX_SSE_REG_P (operands[0])
5167 || TARGET_AVX512VL)"
5170 const machine_mode vmode = <MODEF:ssevecmode>mode;
5171 const machine_mode mode = <MODEF:MODE>mode;
5172 rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
5174 emit_move_insn (op0, CONST0_RTX (vmode));
5176 t = gen_rtx_FLOAT (mode, operands[1]);
5177 t = gen_rtx_VEC_DUPLICATE (vmode, t);
5178 t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
5179 emit_insn (gen_rtx_SET (op0, t));
5183 ;; Break partial reg stall for cvtsd2ss.
5186 [(set (match_operand:SF 0 "register_operand")
5188 (match_operand:DF 1 "nonimmediate_operand")))]
5189 "TARGET_SSE2 && TARGET_SSE_MATH
5190 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5191 && optimize_function_for_speed_p (cfun)
5192 && SSE_REG_P (operands[0])
5193 && (!SSE_REG_P (operands[1])
5194 || REGNO (operands[0]) != REGNO (operands[1]))
5195 && (!EXT_REX_SSE_REG_P (operands[0])
5196 || TARGET_AVX512VL)"
5200 (float_truncate:V2SF
5205 operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
5207 operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
5209 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5212 ;; Break partial reg stall for cvtss2sd.
5215 [(set (match_operand:DF 0 "register_operand")
5217 (match_operand:SF 1 "nonimmediate_operand")))]
5218 "TARGET_SSE2 && TARGET_SSE_MATH
5219 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5220 && optimize_function_for_speed_p (cfun)
5221 && SSE_REG_P (operands[0])
5222 && (!SSE_REG_P (operands[1])
5223 || REGNO (operands[0]) != REGNO (operands[1]))
5224 && (!EXT_REX_SSE_REG_P (operands[0])
5225 || TARGET_AVX512VL)"
5231 (parallel [(const_int 0) (const_int 1)])))
5235 operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
5237 operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
5239 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5242 ;; Avoid store forwarding (partial memory) stall penalty
5243 ;; by passing DImode value through XMM registers. */
5245 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5246 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5248 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5249 (clobber (match_scratch:V4SI 3 "=X,x"))
5250 (clobber (match_scratch:V4SI 4 "=X,x"))
5251 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5252 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5253 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5254 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5256 [(set_attr "type" "multi")
5257 (set_attr "mode" "<X87MODEF:MODE>")
5258 (set_attr "unit" "i387")
5259 (set_attr "fp_int_src" "true")])
5262 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5263 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5264 (clobber (match_scratch:V4SI 3))
5265 (clobber (match_scratch:V4SI 4))
5266 (clobber (match_operand:DI 2 "memory_operand"))]
5267 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5268 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5269 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5270 && reload_completed"
5271 [(set (match_dup 2) (match_dup 3))
5272 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5274 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5275 Assemble the 64-bit DImode value in an xmm register. */
5276 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5277 gen_lowpart (SImode, operands[1])));
5278 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5279 gen_highpart (SImode, operands[1])));
5280 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5283 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5287 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5288 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5289 (clobber (match_scratch:V4SI 3))
5290 (clobber (match_scratch:V4SI 4))
5291 (clobber (match_operand:DI 2 "memory_operand"))]
5292 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5293 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5294 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5295 && reload_completed"
5296 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5298 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5299 [(set (match_operand:MODEF 0 "register_operand")
5300 (unsigned_float:MODEF
5301 (match_operand:SWI12 1 "nonimmediate_operand")))]
5303 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5305 operands[1] = convert_to_mode (SImode, operands[1], 1);
5306 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5310 ;; Avoid store forwarding (partial memory) stall penalty by extending
5311 ;; SImode value to DImode through XMM register instead of pushing two
5312 ;; SImode values to stack. Also note that fild loads from memory only.
5314 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5315 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5316 (unsigned_float:X87MODEF
5317 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5318 (clobber (match_scratch:DI 3 "=x"))
5319 (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5321 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5322 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5324 "&& reload_completed"
5325 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5326 (set (match_dup 2) (match_dup 3))
5328 (float:X87MODEF (match_dup 2)))]
5330 [(set_attr "type" "multi")
5331 (set_attr "mode" "<MODE>")])
5333 (define_expand "floatunssi<mode>2"
5335 [(set (match_operand:X87MODEF 0 "register_operand")
5336 (unsigned_float:X87MODEF
5337 (match_operand:SI 1 "nonimmediate_operand")))
5338 (clobber (match_scratch:DI 3))
5339 (clobber (match_dup 2))])]
5341 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5342 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5343 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5345 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5347 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5351 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5354 (define_expand "floatunsdisf2"
5355 [(use (match_operand:SF 0 "register_operand"))
5356 (use (match_operand:DI 1 "nonimmediate_operand"))]
5357 "TARGET_64BIT && TARGET_SSE_MATH"
5358 "x86_emit_floatuns (operands); DONE;")
5360 (define_expand "floatunsdidf2"
5361 [(use (match_operand:DF 0 "register_operand"))
5362 (use (match_operand:DI 1 "nonimmediate_operand"))]
5363 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5364 && TARGET_SSE2 && TARGET_SSE_MATH"
5367 x86_emit_floatuns (operands);
5369 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5373 ;; Load effective address instructions
5375 (define_insn_and_split "*lea<mode>"
5376 [(set (match_operand:SWI48 0 "register_operand" "=r")
5377 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5380 if (SImode_address_operand (operands[1], VOIDmode))
5382 gcc_assert (TARGET_64BIT);
5383 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5386 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5388 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5391 machine_mode mode = <MODE>mode;
5394 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5395 change operands[] array behind our back. */
5396 pat = PATTERN (curr_insn);
5398 operands[0] = SET_DEST (pat);
5399 operands[1] = SET_SRC (pat);
5401 /* Emit all operations in SImode for zero-extended addresses. */
5402 if (SImode_address_operand (operands[1], VOIDmode))
5405 ix86_split_lea_for_addr (curr_insn, operands, mode);
5407 /* Zero-extend return register to DImode for zero-extended addresses. */
5408 if (mode != <MODE>mode)
5409 emit_insn (gen_zero_extendsidi2
5410 (operands[0], gen_lowpart (mode, operands[0])));
5414 [(set_attr "type" "lea")
5417 (match_operand 1 "SImode_address_operand")
5419 (const_string "<MODE>")))])
5423 (define_expand "add<mode>3"
5424 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5425 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5426 (match_operand:SDWIM 2 "<general_operand>")))]
5428 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5430 (define_insn_and_split "*add<dwi>3_doubleword"
5431 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5433 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5434 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5435 (clobber (reg:CC FLAGS_REG))]
5436 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5439 [(parallel [(set (reg:CCC FLAGS_REG)
5441 (plus:DWIH (match_dup 1) (match_dup 2))
5444 (plus:DWIH (match_dup 1) (match_dup 2)))])
5445 (parallel [(set (match_dup 3)
5448 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5451 (clobber (reg:CC FLAGS_REG))])]
5453 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5454 if (operands[2] == const0_rtx)
5456 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5461 (define_insn "*add<mode>_1"
5462 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5464 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5465 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5466 (clobber (reg:CC FLAGS_REG))]
5467 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5469 switch (get_attr_type (insn))
5475 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5476 if (operands[2] == const1_rtx)
5477 return "inc{<imodesuffix>}\t%0";
5480 gcc_assert (operands[2] == constm1_rtx);
5481 return "dec{<imodesuffix>}\t%0";
5485 /* For most processors, ADD is faster than LEA. This alternative
5486 was added to use ADD as much as possible. */
5487 if (which_alternative == 2)
5488 std::swap (operands[1], operands[2]);
5490 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5491 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5492 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5494 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5498 (cond [(eq_attr "alternative" "3")
5499 (const_string "lea")
5500 (match_operand:SWI48 2 "incdec_operand")
5501 (const_string "incdec")
5503 (const_string "alu")))
5504 (set (attr "length_immediate")
5506 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5508 (const_string "*")))
5509 (set_attr "mode" "<MODE>")])
5511 ;; It may seem that nonimmediate operand is proper one for operand 1.
5512 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5513 ;; we take care in ix86_binary_operator_ok to not allow two memory
5514 ;; operands so proper swapping will be done in reload. This allow
5515 ;; patterns constructed from addsi_1 to match.
5517 (define_insn "addsi_1_zext"
5518 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5520 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5521 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5522 (clobber (reg:CC FLAGS_REG))]
5523 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5525 switch (get_attr_type (insn))
5531 if (operands[2] == const1_rtx)
5532 return "inc{l}\t%k0";
5535 gcc_assert (operands[2] == constm1_rtx);
5536 return "dec{l}\t%k0";
5540 /* For most processors, ADD is faster than LEA. This alternative
5541 was added to use ADD as much as possible. */
5542 if (which_alternative == 1)
5543 std::swap (operands[1], operands[2]);
5545 if (x86_maybe_negate_const_int (&operands[2], SImode))
5546 return "sub{l}\t{%2, %k0|%k0, %2}";
5548 return "add{l}\t{%2, %k0|%k0, %2}";
5552 (cond [(eq_attr "alternative" "2")
5553 (const_string "lea")
5554 (match_operand:SI 2 "incdec_operand")
5555 (const_string "incdec")
5557 (const_string "alu")))
5558 (set (attr "length_immediate")
5560 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5562 (const_string "*")))
5563 (set_attr "mode" "SI")])
5565 (define_insn "*addhi_1"
5566 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5567 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5568 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5569 (clobber (reg:CC FLAGS_REG))]
5570 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5572 switch (get_attr_type (insn))
5578 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5579 if (operands[2] == const1_rtx)
5580 return "inc{w}\t%0";
5583 gcc_assert (operands[2] == constm1_rtx);
5584 return "dec{w}\t%0";
5588 /* For most processors, ADD is faster than LEA. This alternative
5589 was added to use ADD as much as possible. */
5590 if (which_alternative == 2)
5591 std::swap (operands[1], operands[2]);
5593 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5594 if (x86_maybe_negate_const_int (&operands[2], HImode))
5595 return "sub{w}\t{%2, %0|%0, %2}";
5597 return "add{w}\t{%2, %0|%0, %2}";
5601 (cond [(eq_attr "alternative" "3")
5602 (const_string "lea")
5603 (match_operand:HI 2 "incdec_operand")
5604 (const_string "incdec")
5606 (const_string "alu")))
5607 (set (attr "length_immediate")
5609 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5611 (const_string "*")))
5612 (set_attr "mode" "HI,HI,HI,SI")])
5614 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5615 (define_insn "*addqi_1"
5616 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5617 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5618 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5619 (clobber (reg:CC FLAGS_REG))]
5620 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5622 bool widen = (which_alternative == 3 || which_alternative == 4);
5624 switch (get_attr_type (insn))
5630 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5631 if (operands[2] == const1_rtx)
5632 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5635 gcc_assert (operands[2] == constm1_rtx);
5636 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5640 /* For most processors, ADD is faster than LEA. These alternatives
5641 were added to use ADD as much as possible. */
5642 if (which_alternative == 2 || which_alternative == 4)
5643 std::swap (operands[1], operands[2]);
5645 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5646 if (x86_maybe_negate_const_int (&operands[2], QImode))
5649 return "sub{l}\t{%2, %k0|%k0, %2}";
5651 return "sub{b}\t{%2, %0|%0, %2}";
5654 return "add{l}\t{%k2, %k0|%k0, %k2}";
5656 return "add{b}\t{%2, %0|%0, %2}";
5660 (cond [(eq_attr "alternative" "5")
5661 (const_string "lea")
5662 (match_operand:QI 2 "incdec_operand")
5663 (const_string "incdec")
5665 (const_string "alu")))
5666 (set (attr "length_immediate")
5668 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5670 (const_string "*")))
5671 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5673 (define_insn "*addqi_1_slp"
5674 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5675 (plus:QI (match_dup 0)
5676 (match_operand:QI 1 "general_operand" "qn,qm")))
5677 (clobber (reg:CC FLAGS_REG))]
5678 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5679 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5681 switch (get_attr_type (insn))
5684 if (operands[1] == const1_rtx)
5685 return "inc{b}\t%0";
5688 gcc_assert (operands[1] == constm1_rtx);
5689 return "dec{b}\t%0";
5693 if (x86_maybe_negate_const_int (&operands[1], QImode))
5694 return "sub{b}\t{%1, %0|%0, %1}";
5696 return "add{b}\t{%1, %0|%0, %1}";
5700 (if_then_else (match_operand:QI 1 "incdec_operand")
5701 (const_string "incdec")
5702 (const_string "alu1")))
5703 (set (attr "memory")
5704 (if_then_else (match_operand 1 "memory_operand")
5705 (const_string "load")
5706 (const_string "none")))
5707 (set_attr "mode" "QI")])
5709 ;; Split non destructive adds if we cannot use lea.
5711 [(set (match_operand:SWI48 0 "register_operand")
5712 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5713 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5714 (clobber (reg:CC FLAGS_REG))]
5715 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5716 [(set (match_dup 0) (match_dup 1))
5717 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5718 (clobber (reg:CC FLAGS_REG))])])
5720 ;; Convert add to the lea pattern to avoid flags dependency.
5722 [(set (match_operand:SWI 0 "register_operand")
5723 (plus:SWI (match_operand:SWI 1 "register_operand")
5724 (match_operand:SWI 2 "<nonmemory_operand>")))
5725 (clobber (reg:CC FLAGS_REG))]
5726 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5729 machine_mode mode = <MODE>mode;
5732 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5735 operands[0] = gen_lowpart (mode, operands[0]);
5736 operands[1] = gen_lowpart (mode, operands[1]);
5737 operands[2] = gen_lowpart (mode, operands[2]);
5740 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5742 emit_insn (gen_rtx_SET (operands[0], pat));
5746 ;; Split non destructive adds if we cannot use lea.
5748 [(set (match_operand:DI 0 "register_operand")
5750 (plus:SI (match_operand:SI 1 "register_operand")
5751 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5752 (clobber (reg:CC FLAGS_REG))]
5754 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5755 [(set (match_dup 3) (match_dup 1))
5756 (parallel [(set (match_dup 0)
5757 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5758 (clobber (reg:CC FLAGS_REG))])]
5759 "operands[3] = gen_lowpart (SImode, operands[0]);")
5761 ;; Convert add to the lea pattern to avoid flags dependency.
5763 [(set (match_operand:DI 0 "register_operand")
5765 (plus:SI (match_operand:SI 1 "register_operand")
5766 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5767 (clobber (reg:CC FLAGS_REG))]
5768 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5770 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5772 (define_insn "*add<mode>_2"
5773 [(set (reg FLAGS_REG)
5776 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5777 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5779 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5780 (plus:SWI (match_dup 1) (match_dup 2)))]
5781 "ix86_match_ccmode (insn, CCGOCmode)
5782 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5784 switch (get_attr_type (insn))
5787 if (operands[2] == const1_rtx)
5788 return "inc{<imodesuffix>}\t%0";
5791 gcc_assert (operands[2] == constm1_rtx);
5792 return "dec{<imodesuffix>}\t%0";
5796 if (which_alternative == 2)
5797 std::swap (operands[1], operands[2]);
5799 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5800 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5801 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5803 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5807 (if_then_else (match_operand:SWI 2 "incdec_operand")
5808 (const_string "incdec")
5809 (const_string "alu")))
5810 (set (attr "length_immediate")
5812 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5814 (const_string "*")))
5815 (set_attr "mode" "<MODE>")])
5817 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5818 (define_insn "*addsi_2_zext"
5819 [(set (reg FLAGS_REG)
5821 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5822 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5824 (set (match_operand:DI 0 "register_operand" "=r,r")
5825 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5826 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5827 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5829 switch (get_attr_type (insn))
5832 if (operands[2] == const1_rtx)
5833 return "inc{l}\t%k0";
5836 gcc_assert (operands[2] == constm1_rtx);
5837 return "dec{l}\t%k0";
5841 if (which_alternative == 1)
5842 std::swap (operands[1], operands[2]);
5844 if (x86_maybe_negate_const_int (&operands[2], SImode))
5845 return "sub{l}\t{%2, %k0|%k0, %2}";
5847 return "add{l}\t{%2, %k0|%k0, %2}";
5851 (if_then_else (match_operand:SI 2 "incdec_operand")
5852 (const_string "incdec")
5853 (const_string "alu")))
5854 (set (attr "length_immediate")
5856 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5858 (const_string "*")))
5859 (set_attr "mode" "SI")])
5861 (define_insn "*add<mode>_3"
5862 [(set (reg FLAGS_REG)
5864 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5865 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5866 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5867 "ix86_match_ccmode (insn, CCZmode)
5868 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5870 switch (get_attr_type (insn))
5873 if (operands[2] == const1_rtx)
5874 return "inc{<imodesuffix>}\t%0";
5877 gcc_assert (operands[2] == constm1_rtx);
5878 return "dec{<imodesuffix>}\t%0";
5882 if (which_alternative == 1)
5883 std::swap (operands[1], operands[2]);
5885 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5886 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5887 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5889 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5893 (if_then_else (match_operand:SWI 2 "incdec_operand")
5894 (const_string "incdec")
5895 (const_string "alu")))
5896 (set (attr "length_immediate")
5898 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5900 (const_string "*")))
5901 (set_attr "mode" "<MODE>")])
5903 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5904 (define_insn "*addsi_3_zext"
5905 [(set (reg FLAGS_REG)
5907 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5908 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5909 (set (match_operand:DI 0 "register_operand" "=r,r")
5910 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5911 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5912 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5914 switch (get_attr_type (insn))
5917 if (operands[2] == const1_rtx)
5918 return "inc{l}\t%k0";
5921 gcc_assert (operands[2] == constm1_rtx);
5922 return "dec{l}\t%k0";
5926 if (which_alternative == 1)
5927 std::swap (operands[1], operands[2]);
5929 if (x86_maybe_negate_const_int (&operands[2], SImode))
5930 return "sub{l}\t{%2, %k0|%k0, %2}";
5932 return "add{l}\t{%2, %k0|%k0, %2}";
5936 (if_then_else (match_operand:SI 2 "incdec_operand")
5937 (const_string "incdec")
5938 (const_string "alu")))
5939 (set (attr "length_immediate")
5941 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5943 (const_string "*")))
5944 (set_attr "mode" "SI")])
5946 ; For comparisons against 1, -1 and 128, we may generate better code
5947 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5948 ; is matched then. We can't accept general immediate, because for
5949 ; case of overflows, the result is messed up.
5950 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5951 ; only for comparisons not depending on it.
5953 (define_insn "*adddi_4"
5954 [(set (reg FLAGS_REG)
5956 (match_operand:DI 1 "nonimmediate_operand" "0")
5957 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5958 (clobber (match_scratch:DI 0 "=rm"))]
5960 && ix86_match_ccmode (insn, CCGCmode)"
5962 switch (get_attr_type (insn))
5965 if (operands[2] == constm1_rtx)
5966 return "inc{q}\t%0";
5969 gcc_assert (operands[2] == const1_rtx);
5970 return "dec{q}\t%0";
5974 if (x86_maybe_negate_const_int (&operands[2], DImode))
5975 return "add{q}\t{%2, %0|%0, %2}";
5977 return "sub{q}\t{%2, %0|%0, %2}";
5981 (if_then_else (match_operand:DI 2 "incdec_operand")
5982 (const_string "incdec")
5983 (const_string "alu")))
5984 (set (attr "length_immediate")
5986 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5988 (const_string "*")))
5989 (set_attr "mode" "DI")])
5991 ; For comparisons against 1, -1 and 128, we may generate better code
5992 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5993 ; is matched then. We can't accept general immediate, because for
5994 ; case of overflows, the result is messed up.
5995 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5996 ; only for comparisons not depending on it.
5998 (define_insn "*add<mode>_4"
5999 [(set (reg FLAGS_REG)
6001 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6002 (match_operand:SWI124 2 "const_int_operand" "n")))
6003 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6004 "ix86_match_ccmode (insn, CCGCmode)"
6006 switch (get_attr_type (insn))
6009 if (operands[2] == constm1_rtx)
6010 return "inc{<imodesuffix>}\t%0";
6013 gcc_assert (operands[2] == const1_rtx);
6014 return "dec{<imodesuffix>}\t%0";
6018 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6019 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6021 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6025 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6026 (const_string "incdec")
6027 (const_string "alu")))
6028 (set (attr "length_immediate")
6030 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6032 (const_string "*")))
6033 (set_attr "mode" "<MODE>")])
6035 (define_insn "*add<mode>_5"
6036 [(set (reg FLAGS_REG)
6039 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6040 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6042 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6043 "ix86_match_ccmode (insn, CCGOCmode)
6044 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6046 switch (get_attr_type (insn))
6049 if (operands[2] == const1_rtx)
6050 return "inc{<imodesuffix>}\t%0";
6053 gcc_assert (operands[2] == constm1_rtx);
6054 return "dec{<imodesuffix>}\t%0";
6058 if (which_alternative == 1)
6059 std::swap (operands[1], operands[2]);
6061 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6062 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6063 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6065 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6069 (if_then_else (match_operand:SWI 2 "incdec_operand")
6070 (const_string "incdec")
6071 (const_string "alu")))
6072 (set (attr "length_immediate")
6074 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6076 (const_string "*")))
6077 (set_attr "mode" "<MODE>")])
6079 (define_insn "addqi_ext_1"
6080 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
6085 (match_operand 1 "ext_register_operand" "0,0")
6088 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
6089 (clobber (reg:CC FLAGS_REG))]
6092 switch (get_attr_type (insn))
6095 if (operands[2] == const1_rtx)
6096 return "inc{b}\t%h0";
6099 gcc_assert (operands[2] == constm1_rtx);
6100 return "dec{b}\t%h0";
6104 return "add{b}\t{%2, %h0|%h0, %2}";
6107 [(set_attr "isa" "*,nox64")
6109 (if_then_else (match_operand:QI 2 "incdec_operand")
6110 (const_string "incdec")
6111 (const_string "alu")))
6112 (set_attr "modrm" "1")
6113 (set_attr "mode" "QI")])
6115 (define_insn "*addqi_ext_2"
6116 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6121 (match_operand 1 "ext_register_operand" "%0")
6125 (match_operand 2 "ext_register_operand" "Q")
6128 (clobber (reg:CC FLAGS_REG))]
6130 "add{b}\t{%h2, %h0|%h0, %h2}"
6131 [(set_attr "type" "alu")
6132 (set_attr "mode" "QI")])
6134 ;; Add with jump on overflow.
6135 (define_expand "addv<mode>4"
6136 [(parallel [(set (reg:CCO FLAGS_REG)
6139 (match_operand:SWI 1 "nonimmediate_operand"))
6142 (plus:SWI (match_dup 1)
6143 (match_operand:SWI 2
6144 "<general_operand>")))))
6145 (set (match_operand:SWI 0 "register_operand")
6146 (plus:SWI (match_dup 1) (match_dup 2)))])
6147 (set (pc) (if_then_else
6148 (eq (reg:CCO FLAGS_REG) (const_int 0))
6149 (label_ref (match_operand 3))
6153 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6154 if (CONST_INT_P (operands[2]))
6155 operands[4] = operands[2];
6157 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6160 (define_insn "*addv<mode>4"
6161 [(set (reg:CCO FLAGS_REG)
6164 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6166 (match_operand:SWI 2 "<general_sext_operand>"
6169 (plus:SWI (match_dup 1) (match_dup 2)))))
6170 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6171 (plus:SWI (match_dup 1) (match_dup 2)))]
6172 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6173 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6174 [(set_attr "type" "alu")
6175 (set_attr "mode" "<MODE>")])
6177 (define_insn "*addv<mode>4_1"
6178 [(set (reg:CCO FLAGS_REG)
6181 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6182 (match_operand:<DWI> 3 "const_int_operand" "i"))
6184 (plus:SWI (match_dup 1)
6185 (match_operand:SWI 2 "x86_64_immediate_operand"
6187 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6188 (plus:SWI (match_dup 1) (match_dup 2)))]
6189 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6190 && CONST_INT_P (operands[2])
6191 && INTVAL (operands[2]) == INTVAL (operands[3])"
6192 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6193 [(set_attr "type" "alu")
6194 (set_attr "mode" "<MODE>")
6195 (set (attr "length_immediate")
6196 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6198 (match_test "<MODE_SIZE> == 8")
6200 (const_string "<MODE_SIZE>")))])
6202 (define_expand "uaddv<mode>4"
6203 [(parallel [(set (reg:CCC FLAGS_REG)
6206 (match_operand:SWI 1 "nonimmediate_operand")
6207 (match_operand:SWI 2 "<general_operand>"))
6209 (set (match_operand:SWI 0 "register_operand")
6210 (plus:SWI (match_dup 1) (match_dup 2)))])
6211 (set (pc) (if_then_else
6212 (ltu (reg:CCC FLAGS_REG) (const_int 0))
6213 (label_ref (match_operand 3))
6216 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6218 ;; The lea patterns for modes less than 32 bits need to be matched by
6219 ;; several insns converted to real lea by splitters.
6221 (define_insn_and_split "*lea_general_1"
6222 [(set (match_operand 0 "register_operand" "=r")
6223 (plus (plus (match_operand 1 "index_register_operand" "l")
6224 (match_operand 2 "register_operand" "r"))
6225 (match_operand 3 "immediate_operand" "i")))]
6226 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6227 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6228 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6229 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6230 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6231 || GET_MODE (operands[3]) == VOIDmode)"
6233 "&& reload_completed"
6236 machine_mode mode = SImode;
6239 operands[0] = gen_lowpart (mode, operands[0]);
6240 operands[1] = gen_lowpart (mode, operands[1]);
6241 operands[2] = gen_lowpart (mode, operands[2]);
6242 operands[3] = gen_lowpart (mode, operands[3]);
6244 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6247 emit_insn (gen_rtx_SET (operands[0], pat));
6250 [(set_attr "type" "lea")
6251 (set_attr "mode" "SI")])
6253 (define_insn_and_split "*lea_general_2"
6254 [(set (match_operand 0 "register_operand" "=r")
6255 (plus (mult (match_operand 1 "index_register_operand" "l")
6256 (match_operand 2 "const248_operand" "n"))
6257 (match_operand 3 "nonmemory_operand" "ri")))]
6258 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6259 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6260 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6261 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6262 || GET_MODE (operands[3]) == VOIDmode)"
6264 "&& reload_completed"
6267 machine_mode mode = SImode;
6270 operands[0] = gen_lowpart (mode, operands[0]);
6271 operands[1] = gen_lowpart (mode, operands[1]);
6272 operands[3] = gen_lowpart (mode, operands[3]);
6274 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6277 emit_insn (gen_rtx_SET (operands[0], pat));
6280 [(set_attr "type" "lea")
6281 (set_attr "mode" "SI")])
6283 (define_insn_and_split "*lea_general_3"
6284 [(set (match_operand 0 "register_operand" "=r")
6285 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6286 (match_operand 2 "const248_operand" "n"))
6287 (match_operand 3 "register_operand" "r"))
6288 (match_operand 4 "immediate_operand" "i")))]
6289 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6290 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6291 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6292 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6294 "&& reload_completed"
6297 machine_mode mode = SImode;
6300 operands[0] = gen_lowpart (mode, operands[0]);
6301 operands[1] = gen_lowpart (mode, operands[1]);
6302 operands[3] = gen_lowpart (mode, operands[3]);
6303 operands[4] = gen_lowpart (mode, operands[4]);
6305 pat = gen_rtx_PLUS (mode,
6307 gen_rtx_MULT (mode, operands[1],
6312 emit_insn (gen_rtx_SET (operands[0], pat));
6315 [(set_attr "type" "lea")
6316 (set_attr "mode" "SI")])
6318 (define_insn_and_split "*lea_general_4"
6319 [(set (match_operand 0 "register_operand" "=r")
6321 (match_operand 1 "index_register_operand" "l")
6322 (match_operand 2 "const_int_operand" "n"))
6323 (match_operand 3 "const_int_operand" "n")))]
6324 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6325 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6326 || GET_MODE (operands[0]) == SImode
6327 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6328 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6329 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6330 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6331 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6333 "&& reload_completed"
6336 machine_mode mode = GET_MODE (operands[0]);
6339 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6342 operands[0] = gen_lowpart (mode, operands[0]);
6343 operands[1] = gen_lowpart (mode, operands[1]);
6346 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6348 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6349 INTVAL (operands[3]));
6351 emit_insn (gen_rtx_SET (operands[0], pat));
6354 [(set_attr "type" "lea")
6356 (if_then_else (match_operand:DI 0)
6358 (const_string "SI")))])
6360 ;; Subtract instructions
6362 (define_expand "sub<mode>3"
6363 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6364 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6365 (match_operand:SDWIM 2 "<general_operand>")))]
6367 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6369 (define_insn_and_split "*sub<dwi>3_doubleword"
6370 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6372 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6373 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6374 (clobber (reg:CC FLAGS_REG))]
6375 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6378 [(parallel [(set (reg:CC FLAGS_REG)
6379 (compare:CC (match_dup 1) (match_dup 2)))
6381 (minus:DWIH (match_dup 1) (match_dup 2)))])
6382 (parallel [(set (match_dup 3)
6386 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6388 (clobber (reg:CC FLAGS_REG))])]
6390 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6391 if (operands[2] == const0_rtx)
6393 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6398 (define_insn "*sub<mode>_1"
6399 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6401 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6402 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6403 (clobber (reg:CC FLAGS_REG))]
6404 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6405 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6406 [(set_attr "type" "alu")
6407 (set_attr "mode" "<MODE>")])
6409 (define_insn "*subsi_1_zext"
6410 [(set (match_operand:DI 0 "register_operand" "=r")
6412 (minus:SI (match_operand:SI 1 "register_operand" "0")
6413 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6414 (clobber (reg:CC FLAGS_REG))]
6415 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6416 "sub{l}\t{%2, %k0|%k0, %2}"
6417 [(set_attr "type" "alu")
6418 (set_attr "mode" "SI")])
6420 (define_insn "*subqi_1_slp"
6421 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6422 (minus:QI (match_dup 0)
6423 (match_operand:QI 1 "general_operand" "qn,qm")))
6424 (clobber (reg:CC FLAGS_REG))]
6425 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6426 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6427 "sub{b}\t{%1, %0|%0, %1}"
6428 [(set_attr "type" "alu1")
6429 (set_attr "mode" "QI")])
6431 (define_insn "*sub<mode>_2"
6432 [(set (reg FLAGS_REG)
6435 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6436 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6438 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6439 (minus:SWI (match_dup 1) (match_dup 2)))]
6440 "ix86_match_ccmode (insn, CCGOCmode)
6441 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6442 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6443 [(set_attr "type" "alu")
6444 (set_attr "mode" "<MODE>")])
6446 (define_insn "*subsi_2_zext"
6447 [(set (reg FLAGS_REG)
6449 (minus:SI (match_operand:SI 1 "register_operand" "0")
6450 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6452 (set (match_operand:DI 0 "register_operand" "=r")
6454 (minus:SI (match_dup 1)
6456 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6457 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6458 "sub{l}\t{%2, %k0|%k0, %2}"
6459 [(set_attr "type" "alu")
6460 (set_attr "mode" "SI")])
6462 ;; Subtract with jump on overflow.
6463 (define_expand "subv<mode>4"
6464 [(parallel [(set (reg:CCO FLAGS_REG)
6465 (eq:CCO (minus:<DWI>
6467 (match_operand:SWI 1 "nonimmediate_operand"))
6470 (minus:SWI (match_dup 1)
6471 (match_operand:SWI 2
6472 "<general_operand>")))))
6473 (set (match_operand:SWI 0 "register_operand")
6474 (minus:SWI (match_dup 1) (match_dup 2)))])
6475 (set (pc) (if_then_else
6476 (eq (reg:CCO FLAGS_REG) (const_int 0))
6477 (label_ref (match_operand 3))
6481 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6482 if (CONST_INT_P (operands[2]))
6483 operands[4] = operands[2];
6485 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6488 (define_insn "*subv<mode>4"
6489 [(set (reg:CCO FLAGS_REG)
6490 (eq:CCO (minus:<DWI>
6492 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6494 (match_operand:SWI 2 "<general_sext_operand>"
6497 (minus:SWI (match_dup 1) (match_dup 2)))))
6498 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6499 (minus:SWI (match_dup 1) (match_dup 2)))]
6500 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6501 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6502 [(set_attr "type" "alu")
6503 (set_attr "mode" "<MODE>")])
6505 (define_insn "*subv<mode>4_1"
6506 [(set (reg:CCO FLAGS_REG)
6507 (eq:CCO (minus:<DWI>
6509 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6510 (match_operand:<DWI> 3 "const_int_operand" "i"))
6512 (minus:SWI (match_dup 1)
6513 (match_operand:SWI 2 "x86_64_immediate_operand"
6515 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6516 (minus:SWI (match_dup 1) (match_dup 2)))]
6517 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6518 && CONST_INT_P (operands[2])
6519 && INTVAL (operands[2]) == INTVAL (operands[3])"
6520 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6521 [(set_attr "type" "alu")
6522 (set_attr "mode" "<MODE>")
6523 (set (attr "length_immediate")
6524 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6526 (match_test "<MODE_SIZE> == 8")
6528 (const_string "<MODE_SIZE>")))])
6530 (define_expand "usubv<mode>4"
6531 [(parallel [(set (reg:CC FLAGS_REG)
6533 (match_operand:SWI 1 "nonimmediate_operand")
6534 (match_operand:SWI 2 "<general_operand>")))
6535 (set (match_operand:SWI 0 "register_operand")
6536 (minus:SWI (match_dup 1) (match_dup 2)))])
6537 (set (pc) (if_then_else
6538 (ltu (reg:CC FLAGS_REG) (const_int 0))
6539 (label_ref (match_operand 3))
6542 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6544 (define_insn "*sub<mode>_3"
6545 [(set (reg FLAGS_REG)
6546 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6547 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6548 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6549 (minus:SWI (match_dup 1) (match_dup 2)))]
6550 "ix86_match_ccmode (insn, CCmode)
6551 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6552 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6553 [(set_attr "type" "alu")
6554 (set_attr "mode" "<MODE>")])
6556 (define_insn "*subsi_3_zext"
6557 [(set (reg FLAGS_REG)
6558 (compare (match_operand:SI 1 "register_operand" "0")
6559 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6560 (set (match_operand:DI 0 "register_operand" "=r")
6562 (minus:SI (match_dup 1)
6564 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6565 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6566 "sub{l}\t{%2, %1|%1, %2}"
6567 [(set_attr "type" "alu")
6568 (set_attr "mode" "SI")])
6570 ;; Add with carry and subtract with borrow
6572 (define_insn "add<mode>3_carry"
6573 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6576 (match_operator:SWI 4 "ix86_carry_flag_operator"
6577 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6578 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6579 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6580 (clobber (reg:CC FLAGS_REG))]
6581 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6582 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6583 [(set_attr "type" "alu")
6584 (set_attr "use_carry" "1")
6585 (set_attr "pent_pair" "pu")
6586 (set_attr "mode" "<MODE>")])
6588 (define_insn "*addsi3_carry_zext"
6589 [(set (match_operand:DI 0 "register_operand" "=r")
6592 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6593 [(reg FLAGS_REG) (const_int 0)])
6594 (match_operand:SI 1 "register_operand" "%0"))
6595 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6596 (clobber (reg:CC FLAGS_REG))]
6597 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6598 "adc{l}\t{%2, %k0|%k0, %2}"
6599 [(set_attr "type" "alu")
6600 (set_attr "use_carry" "1")
6601 (set_attr "pent_pair" "pu")
6602 (set_attr "mode" "SI")])
6604 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6606 (define_insn "addcarry<mode>"
6607 [(set (reg:CCC FLAGS_REG)
6611 (match_operator:SWI48 4 "ix86_carry_flag_operator"
6612 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6613 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6614 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))
6616 (set (match_operand:SWI48 0 "register_operand" "=r")
6617 (plus:SWI48 (plus:SWI48 (match_op_dup 4
6618 [(match_dup 3) (const_int 0)])
6621 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6622 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6623 [(set_attr "type" "alu")
6624 (set_attr "use_carry" "1")
6625 (set_attr "pent_pair" "pu")
6626 (set_attr "mode" "<MODE>")])
6628 (define_insn "sub<mode>3_carry"
6629 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6632 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6633 (match_operator:SWI 4 "ix86_carry_flag_operator"
6634 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6635 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6636 (clobber (reg:CC FLAGS_REG))]
6637 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6638 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6639 [(set_attr "type" "alu")
6640 (set_attr "use_carry" "1")
6641 (set_attr "pent_pair" "pu")
6642 (set_attr "mode" "<MODE>")])
6644 (define_insn "*subsi3_carry_zext"
6645 [(set (match_operand:DI 0 "register_operand" "=r")
6649 (match_operand:SI 1 "register_operand" "0")
6650 (match_operator:SI 3 "ix86_carry_flag_operator"
6651 [(reg FLAGS_REG) (const_int 0)]))
6652 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6653 (clobber (reg:CC FLAGS_REG))]
6654 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6655 "sbb{l}\t{%2, %k0|%k0, %2}"
6656 [(set_attr "type" "alu")
6657 (set_attr "use_carry" "1")
6658 (set_attr "pent_pair" "pu")
6659 (set_attr "mode" "SI")])
6661 (define_insn "subborrow<mode>"
6662 [(set (reg:CCC FLAGS_REG)
6664 (match_operand:SWI48 1 "nonimmediate_operand" "0")
6666 (match_operator:SWI48 4 "ix86_carry_flag_operator"
6667 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6668 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
6669 (set (match_operand:SWI48 0 "register_operand" "=r")
6670 (minus:SWI48 (minus:SWI48 (match_dup 1)
6672 [(match_dup 3) (const_int 0)]))
6674 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6675 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6676 [(set_attr "type" "alu")
6677 (set_attr "use_carry" "1")
6678 (set_attr "pent_pair" "pu")
6679 (set_attr "mode" "<MODE>")])
6681 ;; Overflow setting add instructions
6683 (define_expand "addqi3_cconly_overflow"
6685 [(set (reg:CCC FLAGS_REG)
6688 (match_operand:QI 0 "nonimmediate_operand")
6689 (match_operand:QI 1 "general_operand"))
6691 (clobber (match_scratch:QI 2))])]
6692 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
6694 (define_insn "*add<mode>3_cconly_overflow_1"
6695 [(set (reg:CCC FLAGS_REG)
6698 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6699 (match_operand:SWI 2 "<general_operand>" "<g>"))
6701 (clobber (match_scratch:SWI 0 "=<r>"))]
6702 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6703 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6704 [(set_attr "type" "alu")
6705 (set_attr "mode" "<MODE>")])
6707 (define_insn "*add<mode>3_cconly_overflow_2"
6708 [(set (reg:CCC FLAGS_REG)
6711 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6712 (match_operand:SWI 2 "<general_operand>" "<g>"))
6714 (clobber (match_scratch:SWI 0 "=<r>"))]
6715 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6716 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6717 [(set_attr "type" "alu")
6718 (set_attr "mode" "<MODE>")])
6720 (define_insn "*add<mode>3_cc_overflow_1"
6721 [(set (reg:CCC FLAGS_REG)
6724 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6725 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6727 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6728 (plus:SWI (match_dup 1) (match_dup 2)))]
6729 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6730 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6731 [(set_attr "type" "alu")
6732 (set_attr "mode" "<MODE>")])
6734 (define_insn "*add<mode>3_cc_overflow_2"
6735 [(set (reg:CCC FLAGS_REG)
6738 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6739 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6741 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6742 (plus:SWI (match_dup 1) (match_dup 2)))]
6743 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6744 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6745 [(set_attr "type" "alu")
6746 (set_attr "mode" "<MODE>")])
6748 (define_insn "*addsi3_zext_cc_overflow_1"
6749 [(set (reg:CCC FLAGS_REG)
6752 (match_operand:SI 1 "nonimmediate_operand" "%0")
6753 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6755 (set (match_operand:DI 0 "register_operand" "=r")
6756 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6757 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6758 "add{l}\t{%2, %k0|%k0, %2}"
6759 [(set_attr "type" "alu")
6760 (set_attr "mode" "SI")])
6762 (define_insn "*addsi3_zext_cc_overflow_2"
6763 [(set (reg:CCC FLAGS_REG)
6766 (match_operand:SI 1 "nonimmediate_operand" "%0")
6767 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6769 (set (match_operand:DI 0 "register_operand" "=r")
6770 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6771 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6772 "add{l}\t{%2, %k0|%k0, %2}"
6773 [(set_attr "type" "alu")
6774 (set_attr "mode" "SI")])
6776 ;; The patterns that match these are at the end of this file.
6778 (define_expand "<plusminus_insn>xf3"
6779 [(set (match_operand:XF 0 "register_operand")
6781 (match_operand:XF 1 "register_operand")
6782 (match_operand:XF 2 "register_operand")))]
6785 (define_expand "<plusminus_insn><mode>3"
6786 [(set (match_operand:MODEF 0 "register_operand")
6788 (match_operand:MODEF 1 "register_operand")
6789 (match_operand:MODEF 2 "nonimmediate_operand")))]
6790 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6791 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6793 ;; Multiply instructions
6795 (define_expand "mul<mode>3"
6796 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6798 (match_operand:SWIM248 1 "register_operand")
6799 (match_operand:SWIM248 2 "<general_operand>")))
6800 (clobber (reg:CC FLAGS_REG))])])
6802 (define_expand "mulqi3"
6803 [(parallel [(set (match_operand:QI 0 "register_operand")
6805 (match_operand:QI 1 "register_operand")
6806 (match_operand:QI 2 "nonimmediate_operand")))
6807 (clobber (reg:CC FLAGS_REG))])]
6808 "TARGET_QIMODE_MATH")
6811 ;; IMUL reg32/64, reg32/64, imm8 Direct
6812 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6813 ;; IMUL reg32/64, reg32/64, imm32 Direct
6814 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6815 ;; IMUL reg32/64, reg32/64 Direct
6816 ;; IMUL reg32/64, mem32/64 Direct
6818 ;; On BDVER1, all above IMULs use DirectPath
6821 ;; IMUL reg16, reg16, imm8 VectorPath
6822 ;; IMUL reg16, mem16, imm8 VectorPath
6823 ;; IMUL reg16, reg16, imm16 VectorPath
6824 ;; IMUL reg16, mem16, imm16 VectorPath
6825 ;; IMUL reg16, reg16 Direct
6826 ;; IMUL reg16, mem16 Direct
6828 ;; On BDVER1, all HI MULs use DoublePath
6830 (define_insn "*mul<mode>3_1"
6831 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
6833 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
6834 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
6835 (clobber (reg:CC FLAGS_REG))]
6836 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6838 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6839 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6840 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6841 [(set_attr "type" "imul")
6842 (set_attr "prefix_0f" "0,0,1")
6843 (set (attr "athlon_decode")
6844 (cond [(eq_attr "cpu" "athlon")
6845 (const_string "vector")
6846 (eq_attr "alternative" "1")
6847 (const_string "vector")
6848 (and (eq_attr "alternative" "2")
6849 (ior (match_test "<MODE>mode == HImode")
6850 (match_operand 1 "memory_operand")))
6851 (const_string "vector")]
6852 (const_string "direct")))
6853 (set (attr "amdfam10_decode")
6854 (cond [(and (eq_attr "alternative" "0,1")
6855 (ior (match_test "<MODE>mode == HImode")
6856 (match_operand 1 "memory_operand")))
6857 (const_string "vector")]
6858 (const_string "direct")))
6859 (set (attr "bdver1_decode")
6861 (match_test "<MODE>mode == HImode")
6862 (const_string "double")
6863 (const_string "direct")))
6864 (set_attr "mode" "<MODE>")])
6866 (define_insn "*mulsi3_1_zext"
6867 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6869 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6870 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6871 (clobber (reg:CC FLAGS_REG))]
6873 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6875 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6876 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6877 imul{l}\t{%2, %k0|%k0, %2}"
6878 [(set_attr "type" "imul")
6879 (set_attr "prefix_0f" "0,0,1")
6880 (set (attr "athlon_decode")
6881 (cond [(eq_attr "cpu" "athlon")
6882 (const_string "vector")
6883 (eq_attr "alternative" "1")
6884 (const_string "vector")
6885 (and (eq_attr "alternative" "2")
6886 (match_operand 1 "memory_operand"))
6887 (const_string "vector")]
6888 (const_string "direct")))
6889 (set (attr "amdfam10_decode")
6890 (cond [(and (eq_attr "alternative" "0,1")
6891 (match_operand 1 "memory_operand"))
6892 (const_string "vector")]
6893 (const_string "direct")))
6894 (set_attr "bdver1_decode" "direct")
6895 (set_attr "mode" "SI")])
6897 ;;On AMDFAM10 and BDVER1
6901 (define_insn "*mulqi3_1"
6902 [(set (match_operand:QI 0 "register_operand" "=a")
6903 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6904 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6905 (clobber (reg:CC FLAGS_REG))]
6907 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6909 [(set_attr "type" "imul")
6910 (set_attr "length_immediate" "0")
6911 (set (attr "athlon_decode")
6912 (if_then_else (eq_attr "cpu" "athlon")
6913 (const_string "vector")
6914 (const_string "direct")))
6915 (set_attr "amdfam10_decode" "direct")
6916 (set_attr "bdver1_decode" "direct")
6917 (set_attr "mode" "QI")])
6919 ;; Multiply with jump on overflow.
6920 (define_expand "mulv<mode>4"
6921 [(parallel [(set (reg:CCO FLAGS_REG)
6924 (match_operand:SWI248 1 "register_operand"))
6927 (mult:SWI248 (match_dup 1)
6928 (match_operand:SWI248 2
6929 "<general_operand>")))))
6930 (set (match_operand:SWI248 0 "register_operand")
6931 (mult:SWI248 (match_dup 1) (match_dup 2)))])
6932 (set (pc) (if_then_else
6933 (eq (reg:CCO FLAGS_REG) (const_int 0))
6934 (label_ref (match_operand 3))
6938 if (CONST_INT_P (operands[2]))
6939 operands[4] = operands[2];
6941 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6944 (define_insn "*mulv<mode>4"
6945 [(set (reg:CCO FLAGS_REG)
6948 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6950 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
6952 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6953 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6954 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6955 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6957 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6958 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6959 [(set_attr "type" "imul")
6960 (set_attr "prefix_0f" "0,1")
6961 (set (attr "athlon_decode")
6962 (cond [(eq_attr "cpu" "athlon")
6963 (const_string "vector")
6964 (eq_attr "alternative" "0")
6965 (const_string "vector")
6966 (and (eq_attr "alternative" "1")
6967 (match_operand 1 "memory_operand"))
6968 (const_string "vector")]
6969 (const_string "direct")))
6970 (set (attr "amdfam10_decode")
6971 (cond [(and (eq_attr "alternative" "1")
6972 (match_operand 1 "memory_operand"))
6973 (const_string "vector")]
6974 (const_string "direct")))
6975 (set_attr "bdver1_decode" "direct")
6976 (set_attr "mode" "<MODE>")])
6978 (define_insn "*mulvhi4"
6979 [(set (reg:CCO FLAGS_REG)
6982 (match_operand:HI 1 "nonimmediate_operand" "%0"))
6984 (match_operand:HI 2 "nonimmediate_operand" "mr")))
6986 (mult:HI (match_dup 1) (match_dup 2)))))
6987 (set (match_operand:HI 0 "register_operand" "=r")
6988 (mult:HI (match_dup 1) (match_dup 2)))]
6989 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6990 "imul{w}\t{%2, %0|%0, %2}"
6991 [(set_attr "type" "imul")
6992 (set_attr "prefix_0f" "1")
6993 (set_attr "athlon_decode" "vector")
6994 (set_attr "amdfam10_decode" "direct")
6995 (set_attr "bdver1_decode" "double")
6996 (set_attr "mode" "HI")])
6998 (define_insn "*mulv<mode>4_1"
6999 [(set (reg:CCO FLAGS_REG)
7002 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7003 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7005 (mult:SWI248 (match_dup 1)
7006 (match_operand:SWI248 2
7007 "<immediate_operand>" "K,<i>")))))
7008 (set (match_operand:SWI248 0 "register_operand" "=r,r")
7009 (mult:SWI248 (match_dup 1) (match_dup 2)))]
7010 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7011 && CONST_INT_P (operands[2])
7012 && INTVAL (operands[2]) == INTVAL (operands[3])"
7013 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7014 [(set_attr "type" "imul")
7015 (set (attr "prefix_0f")
7017 (match_test "<MODE>mode == HImode")
7019 (const_string "*")))
7020 (set (attr "athlon_decode")
7021 (cond [(eq_attr "cpu" "athlon")
7022 (const_string "vector")
7023 (eq_attr "alternative" "1")
7024 (const_string "vector")]
7025 (const_string "direct")))
7026 (set (attr "amdfam10_decode")
7027 (cond [(ior (match_test "<MODE>mode == HImode")
7028 (match_operand 1 "memory_operand"))
7029 (const_string "vector")]
7030 (const_string "direct")))
7031 (set (attr "bdver1_decode")
7033 (match_test "<MODE>mode == HImode")
7034 (const_string "double")
7035 (const_string "direct")))
7036 (set_attr "mode" "<MODE>")
7037 (set (attr "length_immediate")
7038 (cond [(eq_attr "alternative" "0")
7040 (match_test "<MODE_SIZE> == 8")
7042 (const_string "<MODE_SIZE>")))])
7044 (define_expand "umulv<mode>4"
7045 [(parallel [(set (reg:CCO FLAGS_REG)
7048 (match_operand:SWI248 1
7049 "nonimmediate_operand"))
7051 (match_operand:SWI248 2
7052 "nonimmediate_operand")))
7054 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7055 (set (match_operand:SWI248 0 "register_operand")
7056 (mult:SWI248 (match_dup 1) (match_dup 2)))
7057 (clobber (match_scratch:SWI248 4))])
7058 (set (pc) (if_then_else
7059 (eq (reg:CCO FLAGS_REG) (const_int 0))
7060 (label_ref (match_operand 3))
7064 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7065 operands[1] = force_reg (<MODE>mode, operands[1]);
7068 (define_insn "*umulv<mode>4"
7069 [(set (reg:CCO FLAGS_REG)
7072 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7074 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7076 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7077 (set (match_operand:SWI248 0 "register_operand" "=a")
7078 (mult:SWI248 (match_dup 1) (match_dup 2)))
7079 (clobber (match_scratch:SWI248 3 "=d"))]
7080 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7081 "mul{<imodesuffix>}\t%2"
7082 [(set_attr "type" "imul")
7083 (set_attr "length_immediate" "0")
7084 (set (attr "athlon_decode")
7085 (if_then_else (eq_attr "cpu" "athlon")
7086 (const_string "vector")
7087 (const_string "double")))
7088 (set_attr "amdfam10_decode" "double")
7089 (set_attr "bdver1_decode" "direct")
7090 (set_attr "mode" "<MODE>")])
7092 (define_expand "<u>mulvqi4"
7093 [(parallel [(set (reg:CCO FLAGS_REG)
7096 (match_operand:QI 1 "nonimmediate_operand"))
7098 (match_operand:QI 2 "nonimmediate_operand")))
7100 (mult:QI (match_dup 1) (match_dup 2)))))
7101 (set (match_operand:QI 0 "register_operand")
7102 (mult:QI (match_dup 1) (match_dup 2)))])
7103 (set (pc) (if_then_else
7104 (eq (reg:CCO FLAGS_REG) (const_int 0))
7105 (label_ref (match_operand 3))
7107 "TARGET_QIMODE_MATH"
7109 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7110 operands[1] = force_reg (QImode, operands[1]);
7113 (define_insn "*<u>mulvqi4"
7114 [(set (reg:CCO FLAGS_REG)
7117 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7119 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7121 (mult:QI (match_dup 1) (match_dup 2)))))
7122 (set (match_operand:QI 0 "register_operand" "=a")
7123 (mult:QI (match_dup 1) (match_dup 2)))]
7125 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7126 "<sgnprefix>mul{b}\t%2"
7127 [(set_attr "type" "imul")
7128 (set_attr "length_immediate" "0")
7129 (set (attr "athlon_decode")
7130 (if_then_else (eq_attr "cpu" "athlon")
7131 (const_string "vector")
7132 (const_string "direct")))
7133 (set_attr "amdfam10_decode" "direct")
7134 (set_attr "bdver1_decode" "direct")
7135 (set_attr "mode" "QI")])
7137 (define_expand "<u>mul<mode><dwi>3"
7138 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7141 (match_operand:DWIH 1 "nonimmediate_operand"))
7143 (match_operand:DWIH 2 "register_operand"))))
7144 (clobber (reg:CC FLAGS_REG))])])
7146 (define_expand "<u>mulqihi3"
7147 [(parallel [(set (match_operand:HI 0 "register_operand")
7150 (match_operand:QI 1 "nonimmediate_operand"))
7152 (match_operand:QI 2 "register_operand"))))
7153 (clobber (reg:CC FLAGS_REG))])]
7154 "TARGET_QIMODE_MATH")
7156 (define_insn "*bmi2_umul<mode><dwi>3_1"
7157 [(set (match_operand:DWIH 0 "register_operand" "=r")
7159 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7160 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7161 (set (match_operand:DWIH 1 "register_operand" "=r")
7164 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7165 (zero_extend:<DWI> (match_dup 3)))
7166 (match_operand:QI 4 "const_int_operand" "n"))))]
7167 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7168 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7169 "mulx\t{%3, %0, %1|%1, %0, %3}"
7170 [(set_attr "type" "imulx")
7171 (set_attr "prefix" "vex")
7172 (set_attr "mode" "<MODE>")])
7174 (define_insn "*umul<mode><dwi>3_1"
7175 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7178 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7180 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7181 (clobber (reg:CC FLAGS_REG))]
7182 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7185 mul{<imodesuffix>}\t%2"
7186 [(set_attr "isa" "bmi2,*")
7187 (set_attr "type" "imulx,imul")
7188 (set_attr "length_immediate" "*,0")
7189 (set (attr "athlon_decode")
7190 (cond [(eq_attr "alternative" "1")
7191 (if_then_else (eq_attr "cpu" "athlon")
7192 (const_string "vector")
7193 (const_string "double"))]
7194 (const_string "*")))
7195 (set_attr "amdfam10_decode" "*,double")
7196 (set_attr "bdver1_decode" "*,direct")
7197 (set_attr "prefix" "vex,orig")
7198 (set_attr "mode" "<MODE>")])
7200 ;; Convert mul to the mulx pattern to avoid flags dependency.
7202 [(set (match_operand:<DWI> 0 "register_operand")
7205 (match_operand:DWIH 1 "register_operand"))
7207 (match_operand:DWIH 2 "nonimmediate_operand"))))
7208 (clobber (reg:CC FLAGS_REG))]
7209 "TARGET_BMI2 && reload_completed
7210 && true_regnum (operands[1]) == DX_REG"
7211 [(parallel [(set (match_dup 3)
7212 (mult:DWIH (match_dup 1) (match_dup 2)))
7216 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7217 (zero_extend:<DWI> (match_dup 2)))
7220 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7222 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7225 (define_insn "*mul<mode><dwi>3_1"
7226 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7229 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7231 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7232 (clobber (reg:CC FLAGS_REG))]
7233 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7234 "imul{<imodesuffix>}\t%2"
7235 [(set_attr "type" "imul")
7236 (set_attr "length_immediate" "0")
7237 (set (attr "athlon_decode")
7238 (if_then_else (eq_attr "cpu" "athlon")
7239 (const_string "vector")
7240 (const_string "double")))
7241 (set_attr "amdfam10_decode" "double")
7242 (set_attr "bdver1_decode" "direct")
7243 (set_attr "mode" "<MODE>")])
7245 (define_insn "*<u>mulqihi3_1"
7246 [(set (match_operand:HI 0 "register_operand" "=a")
7249 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7251 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7252 (clobber (reg:CC FLAGS_REG))]
7254 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7255 "<sgnprefix>mul{b}\t%2"
7256 [(set_attr "type" "imul")
7257 (set_attr "length_immediate" "0")
7258 (set (attr "athlon_decode")
7259 (if_then_else (eq_attr "cpu" "athlon")
7260 (const_string "vector")
7261 (const_string "direct")))
7262 (set_attr "amdfam10_decode" "direct")
7263 (set_attr "bdver1_decode" "direct")
7264 (set_attr "mode" "QI")])
7266 (define_expand "<s>mul<mode>3_highpart"
7267 [(parallel [(set (match_operand:SWI48 0 "register_operand")
7272 (match_operand:SWI48 1 "nonimmediate_operand"))
7274 (match_operand:SWI48 2 "register_operand")))
7276 (clobber (match_scratch:SWI48 3))
7277 (clobber (reg:CC FLAGS_REG))])]
7279 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7281 (define_insn "*<s>muldi3_highpart_1"
7282 [(set (match_operand:DI 0 "register_operand" "=d")
7287 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7289 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7291 (clobber (match_scratch:DI 3 "=1"))
7292 (clobber (reg:CC FLAGS_REG))]
7294 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7295 "<sgnprefix>mul{q}\t%2"
7296 [(set_attr "type" "imul")
7297 (set_attr "length_immediate" "0")
7298 (set (attr "athlon_decode")
7299 (if_then_else (eq_attr "cpu" "athlon")
7300 (const_string "vector")
7301 (const_string "double")))
7302 (set_attr "amdfam10_decode" "double")
7303 (set_attr "bdver1_decode" "direct")
7304 (set_attr "mode" "DI")])
7306 (define_insn "*<s>mulsi3_highpart_1"
7307 [(set (match_operand:SI 0 "register_operand" "=d")
7312 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7314 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7316 (clobber (match_scratch:SI 3 "=1"))
7317 (clobber (reg:CC FLAGS_REG))]
7318 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7319 "<sgnprefix>mul{l}\t%2"
7320 [(set_attr "type" "imul")
7321 (set_attr "length_immediate" "0")
7322 (set (attr "athlon_decode")
7323 (if_then_else (eq_attr "cpu" "athlon")
7324 (const_string "vector")
7325 (const_string "double")))
7326 (set_attr "amdfam10_decode" "double")
7327 (set_attr "bdver1_decode" "direct")
7328 (set_attr "mode" "SI")])
7330 (define_insn "*<s>mulsi3_highpart_zext"
7331 [(set (match_operand:DI 0 "register_operand" "=d")
7332 (zero_extend:DI (truncate:SI
7334 (mult:DI (any_extend:DI
7335 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7337 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7339 (clobber (match_scratch:SI 3 "=1"))
7340 (clobber (reg:CC FLAGS_REG))]
7342 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7343 "<sgnprefix>mul{l}\t%2"
7344 [(set_attr "type" "imul")
7345 (set_attr "length_immediate" "0")
7346 (set (attr "athlon_decode")
7347 (if_then_else (eq_attr "cpu" "athlon")
7348 (const_string "vector")
7349 (const_string "double")))
7350 (set_attr "amdfam10_decode" "double")
7351 (set_attr "bdver1_decode" "direct")
7352 (set_attr "mode" "SI")])
7354 ;; The patterns that match these are at the end of this file.
7356 (define_expand "mulxf3"
7357 [(set (match_operand:XF 0 "register_operand")
7358 (mult:XF (match_operand:XF 1 "register_operand")
7359 (match_operand:XF 2 "register_operand")))]
7362 (define_expand "mul<mode>3"
7363 [(set (match_operand:MODEF 0 "register_operand")
7364 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7365 (match_operand:MODEF 2 "nonimmediate_operand")))]
7366 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7367 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7369 ;; Divide instructions
7371 ;; The patterns that match these are at the end of this file.
7373 (define_expand "divxf3"
7374 [(set (match_operand:XF 0 "register_operand")
7375 (div:XF (match_operand:XF 1 "register_operand")
7376 (match_operand:XF 2 "register_operand")))]
7379 (define_expand "divdf3"
7380 [(set (match_operand:DF 0 "register_operand")
7381 (div:DF (match_operand:DF 1 "register_operand")
7382 (match_operand:DF 2 "nonimmediate_operand")))]
7383 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7384 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7386 (define_expand "divsf3"
7387 [(set (match_operand:SF 0 "register_operand")
7388 (div:SF (match_operand:SF 1 "register_operand")
7389 (match_operand:SF 2 "nonimmediate_operand")))]
7390 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7395 && optimize_insn_for_speed_p ()
7396 && flag_finite_math_only && !flag_trapping_math
7397 && flag_unsafe_math_optimizations)
7399 ix86_emit_swdivsf (operands[0], operands[1],
7400 operands[2], SFmode);
7405 ;; Divmod instructions.
7407 (define_expand "divmod<mode>4"
7408 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7410 (match_operand:SWIM248 1 "register_operand")
7411 (match_operand:SWIM248 2 "nonimmediate_operand")))
7412 (set (match_operand:SWIM248 3 "register_operand")
7413 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7414 (clobber (reg:CC FLAGS_REG))])])
7416 ;; Split with 8bit unsigned divide:
7417 ;; if (dividend an divisor are in [0-255])
7418 ;; use 8bit unsigned integer divide
7420 ;; use original integer divide
7422 [(set (match_operand:SWI48 0 "register_operand")
7423 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7424 (match_operand:SWI48 3 "nonimmediate_operand")))
7425 (set (match_operand:SWI48 1 "register_operand")
7426 (mod:SWI48 (match_dup 2) (match_dup 3)))
7427 (clobber (reg:CC FLAGS_REG))]
7428 "TARGET_USE_8BIT_IDIV
7429 && TARGET_QIMODE_MATH
7430 && can_create_pseudo_p ()
7431 && !optimize_insn_for_size_p ()"
7433 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7435 (define_insn_and_split "divmod<mode>4_1"
7436 [(set (match_operand:SWI48 0 "register_operand" "=a")
7437 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7438 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7439 (set (match_operand:SWI48 1 "register_operand" "=&d")
7440 (mod:SWI48 (match_dup 2) (match_dup 3)))
7441 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7442 (clobber (reg:CC FLAGS_REG))]
7446 [(parallel [(set (match_dup 1)
7447 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7448 (clobber (reg:CC FLAGS_REG))])
7449 (parallel [(set (match_dup 0)
7450 (div:SWI48 (match_dup 2) (match_dup 3)))
7452 (mod:SWI48 (match_dup 2) (match_dup 3)))
7454 (clobber (reg:CC FLAGS_REG))])]
7456 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7458 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7459 operands[4] = operands[2];
7462 /* Avoid use of cltd in favor of a mov+shift. */
7463 emit_move_insn (operands[1], operands[2]);
7464 operands[4] = operands[1];
7467 [(set_attr "type" "multi")
7468 (set_attr "mode" "<MODE>")])
7470 (define_insn_and_split "*divmod<mode>4"
7471 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7472 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7473 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7474 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7475 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7476 (clobber (reg:CC FLAGS_REG))]
7480 [(parallel [(set (match_dup 1)
7481 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7482 (clobber (reg:CC FLAGS_REG))])
7483 (parallel [(set (match_dup 0)
7484 (div:SWIM248 (match_dup 2) (match_dup 3)))
7486 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7488 (clobber (reg:CC FLAGS_REG))])]
7490 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7492 if (<MODE>mode != HImode
7493 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7494 operands[4] = operands[2];
7497 /* Avoid use of cltd in favor of a mov+shift. */
7498 emit_move_insn (operands[1], operands[2]);
7499 operands[4] = operands[1];
7502 [(set_attr "type" "multi")
7503 (set_attr "mode" "<MODE>")])
7505 (define_insn "*divmod<mode>4_noext"
7506 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7507 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7508 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7509 (set (match_operand:SWIM248 1 "register_operand" "=d")
7510 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7511 (use (match_operand:SWIM248 4 "register_operand" "1"))
7512 (clobber (reg:CC FLAGS_REG))]
7514 "idiv{<imodesuffix>}\t%3"
7515 [(set_attr "type" "idiv")
7516 (set_attr "mode" "<MODE>")])
7518 (define_expand "divmodqi4"
7519 [(parallel [(set (match_operand:QI 0 "register_operand")
7521 (match_operand:QI 1 "register_operand")
7522 (match_operand:QI 2 "nonimmediate_operand")))
7523 (set (match_operand:QI 3 "register_operand")
7524 (mod:QI (match_dup 1) (match_dup 2)))
7525 (clobber (reg:CC FLAGS_REG))])]
7526 "TARGET_QIMODE_MATH"
7531 tmp0 = gen_reg_rtx (HImode);
7532 tmp1 = gen_reg_rtx (HImode);
7534 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7536 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7537 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7539 /* Extract remainder from AH. */
7540 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7541 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7543 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7544 set_unique_reg_note (insn, REG_EQUAL, mod);
7546 /* Extract quotient from AL. */
7547 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7549 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7550 set_unique_reg_note (insn, REG_EQUAL, div);
7555 ;; Divide AX by r/m8, with result stored in
7558 ;; Change div/mod to HImode and extend the second argument to HImode
7559 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7560 ;; combine may fail.
7561 (define_insn "divmodhiqi3"
7562 [(set (match_operand:HI 0 "register_operand" "=a")
7567 (mod:HI (match_operand:HI 1 "register_operand" "0")
7569 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7573 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7574 (clobber (reg:CC FLAGS_REG))]
7575 "TARGET_QIMODE_MATH"
7577 [(set_attr "type" "idiv")
7578 (set_attr "mode" "QI")])
7580 (define_expand "udivmod<mode>4"
7581 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7583 (match_operand:SWIM248 1 "register_operand")
7584 (match_operand:SWIM248 2 "nonimmediate_operand")))
7585 (set (match_operand:SWIM248 3 "register_operand")
7586 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7587 (clobber (reg:CC FLAGS_REG))])])
7589 ;; Split with 8bit unsigned divide:
7590 ;; if (dividend an divisor are in [0-255])
7591 ;; use 8bit unsigned integer divide
7593 ;; use original integer divide
7595 [(set (match_operand:SWI48 0 "register_operand")
7596 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7597 (match_operand:SWI48 3 "nonimmediate_operand")))
7598 (set (match_operand:SWI48 1 "register_operand")
7599 (umod:SWI48 (match_dup 2) (match_dup 3)))
7600 (clobber (reg:CC FLAGS_REG))]
7601 "TARGET_USE_8BIT_IDIV
7602 && TARGET_QIMODE_MATH
7603 && can_create_pseudo_p ()
7604 && !optimize_insn_for_size_p ()"
7606 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7608 (define_insn_and_split "udivmod<mode>4_1"
7609 [(set (match_operand:SWI48 0 "register_operand" "=a")
7610 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7611 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7612 (set (match_operand:SWI48 1 "register_operand" "=&d")
7613 (umod:SWI48 (match_dup 2) (match_dup 3)))
7614 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7615 (clobber (reg:CC FLAGS_REG))]
7619 [(set (match_dup 1) (const_int 0))
7620 (parallel [(set (match_dup 0)
7621 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7623 (umod:SWI48 (match_dup 2) (match_dup 3)))
7625 (clobber (reg:CC FLAGS_REG))])]
7627 [(set_attr "type" "multi")
7628 (set_attr "mode" "<MODE>")])
7630 (define_insn_and_split "*udivmod<mode>4"
7631 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7632 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7633 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7634 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7635 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7636 (clobber (reg:CC FLAGS_REG))]
7640 [(set (match_dup 1) (const_int 0))
7641 (parallel [(set (match_dup 0)
7642 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7644 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7646 (clobber (reg:CC FLAGS_REG))])]
7648 [(set_attr "type" "multi")
7649 (set_attr "mode" "<MODE>")])
7651 ;; Optimize division or modulo by constant power of 2, if the constant
7652 ;; materializes only after expansion.
7653 (define_insn_and_split "*udivmod<mode>4_pow2"
7654 [(set (match_operand:SWI48 0 "register_operand" "=r")
7655 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7656 (match_operand:SWI48 3 "const_int_operand" "n")))
7657 (set (match_operand:SWI48 1 "register_operand" "=r")
7658 (umod:SWI48 (match_dup 2) (match_dup 3)))
7659 (clobber (reg:CC FLAGS_REG))]
7660 "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
7661 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
7664 [(set (match_dup 1) (match_dup 2))
7665 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7666 (clobber (reg:CC FLAGS_REG))])
7667 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7668 (clobber (reg:CC FLAGS_REG))])]
7670 int v = exact_log2 (UINTVAL (operands[3]));
7671 operands[4] = GEN_INT (v);
7672 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7674 [(set_attr "type" "multi")
7675 (set_attr "mode" "<MODE>")])
7677 (define_insn "*udivmod<mode>4_noext"
7678 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7679 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7680 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7681 (set (match_operand:SWIM248 1 "register_operand" "=d")
7682 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7683 (use (match_operand:SWIM248 4 "register_operand" "1"))
7684 (clobber (reg:CC FLAGS_REG))]
7686 "div{<imodesuffix>}\t%3"
7687 [(set_attr "type" "idiv")
7688 (set_attr "mode" "<MODE>")])
7690 (define_expand "udivmodqi4"
7691 [(parallel [(set (match_operand:QI 0 "register_operand")
7693 (match_operand:QI 1 "register_operand")
7694 (match_operand:QI 2 "nonimmediate_operand")))
7695 (set (match_operand:QI 3 "register_operand")
7696 (umod:QI (match_dup 1) (match_dup 2)))
7697 (clobber (reg:CC FLAGS_REG))])]
7698 "TARGET_QIMODE_MATH"
7703 tmp0 = gen_reg_rtx (HImode);
7704 tmp1 = gen_reg_rtx (HImode);
7706 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7708 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7709 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7711 /* Extract remainder from AH. */
7712 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7713 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7714 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7716 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7717 set_unique_reg_note (insn, REG_EQUAL, mod);
7719 /* Extract quotient from AL. */
7720 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7722 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7723 set_unique_reg_note (insn, REG_EQUAL, div);
7728 (define_insn "udivmodhiqi3"
7729 [(set (match_operand:HI 0 "register_operand" "=a")
7734 (mod:HI (match_operand:HI 1 "register_operand" "0")
7736 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7740 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7741 (clobber (reg:CC FLAGS_REG))]
7742 "TARGET_QIMODE_MATH"
7744 [(set_attr "type" "idiv")
7745 (set_attr "mode" "QI")])
7747 ;; We cannot use div/idiv for double division, because it causes
7748 ;; "division by zero" on the overflow and that's not what we expect
7749 ;; from truncate. Because true (non truncating) double division is
7750 ;; never generated, we can't create this insn anyway.
7753 ; [(set (match_operand:SI 0 "register_operand" "=a")
7755 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7757 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7758 ; (set (match_operand:SI 3 "register_operand" "=d")
7760 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7761 ; (clobber (reg:CC FLAGS_REG))]
7763 ; "div{l}\t{%2, %0|%0, %2}"
7764 ; [(set_attr "type" "idiv")])
7766 ;;- Logical AND instructions
7768 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7769 ;; Note that this excludes ah.
7771 (define_expand "testsi_ccno_1"
7772 [(set (reg:CCNO FLAGS_REG)
7774 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7775 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7778 (define_expand "testqi_ccz_1"
7779 [(set (reg:CCZ FLAGS_REG)
7780 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7781 (match_operand:QI 1 "nonmemory_operand"))
7784 (define_expand "testdi_ccno_1"
7785 [(set (reg:CCNO FLAGS_REG)
7787 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7788 (match_operand:DI 1 "x86_64_szext_general_operand"))
7790 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7792 (define_insn "*testdi_1"
7793 [(set (reg FLAGS_REG)
7796 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7797 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7799 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7800 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7802 test{l}\t{%k1, %k0|%k0, %k1}
7803 test{l}\t{%k1, %k0|%k0, %k1}
7804 test{q}\t{%1, %0|%0, %1}
7805 test{q}\t{%1, %0|%0, %1}
7806 test{q}\t{%1, %0|%0, %1}"
7807 [(set_attr "type" "test")
7808 (set_attr "modrm" "0,1,0,1,1")
7809 (set_attr "mode" "SI,SI,DI,DI,DI")])
7811 (define_insn "*testqi_1_maybe_si"
7812 [(set (reg FLAGS_REG)
7815 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7816 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7818 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7819 && ix86_match_ccmode (insn,
7820 CONST_INT_P (operands[1])
7821 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7823 if (which_alternative == 3)
7825 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7826 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7827 return "test{l}\t{%1, %k0|%k0, %1}";
7829 return "test{b}\t{%1, %0|%0, %1}";
7831 [(set_attr "type" "test")
7832 (set_attr "modrm" "0,1,1,1")
7833 (set_attr "mode" "QI,QI,QI,SI")
7834 (set_attr "pent_pair" "uv,np,uv,np")])
7836 (define_insn "*test<mode>_1"
7837 [(set (reg FLAGS_REG)
7840 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7841 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7843 "ix86_match_ccmode (insn, CCNOmode)
7844 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7845 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7846 [(set_attr "type" "test")
7847 (set_attr "modrm" "0,1,1")
7848 (set_attr "mode" "<MODE>")
7849 (set_attr "pent_pair" "uv,np,uv")])
7851 (define_expand "testqi_ext_ccno_0"
7852 [(set (reg:CCNO FLAGS_REG)
7856 (match_operand 0 "ext_register_operand")
7859 (match_operand 1 "const_int_operand"))
7862 (define_insn "*testqi_ext_0"
7863 [(set (reg FLAGS_REG)
7867 (match_operand 0 "ext_register_operand" "Q")
7870 (match_operand 1 "const_int_operand" "n"))
7872 "ix86_match_ccmode (insn, CCNOmode)"
7873 "test{b}\t{%1, %h0|%h0, %1}"
7874 [(set_attr "type" "test")
7875 (set_attr "mode" "QI")
7876 (set_attr "length_immediate" "1")
7877 (set_attr "modrm" "1")
7878 (set_attr "pent_pair" "np")])
7880 (define_insn "*testqi_ext_1"
7881 [(set (reg FLAGS_REG)
7885 (match_operand 0 "ext_register_operand" "Q,Q")
7889 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7891 "ix86_match_ccmode (insn, CCNOmode)"
7892 "test{b}\t{%1, %h0|%h0, %1}"
7893 [(set_attr "isa" "*,nox64")
7894 (set_attr "type" "test")
7895 (set_attr "mode" "QI")])
7897 (define_insn "*testqi_ext_2"
7898 [(set (reg FLAGS_REG)
7902 (match_operand 0 "ext_register_operand" "Q")
7906 (match_operand 1 "ext_register_operand" "Q")
7910 "ix86_match_ccmode (insn, CCNOmode)"
7911 "test{b}\t{%h1, %h0|%h0, %h1}"
7912 [(set_attr "type" "test")
7913 (set_attr "mode" "QI")])
7915 ;; Combine likes to form bit extractions for some tests. Humor it.
7916 (define_insn "*testqi_ext_3"
7917 [(set (reg FLAGS_REG)
7918 (compare (zero_extract:SWI248
7919 (match_operand 0 "nonimmediate_operand" "rm")
7920 (match_operand 1 "const_int_operand" "n")
7921 (match_operand 2 "const_int_operand" "n"))
7923 "ix86_match_ccmode (insn, CCNOmode)
7924 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7925 || GET_MODE (operands[0]) == SImode
7926 || GET_MODE (operands[0]) == HImode
7927 || GET_MODE (operands[0]) == QImode)
7928 /* Ensure that resulting mask is zero or sign extended operand. */
7929 && INTVAL (operands[2]) >= 0
7930 && ((INTVAL (operands[1]) > 0
7931 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7932 || (<MODE>mode == DImode
7933 && INTVAL (operands[1]) > 32
7934 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7938 [(set (match_operand 0 "flags_reg_operand")
7939 (match_operator 1 "compare_operator"
7941 (match_operand 2 "nonimmediate_operand")
7942 (match_operand 3 "const_int_operand")
7943 (match_operand 4 "const_int_operand"))
7945 "ix86_match_ccmode (insn, CCNOmode)"
7946 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7948 rtx val = operands[2];
7949 HOST_WIDE_INT len = INTVAL (operands[3]);
7950 HOST_WIDE_INT pos = INTVAL (operands[4]);
7952 machine_mode mode, submode;
7954 mode = GET_MODE (val);
7957 /* ??? Combine likes to put non-volatile mem extractions in QImode
7958 no matter the size of the test. So find a mode that works. */
7959 if (! MEM_VOLATILE_P (val))
7961 mode = smallest_mode_for_size (pos + len, MODE_INT);
7962 val = adjust_address (val, mode, 0);
7965 else if (SUBREG_P (val)
7966 && (submode = GET_MODE (SUBREG_REG (val)),
7967 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7968 && pos + len <= GET_MODE_BITSIZE (submode)
7969 && GET_MODE_CLASS (submode) == MODE_INT)
7971 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7973 val = SUBREG_REG (val);
7975 else if (mode == HImode && pos + len <= 8)
7977 /* Small HImode tests can be converted to QImode. */
7979 val = gen_lowpart (QImode, val);
7982 if (len == HOST_BITS_PER_WIDE_INT)
7985 mask = ((HOST_WIDE_INT)1 << len) - 1;
7988 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7991 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7992 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7993 ;; this is relatively important trick.
7994 ;; Do the conversion only post-reload to avoid limiting of the register class
7997 [(set (match_operand 0 "flags_reg_operand")
7998 (match_operator 1 "compare_operator"
7999 [(and (match_operand 2 "QIreg_operand")
8000 (match_operand 3 "const_int_operand"))
8003 && GET_MODE (operands[2]) != QImode
8004 && ((ix86_match_ccmode (insn, CCZmode)
8005 && !(INTVAL (operands[3]) & ~(255 << 8)))
8006 || (ix86_match_ccmode (insn, CCNOmode)
8007 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8010 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8014 operands[2] = gen_lowpart (SImode, operands[2]);
8015 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
8019 [(set (match_operand 0 "flags_reg_operand")
8020 (match_operator 1 "compare_operator"
8021 [(and (match_operand 2 "nonimmediate_operand")
8022 (match_operand 3 "const_int_operand"))
8025 && GET_MODE (operands[2]) != QImode
8026 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8027 && ((ix86_match_ccmode (insn, CCZmode)
8028 && !(INTVAL (operands[3]) & ~255))
8029 || (ix86_match_ccmode (insn, CCNOmode)
8030 && !(INTVAL (operands[3]) & ~127)))"
8032 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8035 operands[2] = gen_lowpart (QImode, operands[2]);
8036 operands[3] = gen_lowpart (QImode, operands[3]);
8040 [(set (match_operand:SWI1248x 0 "mask_reg_operand")
8041 (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
8042 (match_operand:SWI1248x 2 "mask_reg_operand")))
8043 (clobber (reg:CC FLAGS_REG))]
8044 "TARGET_AVX512F && reload_completed"
8046 (any_logic:SWI1248x (match_dup 1)
8049 (define_mode_iterator SWI1248_AVX512BW
8050 [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
8052 (define_insn "*k<logic><mode>"
8053 [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
8054 (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
8055 (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
8058 if (!TARGET_AVX512DQ && <MODE>mode == QImode)
8059 return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
8061 return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
8063 [(set_attr "mode" "<MODE>")
8064 (set_attr "type" "msklog")
8065 (set_attr "prefix" "vex")])
8067 ;; %%% This used to optimize known byte-wide and operations to memory,
8068 ;; and sometimes to QImode registers. If this is considered useful,
8069 ;; it should be done with splitters.
8071 (define_expand "and<mode>3"
8072 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8073 (and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8074 (match_operand:SWIM1248x 2 "<general_szext_operand>")))]
8077 machine_mode mode = <MODE>mode;
8078 rtx (*insn) (rtx, rtx);
8080 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
8082 HOST_WIDE_INT ival = INTVAL (operands[2]);
8084 if (ival == (HOST_WIDE_INT) 0xffffffff)
8086 else if (ival == 0xffff)
8088 else if (ival == 0xff)
8092 if (mode == <MODE>mode)
8094 ix86_expand_binary_operator (AND, <MODE>mode, operands);
8098 if (<MODE>mode == DImode)
8099 insn = (mode == SImode)
8100 ? gen_zero_extendsidi2
8102 ? gen_zero_extendhidi2
8103 : gen_zero_extendqidi2;
8104 else if (<MODE>mode == SImode)
8105 insn = (mode == HImode)
8106 ? gen_zero_extendhisi2
8107 : gen_zero_extendqisi2;
8108 else if (<MODE>mode == HImode)
8109 insn = gen_zero_extendqihi2;
8113 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8117 (define_insn "*anddi_1"
8118 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
8120 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
8121 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
8122 (clobber (reg:CC FLAGS_REG))]
8123 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8125 switch (get_attr_type (insn))
8131 return "kandq\t{%2, %1, %0|%0, %1, %2}";
8134 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8135 if (get_attr_mode (insn) == MODE_SI)
8136 return "and{l}\t{%k2, %k0|%k0, %k2}";
8138 return "and{q}\t{%2, %0|%0, %2}";
8141 [(set_attr "type" "alu,alu,alu,imovx,msklog")
8142 (set_attr "length_immediate" "*,*,*,0,0")
8143 (set (attr "prefix_rex")
8145 (and (eq_attr "type" "imovx")
8146 (and (match_test "INTVAL (operands[2]) == 0xff")
8147 (match_operand 1 "ext_QIreg_operand")))
8149 (const_string "*")))
8150 (set_attr "mode" "SI,DI,DI,SI,DI")])
8152 (define_insn_and_split "*anddi3_doubleword"
8153 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8155 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8156 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8157 (clobber (reg:CC FLAGS_REG))]
8158 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8159 && ix86_binary_operator_ok (AND, DImode, operands)"
8161 "&& reload_completed"
8164 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8165 if (operands[2] == const0_rtx)
8167 operands[1] = const0_rtx;
8168 ix86_expand_move (SImode, &operands[0]);
8170 else if (operands[2] != constm1_rtx)
8171 ix86_expand_binary_operator (AND, SImode, &operands[0]);
8172 else if (operands[5] == constm1_rtx)
8173 emit_note (NOTE_INSN_DELETED);
8174 if (operands[5] == const0_rtx)
8176 operands[4] = const0_rtx;
8177 ix86_expand_move (SImode, &operands[3]);
8179 else if (operands[5] != constm1_rtx)
8180 ix86_expand_binary_operator (AND, SImode, &operands[3]);
8184 (define_insn "*andsi_1"
8185 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
8186 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
8187 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
8188 (clobber (reg:CC FLAGS_REG))]
8189 "ix86_binary_operator_ok (AND, SImode, operands)"
8191 switch (get_attr_type (insn))
8197 return "kandd\t{%2, %1, %0|%0, %1, %2}";
8200 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8201 return "and{l}\t{%2, %0|%0, %2}";
8204 [(set_attr "type" "alu,alu,imovx,msklog")
8205 (set (attr "prefix_rex")
8207 (and (eq_attr "type" "imovx")
8208 (and (match_test "INTVAL (operands[2]) == 0xff")
8209 (match_operand 1 "ext_QIreg_operand")))
8211 (const_string "*")))
8212 (set_attr "length_immediate" "*,*,0,0")
8213 (set_attr "mode" "SI")])
8215 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8216 (define_insn "*andsi_1_zext"
8217 [(set (match_operand:DI 0 "register_operand" "=r")
8219 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8220 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8221 (clobber (reg:CC FLAGS_REG))]
8222 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8223 "and{l}\t{%2, %k0|%k0, %2}"
8224 [(set_attr "type" "alu")
8225 (set_attr "mode" "SI")])
8227 (define_insn "*andhi_1"
8228 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
8229 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
8230 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
8231 (clobber (reg:CC FLAGS_REG))]
8232 "ix86_binary_operator_ok (AND, HImode, operands)"
8234 switch (get_attr_type (insn))
8240 return "kandw\t{%2, %1, %0|%0, %1, %2}";
8243 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8244 return "and{w}\t{%2, %0|%0, %2}";
8247 [(set_attr "type" "alu,alu,imovx,msklog")
8248 (set_attr "length_immediate" "*,*,0,*")
8249 (set (attr "prefix_rex")
8251 (and (eq_attr "type" "imovx")
8252 (match_operand 1 "ext_QIreg_operand"))
8254 (const_string "*")))
8255 (set_attr "mode" "HI,HI,SI,HI")])
8257 ;; %%% Potential partial reg stall on alternative 2. What to do?
8258 (define_insn "*andqi_1"
8259 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
8260 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8261 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
8262 (clobber (reg:CC FLAGS_REG))]
8263 "ix86_binary_operator_ok (AND, QImode, operands)"
8265 switch (which_alternative)
8269 return "and{b}\t{%2, %0|%0, %2}";
8271 return "and{l}\t{%k2, %k0|%k0, %k2}";
8273 return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
8274 : "kandw\t{%2, %1, %0|%0, %1, %2}";
8279 [(set_attr "type" "alu,alu,alu,msklog")
8280 (set_attr "mode" "QI,QI,SI,HI")])
8282 (define_insn "*andqi_1_slp"
8283 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8284 (and:QI (match_dup 0)
8285 (match_operand:QI 1 "general_operand" "qn,qmn")))
8286 (clobber (reg:CC FLAGS_REG))]
8287 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8288 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8289 "and{b}\t{%1, %0|%0, %1}"
8290 [(set_attr "type" "alu1")
8291 (set_attr "mode" "QI")])
8293 (define_insn "kandn<mode>"
8294 [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
8297 (match_operand:SWI12 1 "register_operand" "r,0,k"))
8298 (match_operand:SWI12 2 "register_operand" "r,r,k")))
8299 (clobber (reg:CC FLAGS_REG))]
8302 switch (which_alternative)
8305 return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
8309 if (TARGET_AVX512DQ && <MODE>mode == QImode)
8310 return "kandnb\t{%2, %1, %0|%0, %1, %2}";
8312 return "kandnw\t{%2, %1, %0|%0, %1, %2}";
8317 [(set_attr "isa" "bmi,*,avx512f")
8318 (set_attr "type" "bitmanip,*,msklog")
8319 (set_attr "prefix" "*,*,vex")
8320 (set_attr "btver2_decode" "direct,*,*")
8321 (set_attr "mode" "<MODE>")])
8324 [(set (match_operand:SWI12 0 "general_reg_operand")
8328 (match_operand:SWI12 1 "general_reg_operand")))
8329 (clobber (reg:CC FLAGS_REG))]
8330 "TARGET_AVX512F && !TARGET_BMI && reload_completed"
8332 (not:SWI12 (match_dup 0)))
8333 (parallel [(set (match_dup 0)
8334 (and:SWI12 (match_dup 0)
8336 (clobber (reg:CC FLAGS_REG))])])
8338 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8340 [(set (match_operand:DI 0 "register_operand")
8341 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8342 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8343 (clobber (reg:CC FLAGS_REG))]
8345 [(parallel [(set (match_dup 0)
8346 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8347 (clobber (reg:CC FLAGS_REG))])]
8348 "operands[2] = gen_lowpart (SImode, operands[2]);")
8351 [(set (match_operand:SWI248 0 "register_operand")
8352 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8353 (match_operand:SWI248 2 "const_int_operand")))
8354 (clobber (reg:CC FLAGS_REG))]
8356 && true_regnum (operands[0]) != true_regnum (operands[1])"
8359 HOST_WIDE_INT ival = INTVAL (operands[2]);
8361 rtx (*insn) (rtx, rtx);
8363 if (ival == (HOST_WIDE_INT) 0xffffffff)
8365 else if (ival == 0xffff)
8369 gcc_assert (ival == 0xff);
8373 if (<MODE>mode == DImode)
8374 insn = (mode == SImode)
8375 ? gen_zero_extendsidi2
8377 ? gen_zero_extendhidi2
8378 : gen_zero_extendqidi2;
8381 if (<MODE>mode != SImode)
8382 /* Zero extend to SImode to avoid partial register stalls. */
8383 operands[0] = gen_lowpart (SImode, operands[0]);
8385 insn = (mode == HImode)
8386 ? gen_zero_extendhisi2
8387 : gen_zero_extendqisi2;
8389 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8394 [(set (match_operand:SWI48 0 "register_operand")
8395 (and:SWI48 (match_dup 0)
8396 (const_int -65536)))
8397 (clobber (reg:CC FLAGS_REG))]
8398 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8399 || optimize_function_for_size_p (cfun)"
8400 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8401 "operands[1] = gen_lowpart (HImode, operands[0]);")
8404 [(set (match_operand:SWI248 0 "any_QIreg_operand")
8405 (and:SWI248 (match_dup 0)
8407 (clobber (reg:CC FLAGS_REG))]
8408 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8409 && reload_completed"
8410 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8411 "operands[1] = gen_lowpart (QImode, operands[0]);")
8414 [(set (match_operand:SWI248 0 "QIreg_operand")
8415 (and:SWI248 (match_dup 0)
8416 (const_int -65281)))
8417 (clobber (reg:CC FLAGS_REG))]
8418 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8419 && reload_completed"
8420 [(parallel [(set (zero_extract:SI (match_dup 0)
8424 (zero_extract:SI (match_dup 0)
8427 (zero_extract:SI (match_dup 0)
8430 (clobber (reg:CC FLAGS_REG))])]
8431 "operands[0] = gen_lowpart (SImode, operands[0]);")
8433 (define_insn "*anddi_2"
8434 [(set (reg FLAGS_REG)
8437 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8438 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8440 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8441 (and:DI (match_dup 1) (match_dup 2)))]
8443 && ix86_match_ccmode
8445 /* If we are going to emit andl instead of andq, and the operands[2]
8446 constant might have the SImode sign bit set, make sure the sign
8447 flag isn't tested, because the instruction will set the sign flag
8448 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8449 conservatively assume it might have bit 31 set. */
8450 (satisfies_constraint_Z (operands[2])
8451 && (!CONST_INT_P (operands[2])
8452 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8453 ? CCZmode : CCNOmode)
8454 && ix86_binary_operator_ok (AND, DImode, operands)"
8456 and{l}\t{%k2, %k0|%k0, %k2}
8457 and{q}\t{%2, %0|%0, %2}
8458 and{q}\t{%2, %0|%0, %2}"
8459 [(set_attr "type" "alu")
8460 (set_attr "mode" "SI,DI,DI")])
8462 (define_insn "*andqi_2_maybe_si"
8463 [(set (reg FLAGS_REG)
8465 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8466 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8468 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8469 (and:QI (match_dup 1) (match_dup 2)))]
8470 "ix86_binary_operator_ok (AND, QImode, operands)
8471 && ix86_match_ccmode (insn,
8472 CONST_INT_P (operands[2])
8473 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8475 if (which_alternative == 2)
8477 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8478 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8479 return "and{l}\t{%2, %k0|%k0, %2}";
8481 return "and{b}\t{%2, %0|%0, %2}";
8483 [(set_attr "type" "alu")
8484 (set_attr "mode" "QI,QI,SI")])
8486 (define_insn "*and<mode>_2"
8487 [(set (reg FLAGS_REG)
8488 (compare (and:SWI124
8489 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8490 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8492 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8493 (and:SWI124 (match_dup 1) (match_dup 2)))]
8494 "ix86_match_ccmode (insn, CCNOmode)
8495 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8496 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8497 [(set_attr "type" "alu")
8498 (set_attr "mode" "<MODE>")])
8500 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8501 (define_insn "*andsi_2_zext"
8502 [(set (reg FLAGS_REG)
8504 (match_operand:SI 1 "nonimmediate_operand" "%0")
8505 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8507 (set (match_operand:DI 0 "register_operand" "=r")
8508 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8509 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8510 && ix86_binary_operator_ok (AND, SImode, operands)"
8511 "and{l}\t{%2, %k0|%k0, %2}"
8512 [(set_attr "type" "alu")
8513 (set_attr "mode" "SI")])
8515 (define_insn "*andqi_2_slp"
8516 [(set (reg FLAGS_REG)
8518 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8519 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8521 (set (strict_low_part (match_dup 0))
8522 (and:QI (match_dup 0) (match_dup 1)))]
8523 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8524 && ix86_match_ccmode (insn, CCNOmode)
8525 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8526 "and{b}\t{%1, %0|%0, %1}"
8527 [(set_attr "type" "alu1")
8528 (set_attr "mode" "QI")])
8530 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8531 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8532 ;; for a QImode operand, which of course failed.
8533 (define_insn "andqi_ext_0"
8534 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8539 (match_operand 1 "ext_register_operand" "0")
8542 (match_operand 2 "const_int_operand" "n")))
8543 (clobber (reg:CC FLAGS_REG))]
8545 "and{b}\t{%2, %h0|%h0, %2}"
8546 [(set_attr "type" "alu")
8547 (set_attr "length_immediate" "1")
8548 (set_attr "modrm" "1")
8549 (set_attr "mode" "QI")])
8551 ;; Generated by peephole translating test to and. This shows up
8552 ;; often in fp comparisons.
8553 (define_insn "*andqi_ext_0_cc"
8554 [(set (reg FLAGS_REG)
8558 (match_operand 1 "ext_register_operand" "0")
8561 (match_operand 2 "const_int_operand" "n"))
8563 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8572 "ix86_match_ccmode (insn, CCNOmode)"
8573 "and{b}\t{%2, %h0|%h0, %2}"
8574 [(set_attr "type" "alu")
8575 (set_attr "length_immediate" "1")
8576 (set_attr "modrm" "1")
8577 (set_attr "mode" "QI")])
8579 (define_insn "*andqi_ext_1"
8580 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8585 (match_operand 1 "ext_register_operand" "0,0")
8589 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8590 (clobber (reg:CC FLAGS_REG))]
8592 "and{b}\t{%2, %h0|%h0, %2}"
8593 [(set_attr "isa" "*,nox64")
8594 (set_attr "type" "alu")
8595 (set_attr "length_immediate" "0")
8596 (set_attr "mode" "QI")])
8598 (define_insn "*andqi_ext_2"
8599 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8604 (match_operand 1 "ext_register_operand" "%0")
8608 (match_operand 2 "ext_register_operand" "Q")
8611 (clobber (reg:CC FLAGS_REG))]
8613 "and{b}\t{%h2, %h0|%h0, %h2}"
8614 [(set_attr "type" "alu")
8615 (set_attr "length_immediate" "0")
8616 (set_attr "mode" "QI")])
8618 ;; Convert wide AND instructions with immediate operand to shorter QImode
8619 ;; equivalents when possible.
8620 ;; Don't do the splitting with memory operands, since it introduces risk
8621 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8622 ;; for size, but that can (should?) be handled by generic code instead.
8624 [(set (match_operand 0 "QIreg_operand")
8625 (and (match_operand 1 "register_operand")
8626 (match_operand 2 "const_int_operand")))
8627 (clobber (reg:CC FLAGS_REG))]
8629 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8630 && !(~INTVAL (operands[2]) & ~(255 << 8))
8631 && GET_MODE (operands[0]) != QImode"
8632 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8633 (and:SI (zero_extract:SI (match_dup 1)
8634 (const_int 8) (const_int 8))
8636 (clobber (reg:CC FLAGS_REG))])]
8638 operands[0] = gen_lowpart (SImode, operands[0]);
8639 operands[1] = gen_lowpart (SImode, operands[1]);
8640 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8643 ;; Since AND can be encoded with sign extended immediate, this is only
8644 ;; profitable when 7th bit is not set.
8646 [(set (match_operand 0 "any_QIreg_operand")
8647 (and (match_operand 1 "general_operand")
8648 (match_operand 2 "const_int_operand")))
8649 (clobber (reg:CC FLAGS_REG))]
8651 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8652 && !(~INTVAL (operands[2]) & ~255)
8653 && !(INTVAL (operands[2]) & 128)
8654 && GET_MODE (operands[0]) != QImode"
8655 [(parallel [(set (strict_low_part (match_dup 0))
8656 (and:QI (match_dup 1)
8658 (clobber (reg:CC FLAGS_REG))])]
8660 operands[0] = gen_lowpart (QImode, operands[0]);
8661 operands[1] = gen_lowpart (QImode, operands[1]);
8662 operands[2] = gen_lowpart (QImode, operands[2]);
8665 ;; Logical inclusive and exclusive OR instructions
8667 ;; %%% This used to optimize known byte-wide and operations to memory.
8668 ;; If this is considered useful, it should be done with splitters.
8670 (define_expand "<code><mode>3"
8671 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8672 (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8673 (match_operand:SWIM1248x 2 "<general_operand>")))]
8675 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8677 (define_insn "*<code><mode>_1"
8678 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8680 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8681 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8682 (clobber (reg:CC FLAGS_REG))]
8683 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8685 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8686 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8687 k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8688 [(set_attr "type" "alu,alu,msklog")
8689 (set_attr "mode" "<MODE>")])
8691 (define_insn_and_split "*<code>di3_doubleword"
8692 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8694 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8695 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8696 (clobber (reg:CC FLAGS_REG))]
8697 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8698 && ix86_binary_operator_ok (<CODE>, DImode, operands)"
8700 "&& reload_completed"
8703 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8704 if (operands[2] == constm1_rtx)
8708 operands[1] = constm1_rtx;
8709 ix86_expand_move (SImode, &operands[0]);
8712 ix86_expand_unary_operator (NOT, SImode, &operands[0]);
8714 else if (operands[2] != const0_rtx)
8715 ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
8716 else if (operands[5] == const0_rtx)
8717 emit_note (NOTE_INSN_DELETED);
8718 if (operands[5] == constm1_rtx)
8722 operands[4] = constm1_rtx;
8723 ix86_expand_move (SImode, &operands[3]);
8726 ix86_expand_unary_operator (NOT, SImode, &operands[3]);
8728 else if (operands[5] != const0_rtx)
8729 ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
8733 (define_insn_and_split "*andndi3_doubleword"
8734 [(set (match_operand:DI 0 "register_operand" "=r,r")
8736 (not:DI (match_operand:DI 1 "register_operand" "r,r"))
8737 (match_operand:DI 2 "nonimmediate_operand" "r,m")))
8738 (clobber (reg:CC FLAGS_REG))]
8739 "TARGET_BMI && !TARGET_64BIT && TARGET_STV && TARGET_SSE"
8741 "&& reload_completed"
8742 [(parallel [(set (match_dup 0)
8743 (and:SI (not:SI (match_dup 1)) (match_dup 2)))
8744 (clobber (reg:CC FLAGS_REG))])
8745 (parallel [(set (match_dup 3)
8746 (and:SI (not:SI (match_dup 4)) (match_dup 5)))
8747 (clobber (reg:CC FLAGS_REG))])]
8748 "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
8750 (define_insn "*<code>hi_1"
8751 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8753 (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8754 (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8755 (clobber (reg:CC FLAGS_REG))]
8756 "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8758 <logic>{w}\t{%2, %0|%0, %2}
8759 <logic>{w}\t{%2, %0|%0, %2}
8760 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8761 [(set_attr "type" "alu,alu,msklog")
8762 (set_attr "mode" "HI")])
8764 ;; %%% Potential partial reg stall on alternative 2. What to do?
8765 (define_insn "*<code>qi_1"
8766 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8767 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8768 (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8769 (clobber (reg:CC FLAGS_REG))]
8770 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8772 <logic>{b}\t{%2, %0|%0, %2}
8773 <logic>{b}\t{%2, %0|%0, %2}
8774 <logic>{l}\t{%k2, %k0|%k0, %k2}
8775 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8776 [(set_attr "type" "alu,alu,alu,msklog")
8777 (set_attr "mode" "QI,QI,SI,HI")])
8779 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8780 (define_insn "*<code>si_1_zext"
8781 [(set (match_operand:DI 0 "register_operand" "=r")
8783 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8784 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8785 (clobber (reg:CC FLAGS_REG))]
8786 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8787 "<logic>{l}\t{%2, %k0|%k0, %2}"
8788 [(set_attr "type" "alu")
8789 (set_attr "mode" "SI")])
8791 (define_insn "*<code>si_1_zext_imm"
8792 [(set (match_operand:DI 0 "register_operand" "=r")
8794 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8795 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8796 (clobber (reg:CC FLAGS_REG))]
8797 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8798 "<logic>{l}\t{%2, %k0|%k0, %2}"
8799 [(set_attr "type" "alu")
8800 (set_attr "mode" "SI")])
8802 (define_insn "*<code>qi_1_slp"
8803 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8804 (any_or:QI (match_dup 0)
8805 (match_operand:QI 1 "general_operand" "qmn,qn")))
8806 (clobber (reg:CC FLAGS_REG))]
8807 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8808 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8809 "<logic>{b}\t{%1, %0|%0, %1}"
8810 [(set_attr "type" "alu1")
8811 (set_attr "mode" "QI")])
8813 (define_insn "*<code><mode>_2"
8814 [(set (reg FLAGS_REG)
8815 (compare (any_or:SWI
8816 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8817 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8819 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8820 (any_or:SWI (match_dup 1) (match_dup 2)))]
8821 "ix86_match_ccmode (insn, CCNOmode)
8822 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8823 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8824 [(set_attr "type" "alu")
8825 (set_attr "mode" "<MODE>")])
8827 (define_insn "kxnor<mode>"
8828 [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8831 (match_operand:SWI12 1 "register_operand" "0,k")
8832 (match_operand:SWI12 2 "register_operand" "r,k"))))
8833 (clobber (reg:CC FLAGS_REG))]
8836 if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8837 return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8838 return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8840 [(set_attr "type" "*,msklog")
8841 (set_attr "prefix" "*,vex")
8842 (set_attr "mode" "<MODE>")])
8844 (define_insn "kxnor<mode>"
8845 [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8848 (match_operand:SWI48x 1 "register_operand" "0,k")
8849 (match_operand:SWI48x 2 "register_operand" "r,k"))))
8850 (clobber (reg:CC FLAGS_REG))]
8854 kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8855 [(set_attr "type" "*,msklog")
8856 (set_attr "prefix" "*,vex")
8857 (set_attr "mode" "<MODE>")])
8860 [(set (match_operand:SWI1248x 0 "general_reg_operand")
8864 (match_operand:SWI1248x 1 "general_reg_operand"))))
8865 (clobber (reg:CC FLAGS_REG))]
8866 "TARGET_AVX512F && reload_completed"
8867 [(parallel [(set (match_dup 0)
8868 (xor:SWI1248x (match_dup 0)
8870 (clobber (reg:CC FLAGS_REG))])
8872 (not:SWI1248x (match_dup 0)))])
8874 ;;There are kortrest[bdq] but no intrinsics for them.
8875 ;;We probably don't need to implement them.
8876 (define_insn "kortestzhi"
8877 [(set (reg:CCZ FLAGS_REG)
8880 (match_operand:HI 0 "register_operand" "k")
8881 (match_operand:HI 1 "register_operand" "k"))
8883 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8884 "kortestw\t{%1, %0|%0, %1}"
8885 [(set_attr "mode" "HI")
8886 (set_attr "type" "msklog")
8887 (set_attr "prefix" "vex")])
8889 (define_insn "kortestchi"
8890 [(set (reg:CCC FLAGS_REG)
8893 (match_operand:HI 0 "register_operand" "k")
8894 (match_operand:HI 1 "register_operand" "k"))
8896 "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8897 "kortestw\t{%1, %0|%0, %1}"
8898 [(set_attr "mode" "HI")
8899 (set_attr "type" "msklog")
8900 (set_attr "prefix" "vex")])
8902 (define_insn "kunpckhi"
8903 [(set (match_operand:HI 0 "register_operand" "=k")
8906 (zero_extend:HI (match_operand:QI 1 "register_operand" "k"))
8908 (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8910 "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8911 [(set_attr "mode" "HI")
8912 (set_attr "type" "msklog")
8913 (set_attr "prefix" "vex")])
8915 (define_insn "kunpcksi"
8916 [(set (match_operand:SI 0 "register_operand" "=k")
8919 (zero_extend:SI (match_operand:HI 1 "register_operand" "k"))
8921 (zero_extend:SI (match_operand:HI 2 "register_operand" "k"))))]
8923 "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8924 [(set_attr "mode" "SI")])
8926 (define_insn "kunpckdi"
8927 [(set (match_operand:DI 0 "register_operand" "=k")
8930 (zero_extend:DI (match_operand:SI 1 "register_operand" "k"))
8932 (zero_extend:DI (match_operand:SI 2 "register_operand" "k"))))]
8934 "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8935 [(set_attr "mode" "DI")])
8937 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8938 ;; ??? Special case for immediate operand is missing - it is tricky.
8939 (define_insn "*<code>si_2_zext"
8940 [(set (reg FLAGS_REG)
8941 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8942 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8944 (set (match_operand:DI 0 "register_operand" "=r")
8945 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8946 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8947 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8948 "<logic>{l}\t{%2, %k0|%k0, %2}"
8949 [(set_attr "type" "alu")
8950 (set_attr "mode" "SI")])
8952 (define_insn "*<code>si_2_zext_imm"
8953 [(set (reg FLAGS_REG)
8955 (match_operand:SI 1 "nonimmediate_operand" "%0")
8956 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8958 (set (match_operand:DI 0 "register_operand" "=r")
8959 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8960 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8961 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8962 "<logic>{l}\t{%2, %k0|%k0, %2}"
8963 [(set_attr "type" "alu")
8964 (set_attr "mode" "SI")])
8966 (define_insn "*<code>qi_2_slp"
8967 [(set (reg FLAGS_REG)
8968 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8969 (match_operand:QI 1 "general_operand" "qmn,qn"))
8971 (set (strict_low_part (match_dup 0))
8972 (any_or:QI (match_dup 0) (match_dup 1)))]
8973 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8974 && ix86_match_ccmode (insn, CCNOmode)
8975 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8976 "<logic>{b}\t{%1, %0|%0, %1}"
8977 [(set_attr "type" "alu1")
8978 (set_attr "mode" "QI")])
8980 (define_insn "*<code><mode>_3"
8981 [(set (reg FLAGS_REG)
8982 (compare (any_or:SWI
8983 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8984 (match_operand:SWI 2 "<general_operand>" "<g>"))
8986 (clobber (match_scratch:SWI 0 "=<r>"))]
8987 "ix86_match_ccmode (insn, CCNOmode)
8988 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8989 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8990 [(set_attr "type" "alu")
8991 (set_attr "mode" "<MODE>")])
8993 (define_insn "*<code>qi_ext_0"
8994 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8999 (match_operand 1 "ext_register_operand" "0")
9002 (match_operand 2 "const_int_operand" "n")))
9003 (clobber (reg:CC FLAGS_REG))]
9004 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9005 "<logic>{b}\t{%2, %h0|%h0, %2}"
9006 [(set_attr "type" "alu")
9007 (set_attr "length_immediate" "1")
9008 (set_attr "modrm" "1")
9009 (set_attr "mode" "QI")])
9011 (define_insn "*<code>qi_ext_1"
9012 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
9017 (match_operand 1 "ext_register_operand" "0,0")
9021 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
9022 (clobber (reg:CC FLAGS_REG))]
9023 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9024 "<logic>{b}\t{%2, %h0|%h0, %2}"
9025 [(set_attr "isa" "*,nox64")
9026 (set_attr "type" "alu")
9027 (set_attr "length_immediate" "0")
9028 (set_attr "mode" "QI")])
9030 (define_insn "*<code>qi_ext_2"
9031 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9035 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9038 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9041 (clobber (reg:CC FLAGS_REG))]
9042 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9043 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9044 [(set_attr "type" "alu")
9045 (set_attr "length_immediate" "0")
9046 (set_attr "mode" "QI")])
9049 [(set (match_operand 0 "QIreg_operand")
9050 (any_or (match_operand 1 "register_operand")
9051 (match_operand 2 "const_int_operand")))
9052 (clobber (reg:CC FLAGS_REG))]
9054 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9055 && !(INTVAL (operands[2]) & ~(255 << 8))
9056 && GET_MODE (operands[0]) != QImode"
9057 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9058 (any_or:SI (zero_extract:SI (match_dup 1)
9059 (const_int 8) (const_int 8))
9061 (clobber (reg:CC FLAGS_REG))])]
9063 operands[0] = gen_lowpart (SImode, operands[0]);
9064 operands[1] = gen_lowpart (SImode, operands[1]);
9065 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
9068 ;; Since OR can be encoded with sign extended immediate, this is only
9069 ;; profitable when 7th bit is set.
9071 [(set (match_operand 0 "any_QIreg_operand")
9072 (any_or (match_operand 1 "general_operand")
9073 (match_operand 2 "const_int_operand")))
9074 (clobber (reg:CC FLAGS_REG))]
9076 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9077 && !(INTVAL (operands[2]) & ~255)
9078 && (INTVAL (operands[2]) & 128)
9079 && GET_MODE (operands[0]) != QImode"
9080 [(parallel [(set (strict_low_part (match_dup 0))
9081 (any_or:QI (match_dup 1)
9083 (clobber (reg:CC FLAGS_REG))])]
9085 operands[0] = gen_lowpart (QImode, operands[0]);
9086 operands[1] = gen_lowpart (QImode, operands[1]);
9087 operands[2] = gen_lowpart (QImode, operands[2]);
9090 (define_expand "xorqi_cc_ext_1"
9092 (set (reg:CCNO FLAGS_REG)
9096 (match_operand 1 "ext_register_operand")
9099 (match_operand:QI 2 "const_int_operand"))
9101 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9111 (define_insn "*xorqi_cc_ext_1"
9112 [(set (reg FLAGS_REG)
9116 (match_operand 1 "ext_register_operand" "0,0")
9119 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
9121 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
9130 "ix86_match_ccmode (insn, CCNOmode)"
9131 "xor{b}\t{%2, %h0|%h0, %2}"
9132 [(set_attr "isa" "*,nox64")
9133 (set_attr "type" "alu")
9134 (set_attr "modrm" "1")
9135 (set_attr "mode" "QI")])
9137 ;; Negation instructions
9139 (define_expand "neg<mode>2"
9140 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
9141 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
9143 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9145 (define_insn_and_split "*neg<dwi>2_doubleword"
9146 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9147 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9148 (clobber (reg:CC FLAGS_REG))]
9149 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9153 [(set (reg:CCZ FLAGS_REG)
9154 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9155 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9158 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9161 (clobber (reg:CC FLAGS_REG))])
9164 (neg:DWIH (match_dup 2)))
9165 (clobber (reg:CC FLAGS_REG))])]
9166 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
9168 (define_insn "*neg<mode>2_1"
9169 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9170 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9171 (clobber (reg:CC FLAGS_REG))]
9172 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9173 "neg{<imodesuffix>}\t%0"
9174 [(set_attr "type" "negnot")
9175 (set_attr "mode" "<MODE>")])
9177 ;; Combine is quite creative about this pattern.
9178 (define_insn "*negsi2_1_zext"
9179 [(set (match_operand:DI 0 "register_operand" "=r")
9181 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9184 (clobber (reg:CC FLAGS_REG))]
9185 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9187 [(set_attr "type" "negnot")
9188 (set_attr "mode" "SI")])
9190 ;; The problem with neg is that it does not perform (compare x 0),
9191 ;; it really performs (compare 0 x), which leaves us with the zero
9192 ;; flag being the only useful item.
9194 (define_insn "*neg<mode>2_cmpz"
9195 [(set (reg:CCZ FLAGS_REG)
9197 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9199 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9200 (neg:SWI (match_dup 1)))]
9201 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9202 "neg{<imodesuffix>}\t%0"
9203 [(set_attr "type" "negnot")
9204 (set_attr "mode" "<MODE>")])
9206 (define_insn "*negsi2_cmpz_zext"
9207 [(set (reg:CCZ FLAGS_REG)
9211 (match_operand:DI 1 "register_operand" "0")
9215 (set (match_operand:DI 0 "register_operand" "=r")
9216 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9219 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9221 [(set_attr "type" "negnot")
9222 (set_attr "mode" "SI")])
9224 ;; Negate with jump on overflow.
9225 (define_expand "negv<mode>3"
9226 [(parallel [(set (reg:CCO FLAGS_REG)
9227 (ne:CCO (match_operand:SWI 1 "register_operand")
9229 (set (match_operand:SWI 0 "register_operand")
9230 (neg:SWI (match_dup 1)))])
9231 (set (pc) (if_then_else
9232 (eq (reg:CCO FLAGS_REG) (const_int 0))
9233 (label_ref (match_operand 2))
9238 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
9242 (define_insn "*negv<mode>3"
9243 [(set (reg:CCO FLAGS_REG)
9244 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
9245 (match_operand:SWI 2 "const_int_operand")))
9246 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9247 (neg:SWI (match_dup 1)))]
9248 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
9249 && mode_signbit_p (<MODE>mode, operands[2])"
9250 "neg{<imodesuffix>}\t%0"
9251 [(set_attr "type" "negnot")
9252 (set_attr "mode" "<MODE>")])
9254 ;; Changing of sign for FP values is doable using integer unit too.
9256 (define_expand "<code><mode>2"
9257 [(set (match_operand:X87MODEF 0 "register_operand")
9258 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
9259 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9260 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9262 (define_insn "*absneg<mode>2_mixed"
9263 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9264 (match_operator:MODEF 3 "absneg_operator"
9265 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9266 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9267 (clobber (reg:CC FLAGS_REG))]
9268 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9270 [(set (attr "enabled")
9271 (cond [(eq_attr "alternative" "2")
9272 (symbol_ref "TARGET_MIX_SSE_I387")
9274 (symbol_ref "true")))])
9276 (define_insn "*absneg<mode>2_i387"
9277 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9278 (match_operator:X87MODEF 3 "absneg_operator"
9279 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9280 (use (match_operand 2))
9281 (clobber (reg:CC FLAGS_REG))]
9282 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9285 (define_expand "<code>tf2"
9286 [(set (match_operand:TF 0 "register_operand")
9287 (absneg:TF (match_operand:TF 1 "register_operand")))]
9289 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9291 (define_insn "*absnegtf2_sse"
9292 [(set (match_operand:TF 0 "register_operand" "=x,x")
9293 (match_operator:TF 3 "absneg_operator"
9294 [(match_operand:TF 1 "register_operand" "0,x")]))
9295 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9296 (clobber (reg:CC FLAGS_REG))]
9300 ;; Splitters for fp abs and neg.
9303 [(set (match_operand 0 "fp_register_operand")
9304 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9305 (use (match_operand 2))
9306 (clobber (reg:CC FLAGS_REG))]
9308 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9311 [(set (match_operand 0 "register_operand")
9312 (match_operator 3 "absneg_operator"
9313 [(match_operand 1 "register_operand")]))
9314 (use (match_operand 2 "nonimmediate_operand"))
9315 (clobber (reg:CC FLAGS_REG))]
9316 "reload_completed && SSE_REG_P (operands[0])"
9317 [(set (match_dup 0) (match_dup 3))]
9319 machine_mode mode = GET_MODE (operands[0]);
9320 machine_mode vmode = GET_MODE (operands[2]);
9323 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9324 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9325 if (operands_match_p (operands[0], operands[2]))
9326 std::swap (operands[1], operands[2]);
9327 if (GET_CODE (operands[3]) == ABS)
9328 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9330 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9335 [(set (match_operand:SF 0 "general_reg_operand")
9336 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9337 (use (match_operand:V4SF 2))
9338 (clobber (reg:CC FLAGS_REG))]
9340 [(parallel [(set (match_dup 0) (match_dup 1))
9341 (clobber (reg:CC FLAGS_REG))])]
9344 operands[0] = gen_lowpart (SImode, operands[0]);
9345 if (GET_CODE (operands[1]) == ABS)
9347 tmp = gen_int_mode (0x7fffffff, SImode);
9348 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9352 tmp = gen_int_mode (0x80000000, SImode);
9353 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9359 [(set (match_operand:DF 0 "general_reg_operand")
9360 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9361 (use (match_operand 2))
9362 (clobber (reg:CC FLAGS_REG))]
9364 [(parallel [(set (match_dup 0) (match_dup 1))
9365 (clobber (reg:CC FLAGS_REG))])]
9370 tmp = gen_lowpart (DImode, operands[0]);
9371 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9374 if (GET_CODE (operands[1]) == ABS)
9377 tmp = gen_rtx_NOT (DImode, tmp);
9381 operands[0] = gen_highpart (SImode, operands[0]);
9382 if (GET_CODE (operands[1]) == ABS)
9384 tmp = gen_int_mode (0x7fffffff, SImode);
9385 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9389 tmp = gen_int_mode (0x80000000, SImode);
9390 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9397 [(set (match_operand:XF 0 "general_reg_operand")
9398 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9399 (use (match_operand 2))
9400 (clobber (reg:CC FLAGS_REG))]
9402 [(parallel [(set (match_dup 0) (match_dup 1))
9403 (clobber (reg:CC FLAGS_REG))])]
9406 operands[0] = gen_rtx_REG (SImode,
9407 true_regnum (operands[0])
9408 + (TARGET_64BIT ? 1 : 2));
9409 if (GET_CODE (operands[1]) == ABS)
9411 tmp = GEN_INT (0x7fff);
9412 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9416 tmp = GEN_INT (0x8000);
9417 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9422 ;; Conditionalize these after reload. If they match before reload, we
9423 ;; lose the clobber and ability to use integer instructions.
9425 (define_insn "*<code><mode>2_1"
9426 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9427 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9429 && (reload_completed
9430 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9431 "f<absneg_mnemonic>"
9432 [(set_attr "type" "fsgn")
9433 (set_attr "mode" "<MODE>")])
9435 (define_insn "*<code>extendsfdf2"
9436 [(set (match_operand:DF 0 "register_operand" "=f")
9437 (absneg:DF (float_extend:DF
9438 (match_operand:SF 1 "register_operand" "0"))))]
9439 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9440 "f<absneg_mnemonic>"
9441 [(set_attr "type" "fsgn")
9442 (set_attr "mode" "DF")])
9444 (define_insn "*<code>extendsfxf2"
9445 [(set (match_operand:XF 0 "register_operand" "=f")
9446 (absneg:XF (float_extend:XF
9447 (match_operand:SF 1 "register_operand" "0"))))]
9449 "f<absneg_mnemonic>"
9450 [(set_attr "type" "fsgn")
9451 (set_attr "mode" "XF")])
9453 (define_insn "*<code>extenddfxf2"
9454 [(set (match_operand:XF 0 "register_operand" "=f")
9455 (absneg:XF (float_extend:XF
9456 (match_operand:DF 1 "register_operand" "0"))))]
9458 "f<absneg_mnemonic>"
9459 [(set_attr "type" "fsgn")
9460 (set_attr "mode" "XF")])
9462 ;; Copysign instructions
9464 (define_mode_iterator CSGNMODE [SF DF TF])
9465 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9467 (define_expand "copysign<mode>3"
9468 [(match_operand:CSGNMODE 0 "register_operand")
9469 (match_operand:CSGNMODE 1 "nonmemory_operand")
9470 (match_operand:CSGNMODE 2 "register_operand")]
9471 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9472 || (TARGET_SSE && (<MODE>mode == TFmode))"
9473 "ix86_expand_copysign (operands); DONE;")
9475 (define_insn_and_split "copysign<mode>3_const"
9476 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9478 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9479 (match_operand:CSGNMODE 2 "register_operand" "0")
9480 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9482 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9483 || (TARGET_SSE && (<MODE>mode == TFmode))"
9485 "&& reload_completed"
9487 "ix86_split_copysign_const (operands); DONE;")
9489 (define_insn "copysign<mode>3_var"
9490 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9492 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9493 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9494 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9495 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9497 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9498 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9499 || (TARGET_SSE && (<MODE>mode == TFmode))"
9503 [(set (match_operand:CSGNMODE 0 "register_operand")
9505 [(match_operand:CSGNMODE 2 "register_operand")
9506 (match_operand:CSGNMODE 3 "register_operand")
9507 (match_operand:<CSGNVMODE> 4)
9508 (match_operand:<CSGNVMODE> 5)]
9510 (clobber (match_scratch:<CSGNVMODE> 1))]
9511 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9512 || (TARGET_SSE && (<MODE>mode == TFmode)))
9513 && reload_completed"
9515 "ix86_split_copysign_var (operands); DONE;")
9517 ;; One complement instructions
9519 (define_expand "one_cmpl<mode>2"
9520 [(set (match_operand:SWIM 0 "nonimmediate_operand")
9521 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9523 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9525 (define_insn "*one_cmpl<mode>2_1"
9526 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
9527 (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
9528 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9530 not{<imodesuffix>}\t%0
9531 knot<mskmodesuffix>\t{%1, %0|%0, %1}"
9532 [(set_attr "isa" "*,avx512bw")
9533 (set_attr "type" "negnot,msklog")
9534 (set_attr "prefix" "*,vex")
9535 (set_attr "mode" "<MODE>")])
9537 (define_insn "*one_cmplhi2_1"
9538 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
9539 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
9540 "ix86_unary_operator_ok (NOT, HImode, operands)"
9543 knotw\t{%1, %0|%0, %1}"
9544 [(set_attr "isa" "*,avx512f")
9545 (set_attr "type" "negnot,msklog")
9546 (set_attr "prefix" "*,vex")
9547 (set_attr "mode" "HI")])
9549 ;; %%% Potential partial reg stall on alternative 1. What to do?
9550 (define_insn "*one_cmplqi2_1"
9551 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
9552 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
9553 "ix86_unary_operator_ok (NOT, QImode, operands)"
9555 switch (which_alternative)
9558 return "not{b}\t%0";
9560 return "not{l}\t%k0";
9562 if (TARGET_AVX512DQ)
9563 return "knotb\t{%1, %0|%0, %1}";
9564 return "knotw\t{%1, %0|%0, %1}";
9569 [(set_attr "isa" "*,*,avx512f")
9570 (set_attr "type" "negnot,negnot,msklog")
9571 (set_attr "prefix" "*,*,vex")
9572 (set_attr "mode" "QI,SI,QI")])
9574 ;; ??? Currently never generated - xor is used instead.
9575 (define_insn "*one_cmplsi2_1_zext"
9576 [(set (match_operand:DI 0 "register_operand" "=r")
9578 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9579 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9581 [(set_attr "type" "negnot")
9582 (set_attr "mode" "SI")])
9584 (define_insn "*one_cmpl<mode>2_2"
9585 [(set (reg FLAGS_REG)
9586 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9588 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9589 (not:SWI (match_dup 1)))]
9590 "ix86_match_ccmode (insn, CCNOmode)
9591 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9593 [(set_attr "type" "alu1")
9594 (set_attr "mode" "<MODE>")])
9597 [(set (match_operand 0 "flags_reg_operand")
9598 (match_operator 2 "compare_operator"
9599 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9601 (set (match_operand:SWI 1 "nonimmediate_operand")
9602 (not:SWI (match_dup 3)))]
9603 "ix86_match_ccmode (insn, CCNOmode)"
9604 [(parallel [(set (match_dup 0)
9605 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9608 (xor:SWI (match_dup 3) (const_int -1)))])])
9610 ;; ??? Currently never generated - xor is used instead.
9611 (define_insn "*one_cmplsi2_2_zext"
9612 [(set (reg FLAGS_REG)
9613 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9615 (set (match_operand:DI 0 "register_operand" "=r")
9616 (zero_extend:DI (not:SI (match_dup 1))))]
9617 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9618 && ix86_unary_operator_ok (NOT, SImode, operands)"
9620 [(set_attr "type" "alu1")
9621 (set_attr "mode" "SI")])
9624 [(set (match_operand 0 "flags_reg_operand")
9625 (match_operator 2 "compare_operator"
9626 [(not:SI (match_operand:SI 3 "register_operand"))
9628 (set (match_operand:DI 1 "register_operand")
9629 (zero_extend:DI (not:SI (match_dup 3))))]
9630 "ix86_match_ccmode (insn, CCNOmode)"
9631 [(parallel [(set (match_dup 0)
9632 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9635 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9637 ;; Shift instructions
9639 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9640 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9641 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9642 ;; from the assembler input.
9644 ;; This instruction shifts the target reg/mem as usual, but instead of
9645 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9646 ;; is a left shift double, bits are taken from the high order bits of
9647 ;; reg, else if the insn is a shift right double, bits are taken from the
9648 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9649 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9651 ;; Since sh[lr]d does not change the `reg' operand, that is done
9652 ;; separately, making all shifts emit pairs of shift double and normal
9653 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9654 ;; support a 63 bit shift, each shift where the count is in a reg expands
9655 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9657 ;; If the shift count is a constant, we need never emit more than one
9658 ;; shift pair, instead using moves and sign extension for counts greater
9661 (define_insn "*<mshift><mode>3"
9662 [(set (match_operand:SWI1248_AVX512BWDQ 0 "register_operand" "=k")
9663 (any_lshift:SWI1248_AVX512BWDQ (match_operand:SWI1248_AVX512BWDQ 1 "register_operand" "k")
9664 (match_operand:QI 2 "immediate_operand" "i")))]
9666 "k<mshift><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
9667 [(set_attr "type" "msklog")
9668 (set_attr "prefix" "vex")])
9670 (define_expand "ashl<mode>3"
9671 [(set (match_operand:SDWIM 0 "<shift_operand>")
9672 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9673 (match_operand:QI 2 "nonmemory_operand")))]
9675 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9677 (define_insn "*ashl<mode>3_doubleword"
9678 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9679 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9680 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9681 (clobber (reg:CC FLAGS_REG))]
9684 [(set_attr "type" "multi")])
9687 [(set (match_operand:DWI 0 "register_operand")
9688 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9689 (match_operand:QI 2 "nonmemory_operand")))
9690 (clobber (reg:CC FLAGS_REG))]
9691 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9693 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9695 ;; By default we don't ask for a scratch register, because when DWImode
9696 ;; values are manipulated, registers are already at a premium. But if
9697 ;; we have one handy, we won't turn it away.
9700 [(match_scratch:DWIH 3 "r")
9701 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9703 (match_operand:<DWI> 1 "nonmemory_operand")
9704 (match_operand:QI 2 "nonmemory_operand")))
9705 (clobber (reg:CC FLAGS_REG))])
9709 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9711 (define_insn "x86_64_shld"
9712 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9713 (ior:DI (ashift:DI (match_dup 0)
9714 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9715 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9716 (minus:QI (const_int 64) (match_dup 2)))))
9717 (clobber (reg:CC FLAGS_REG))]
9719 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9720 [(set_attr "type" "ishift")
9721 (set_attr "prefix_0f" "1")
9722 (set_attr "mode" "DI")
9723 (set_attr "athlon_decode" "vector")
9724 (set_attr "amdfam10_decode" "vector")
9725 (set_attr "bdver1_decode" "vector")])
9727 (define_insn "x86_shld"
9728 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9729 (ior:SI (ashift:SI (match_dup 0)
9730 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9731 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9732 (minus:QI (const_int 32) (match_dup 2)))))
9733 (clobber (reg:CC FLAGS_REG))]
9735 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9736 [(set_attr "type" "ishift")
9737 (set_attr "prefix_0f" "1")
9738 (set_attr "mode" "SI")
9739 (set_attr "pent_pair" "np")
9740 (set_attr "athlon_decode" "vector")
9741 (set_attr "amdfam10_decode" "vector")
9742 (set_attr "bdver1_decode" "vector")])
9744 (define_expand "x86_shift<mode>_adj_1"
9745 [(set (reg:CCZ FLAGS_REG)
9746 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9749 (set (match_operand:SWI48 0 "register_operand")
9750 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9751 (match_operand:SWI48 1 "register_operand")
9754 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9755 (match_operand:SWI48 3 "register_operand")
9758 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9760 (define_expand "x86_shift<mode>_adj_2"
9761 [(use (match_operand:SWI48 0 "register_operand"))
9762 (use (match_operand:SWI48 1 "register_operand"))
9763 (use (match_operand:QI 2 "register_operand"))]
9766 rtx_code_label *label = gen_label_rtx ();
9769 emit_insn (gen_testqi_ccz_1 (operands[2],
9770 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9772 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9773 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9774 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9775 gen_rtx_LABEL_REF (VOIDmode, label),
9777 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
9778 JUMP_LABEL (tmp) = label;
9780 emit_move_insn (operands[0], operands[1]);
9781 ix86_expand_clear (operands[1]);
9784 LABEL_NUSES (label) = 1;
9789 ;; Avoid useless masking of count operand.
9790 (define_insn "*ashl<mode>3_mask"
9791 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9793 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9796 (match_operand:SI 2 "register_operand" "c")
9797 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9798 (clobber (reg:CC FLAGS_REG))]
9799 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9800 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9801 == GET_MODE_BITSIZE (<MODE>mode)-1"
9803 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9805 [(set_attr "type" "ishift")
9806 (set_attr "mode" "<MODE>")])
9808 (define_insn "*bmi2_ashl<mode>3_1"
9809 [(set (match_operand:SWI48 0 "register_operand" "=r")
9810 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9811 (match_operand:SWI48 2 "register_operand" "r")))]
9813 "shlx\t{%2, %1, %0|%0, %1, %2}"
9814 [(set_attr "type" "ishiftx")
9815 (set_attr "mode" "<MODE>")])
9817 (define_insn "*ashl<mode>3_1"
9818 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9819 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9820 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9821 (clobber (reg:CC FLAGS_REG))]
9822 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9824 switch (get_attr_type (insn))
9831 gcc_assert (operands[2] == const1_rtx);
9832 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9833 return "add{<imodesuffix>}\t%0, %0";
9836 if (operands[2] == const1_rtx
9837 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9838 return "sal{<imodesuffix>}\t%0";
9840 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9843 [(set_attr "isa" "*,*,bmi2")
9845 (cond [(eq_attr "alternative" "1")
9846 (const_string "lea")
9847 (eq_attr "alternative" "2")
9848 (const_string "ishiftx")
9849 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9850 (match_operand 0 "register_operand"))
9851 (match_operand 2 "const1_operand"))
9852 (const_string "alu")
9854 (const_string "ishift")))
9855 (set (attr "length_immediate")
9857 (ior (eq_attr "type" "alu")
9858 (and (eq_attr "type" "ishift")
9859 (and (match_operand 2 "const1_operand")
9860 (ior (match_test "TARGET_SHIFT1")
9861 (match_test "optimize_function_for_size_p (cfun)")))))
9863 (const_string "*")))
9864 (set_attr "mode" "<MODE>")])
9866 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9868 [(set (match_operand:SWI48 0 "register_operand")
9869 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9870 (match_operand:QI 2 "register_operand")))
9871 (clobber (reg:CC FLAGS_REG))]
9872 "TARGET_BMI2 && reload_completed"
9874 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9875 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9877 (define_insn "*bmi2_ashlsi3_1_zext"
9878 [(set (match_operand:DI 0 "register_operand" "=r")
9880 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9881 (match_operand:SI 2 "register_operand" "r"))))]
9882 "TARGET_64BIT && TARGET_BMI2"
9883 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9884 [(set_attr "type" "ishiftx")
9885 (set_attr "mode" "SI")])
9887 (define_insn "*ashlsi3_1_zext"
9888 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9890 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9891 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9892 (clobber (reg:CC FLAGS_REG))]
9893 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9895 switch (get_attr_type (insn))
9902 gcc_assert (operands[2] == const1_rtx);
9903 return "add{l}\t%k0, %k0";
9906 if (operands[2] == const1_rtx
9907 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9908 return "sal{l}\t%k0";
9910 return "sal{l}\t{%2, %k0|%k0, %2}";
9913 [(set_attr "isa" "*,*,bmi2")
9915 (cond [(eq_attr "alternative" "1")
9916 (const_string "lea")
9917 (eq_attr "alternative" "2")
9918 (const_string "ishiftx")
9919 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9920 (match_operand 2 "const1_operand"))
9921 (const_string "alu")
9923 (const_string "ishift")))
9924 (set (attr "length_immediate")
9926 (ior (eq_attr "type" "alu")
9927 (and (eq_attr "type" "ishift")
9928 (and (match_operand 2 "const1_operand")
9929 (ior (match_test "TARGET_SHIFT1")
9930 (match_test "optimize_function_for_size_p (cfun)")))))
9932 (const_string "*")))
9933 (set_attr "mode" "SI")])
9935 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9937 [(set (match_operand:DI 0 "register_operand")
9939 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9940 (match_operand:QI 2 "register_operand"))))
9941 (clobber (reg:CC FLAGS_REG))]
9942 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9944 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9945 "operands[2] = gen_lowpart (SImode, operands[2]);")
9947 (define_insn "*ashlhi3_1"
9948 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9949 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9950 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9951 (clobber (reg:CC FLAGS_REG))]
9952 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9954 switch (get_attr_type (insn))
9960 gcc_assert (operands[2] == const1_rtx);
9961 return "add{w}\t%0, %0";
9964 if (operands[2] == const1_rtx
9965 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9966 return "sal{w}\t%0";
9968 return "sal{w}\t{%2, %0|%0, %2}";
9972 (cond [(eq_attr "alternative" "1")
9973 (const_string "lea")
9974 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9975 (match_operand 0 "register_operand"))
9976 (match_operand 2 "const1_operand"))
9977 (const_string "alu")
9979 (const_string "ishift")))
9980 (set (attr "length_immediate")
9982 (ior (eq_attr "type" "alu")
9983 (and (eq_attr "type" "ishift")
9984 (and (match_operand 2 "const1_operand")
9985 (ior (match_test "TARGET_SHIFT1")
9986 (match_test "optimize_function_for_size_p (cfun)")))))
9988 (const_string "*")))
9989 (set_attr "mode" "HI,SI")])
9991 ;; %%% Potential partial reg stall on alternative 1. What to do?
9992 (define_insn "*ashlqi3_1"
9993 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9994 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9995 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9996 (clobber (reg:CC FLAGS_REG))]
9997 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9999 switch (get_attr_type (insn))
10005 gcc_assert (operands[2] == const1_rtx);
10006 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
10007 return "add{l}\t%k0, %k0";
10009 return "add{b}\t%0, %0";
10012 if (operands[2] == const1_rtx
10013 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10015 if (get_attr_mode (insn) == MODE_SI)
10016 return "sal{l}\t%k0";
10018 return "sal{b}\t%0";
10022 if (get_attr_mode (insn) == MODE_SI)
10023 return "sal{l}\t{%2, %k0|%k0, %2}";
10025 return "sal{b}\t{%2, %0|%0, %2}";
10029 [(set (attr "type")
10030 (cond [(eq_attr "alternative" "2")
10031 (const_string "lea")
10032 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10033 (match_operand 0 "register_operand"))
10034 (match_operand 2 "const1_operand"))
10035 (const_string "alu")
10037 (const_string "ishift")))
10038 (set (attr "length_immediate")
10040 (ior (eq_attr "type" "alu")
10041 (and (eq_attr "type" "ishift")
10042 (and (match_operand 2 "const1_operand")
10043 (ior (match_test "TARGET_SHIFT1")
10044 (match_test "optimize_function_for_size_p (cfun)")))))
10046 (const_string "*")))
10047 (set_attr "mode" "QI,SI,SI")])
10049 (define_insn "*ashlqi3_1_slp"
10050 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10051 (ashift:QI (match_dup 0)
10052 (match_operand:QI 1 "nonmemory_operand" "cI")))
10053 (clobber (reg:CC FLAGS_REG))]
10054 "(optimize_function_for_size_p (cfun)
10055 || !TARGET_PARTIAL_FLAG_REG_STALL
10056 || (operands[1] == const1_rtx
10058 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10060 switch (get_attr_type (insn))
10063 gcc_assert (operands[1] == const1_rtx);
10064 return "add{b}\t%0, %0";
10067 if (operands[1] == const1_rtx
10068 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10069 return "sal{b}\t%0";
10071 return "sal{b}\t{%1, %0|%0, %1}";
10074 [(set (attr "type")
10075 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10076 (match_operand 0 "register_operand"))
10077 (match_operand 1 "const1_operand"))
10078 (const_string "alu")
10080 (const_string "ishift1")))
10081 (set (attr "length_immediate")
10083 (ior (eq_attr "type" "alu")
10084 (and (eq_attr "type" "ishift1")
10085 (and (match_operand 1 "const1_operand")
10086 (ior (match_test "TARGET_SHIFT1")
10087 (match_test "optimize_function_for_size_p (cfun)")))))
10089 (const_string "*")))
10090 (set_attr "mode" "QI")])
10092 ;; Convert ashift to the lea pattern to avoid flags dependency.
10094 [(set (match_operand 0 "register_operand")
10095 (ashift (match_operand 1 "index_register_operand")
10096 (match_operand:QI 2 "const_int_operand")))
10097 (clobber (reg:CC FLAGS_REG))]
10098 "GET_MODE (operands[0]) == GET_MODE (operands[1])
10099 && reload_completed
10100 && true_regnum (operands[0]) != true_regnum (operands[1])"
10103 machine_mode mode = GET_MODE (operands[0]);
10106 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
10109 operands[0] = gen_lowpart (mode, operands[0]);
10110 operands[1] = gen_lowpart (mode, operands[1]);
10113 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
10115 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
10117 emit_insn (gen_rtx_SET (operands[0], pat));
10121 ;; Convert ashift to the lea pattern to avoid flags dependency.
10123 [(set (match_operand:DI 0 "register_operand")
10125 (ashift:SI (match_operand:SI 1 "index_register_operand")
10126 (match_operand:QI 2 "const_int_operand"))))
10127 (clobber (reg:CC FLAGS_REG))]
10128 "TARGET_64BIT && reload_completed
10129 && true_regnum (operands[0]) != true_regnum (operands[1])"
10130 [(set (match_dup 0)
10131 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10133 operands[1] = gen_lowpart (SImode, operands[1]);
10134 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
10137 ;; This pattern can't accept a variable shift count, since shifts by
10138 ;; zero don't affect the flags. We assume that shifts by constant
10139 ;; zero are optimized away.
10140 (define_insn "*ashl<mode>3_cmp"
10141 [(set (reg FLAGS_REG)
10143 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10144 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10146 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10147 (ashift:SWI (match_dup 1) (match_dup 2)))]
10148 "(optimize_function_for_size_p (cfun)
10149 || !TARGET_PARTIAL_FLAG_REG_STALL
10150 || (operands[2] == const1_rtx
10152 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10153 && ix86_match_ccmode (insn, CCGOCmode)
10154 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10156 switch (get_attr_type (insn))
10159 gcc_assert (operands[2] == const1_rtx);
10160 return "add{<imodesuffix>}\t%0, %0";
10163 if (operands[2] == const1_rtx
10164 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10165 return "sal{<imodesuffix>}\t%0";
10167 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10170 [(set (attr "type")
10171 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10172 (match_operand 0 "register_operand"))
10173 (match_operand 2 "const1_operand"))
10174 (const_string "alu")
10176 (const_string "ishift")))
10177 (set (attr "length_immediate")
10179 (ior (eq_attr "type" "alu")
10180 (and (eq_attr "type" "ishift")
10181 (and (match_operand 2 "const1_operand")
10182 (ior (match_test "TARGET_SHIFT1")
10183 (match_test "optimize_function_for_size_p (cfun)")))))
10185 (const_string "*")))
10186 (set_attr "mode" "<MODE>")])
10188 (define_insn "*ashlsi3_cmp_zext"
10189 [(set (reg FLAGS_REG)
10191 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10192 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10194 (set (match_operand:DI 0 "register_operand" "=r")
10195 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10197 && (optimize_function_for_size_p (cfun)
10198 || !TARGET_PARTIAL_FLAG_REG_STALL
10199 || (operands[2] == const1_rtx
10201 || TARGET_DOUBLE_WITH_ADD)))
10202 && ix86_match_ccmode (insn, CCGOCmode)
10203 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10205 switch (get_attr_type (insn))
10208 gcc_assert (operands[2] == const1_rtx);
10209 return "add{l}\t%k0, %k0";
10212 if (operands[2] == const1_rtx
10213 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10214 return "sal{l}\t%k0";
10216 return "sal{l}\t{%2, %k0|%k0, %2}";
10219 [(set (attr "type")
10220 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
10221 (match_operand 2 "const1_operand"))
10222 (const_string "alu")
10224 (const_string "ishift")))
10225 (set (attr "length_immediate")
10227 (ior (eq_attr "type" "alu")
10228 (and (eq_attr "type" "ishift")
10229 (and (match_operand 2 "const1_operand")
10230 (ior (match_test "TARGET_SHIFT1")
10231 (match_test "optimize_function_for_size_p (cfun)")))))
10233 (const_string "*")))
10234 (set_attr "mode" "SI")])
10236 (define_insn "*ashl<mode>3_cconly"
10237 [(set (reg FLAGS_REG)
10239 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
10240 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10242 (clobber (match_scratch:SWI 0 "=<r>"))]
10243 "(optimize_function_for_size_p (cfun)
10244 || !TARGET_PARTIAL_FLAG_REG_STALL
10245 || (operands[2] == const1_rtx
10247 || TARGET_DOUBLE_WITH_ADD)))
10248 && ix86_match_ccmode (insn, CCGOCmode)"
10250 switch (get_attr_type (insn))
10253 gcc_assert (operands[2] == const1_rtx);
10254 return "add{<imodesuffix>}\t%0, %0";
10257 if (operands[2] == const1_rtx
10258 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10259 return "sal{<imodesuffix>}\t%0";
10261 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10264 [(set (attr "type")
10265 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10266 (match_operand 0 "register_operand"))
10267 (match_operand 2 "const1_operand"))
10268 (const_string "alu")
10270 (const_string "ishift")))
10271 (set (attr "length_immediate")
10273 (ior (eq_attr "type" "alu")
10274 (and (eq_attr "type" "ishift")
10275 (and (match_operand 2 "const1_operand")
10276 (ior (match_test "TARGET_SHIFT1")
10277 (match_test "optimize_function_for_size_p (cfun)")))))
10279 (const_string "*")))
10280 (set_attr "mode" "<MODE>")])
10282 ;; See comment above `ashl<mode>3' about how this works.
10284 (define_expand "<shift_insn><mode>3"
10285 [(set (match_operand:SDWIM 0 "<shift_operand>")
10286 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
10287 (match_operand:QI 2 "nonmemory_operand")))]
10289 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10291 ;; Avoid useless masking of count operand.
10292 (define_insn "*<shift_insn><mode>3_mask"
10293 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10295 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10298 (match_operand:SI 2 "register_operand" "c")
10299 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10300 (clobber (reg:CC FLAGS_REG))]
10301 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10302 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10303 == GET_MODE_BITSIZE (<MODE>mode)-1"
10305 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10307 [(set_attr "type" "ishift")
10308 (set_attr "mode" "<MODE>")])
10310 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
10311 [(set (match_operand:DWI 0 "register_operand" "=r")
10312 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10313 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10314 (clobber (reg:CC FLAGS_REG))]
10317 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10319 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10320 [(set_attr "type" "multi")])
10322 ;; By default we don't ask for a scratch register, because when DWImode
10323 ;; values are manipulated, registers are already at a premium. But if
10324 ;; we have one handy, we won't turn it away.
10327 [(match_scratch:DWIH 3 "r")
10328 (parallel [(set (match_operand:<DWI> 0 "register_operand")
10330 (match_operand:<DWI> 1 "register_operand")
10331 (match_operand:QI 2 "nonmemory_operand")))
10332 (clobber (reg:CC FLAGS_REG))])
10336 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
10338 (define_insn "x86_64_shrd"
10339 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10340 (ior:DI (lshiftrt:DI (match_dup 0)
10341 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10342 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10343 (minus:QI (const_int 64) (match_dup 2)))))
10344 (clobber (reg:CC FLAGS_REG))]
10346 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10347 [(set_attr "type" "ishift")
10348 (set_attr "prefix_0f" "1")
10349 (set_attr "mode" "DI")
10350 (set_attr "athlon_decode" "vector")
10351 (set_attr "amdfam10_decode" "vector")
10352 (set_attr "bdver1_decode" "vector")])
10354 (define_insn "x86_shrd"
10355 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10356 (ior:SI (lshiftrt:SI (match_dup 0)
10357 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10358 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10359 (minus:QI (const_int 32) (match_dup 2)))))
10360 (clobber (reg:CC FLAGS_REG))]
10362 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10363 [(set_attr "type" "ishift")
10364 (set_attr "prefix_0f" "1")
10365 (set_attr "mode" "SI")
10366 (set_attr "pent_pair" "np")
10367 (set_attr "athlon_decode" "vector")
10368 (set_attr "amdfam10_decode" "vector")
10369 (set_attr "bdver1_decode" "vector")])
10371 (define_insn "ashrdi3_cvt"
10372 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10373 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10374 (match_operand:QI 2 "const_int_operand")))
10375 (clobber (reg:CC FLAGS_REG))]
10376 "TARGET_64BIT && INTVAL (operands[2]) == 63
10377 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10378 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10381 sar{q}\t{%2, %0|%0, %2}"
10382 [(set_attr "type" "imovx,ishift")
10383 (set_attr "prefix_0f" "0,*")
10384 (set_attr "length_immediate" "0,*")
10385 (set_attr "modrm" "0,1")
10386 (set_attr "mode" "DI")])
10388 (define_insn "ashrsi3_cvt"
10389 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10390 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10391 (match_operand:QI 2 "const_int_operand")))
10392 (clobber (reg:CC FLAGS_REG))]
10393 "INTVAL (operands[2]) == 31
10394 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10395 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10398 sar{l}\t{%2, %0|%0, %2}"
10399 [(set_attr "type" "imovx,ishift")
10400 (set_attr "prefix_0f" "0,*")
10401 (set_attr "length_immediate" "0,*")
10402 (set_attr "modrm" "0,1")
10403 (set_attr "mode" "SI")])
10405 (define_insn "*ashrsi3_cvt_zext"
10406 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10408 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10409 (match_operand:QI 2 "const_int_operand"))))
10410 (clobber (reg:CC FLAGS_REG))]
10411 "TARGET_64BIT && INTVAL (operands[2]) == 31
10412 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10413 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10416 sar{l}\t{%2, %k0|%k0, %2}"
10417 [(set_attr "type" "imovx,ishift")
10418 (set_attr "prefix_0f" "0,*")
10419 (set_attr "length_immediate" "0,*")
10420 (set_attr "modrm" "0,1")
10421 (set_attr "mode" "SI")])
10423 (define_expand "x86_shift<mode>_adj_3"
10424 [(use (match_operand:SWI48 0 "register_operand"))
10425 (use (match_operand:SWI48 1 "register_operand"))
10426 (use (match_operand:QI 2 "register_operand"))]
10429 rtx_code_label *label = gen_label_rtx ();
10432 emit_insn (gen_testqi_ccz_1 (operands[2],
10433 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10435 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10436 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10437 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10438 gen_rtx_LABEL_REF (VOIDmode, label),
10440 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10441 JUMP_LABEL (tmp) = label;
10443 emit_move_insn (operands[0], operands[1]);
10444 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10445 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10446 emit_label (label);
10447 LABEL_NUSES (label) = 1;
10452 (define_insn "*bmi2_<shift_insn><mode>3_1"
10453 [(set (match_operand:SWI48 0 "register_operand" "=r")
10454 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10455 (match_operand:SWI48 2 "register_operand" "r")))]
10457 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10458 [(set_attr "type" "ishiftx")
10459 (set_attr "mode" "<MODE>")])
10461 (define_insn "*<shift_insn><mode>3_1"
10462 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10464 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10465 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10466 (clobber (reg:CC FLAGS_REG))]
10467 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10469 switch (get_attr_type (insn))
10475 if (operands[2] == const1_rtx
10476 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10477 return "<shift>{<imodesuffix>}\t%0";
10479 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10482 [(set_attr "isa" "*,bmi2")
10483 (set_attr "type" "ishift,ishiftx")
10484 (set (attr "length_immediate")
10486 (and (match_operand 2 "const1_operand")
10487 (ior (match_test "TARGET_SHIFT1")
10488 (match_test "optimize_function_for_size_p (cfun)")))
10490 (const_string "*")))
10491 (set_attr "mode" "<MODE>")])
10493 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10495 [(set (match_operand:SWI48 0 "register_operand")
10496 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10497 (match_operand:QI 2 "register_operand")))
10498 (clobber (reg:CC FLAGS_REG))]
10499 "TARGET_BMI2 && reload_completed"
10500 [(set (match_dup 0)
10501 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10502 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10504 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10505 [(set (match_operand:DI 0 "register_operand" "=r")
10507 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10508 (match_operand:SI 2 "register_operand" "r"))))]
10509 "TARGET_64BIT && TARGET_BMI2"
10510 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10511 [(set_attr "type" "ishiftx")
10512 (set_attr "mode" "SI")])
10514 (define_insn "*<shift_insn>si3_1_zext"
10515 [(set (match_operand:DI 0 "register_operand" "=r,r")
10517 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10518 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10519 (clobber (reg:CC FLAGS_REG))]
10520 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10522 switch (get_attr_type (insn))
10528 if (operands[2] == const1_rtx
10529 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10530 return "<shift>{l}\t%k0";
10532 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10535 [(set_attr "isa" "*,bmi2")
10536 (set_attr "type" "ishift,ishiftx")
10537 (set (attr "length_immediate")
10539 (and (match_operand 2 "const1_operand")
10540 (ior (match_test "TARGET_SHIFT1")
10541 (match_test "optimize_function_for_size_p (cfun)")))
10543 (const_string "*")))
10544 (set_attr "mode" "SI")])
10546 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10548 [(set (match_operand:DI 0 "register_operand")
10550 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10551 (match_operand:QI 2 "register_operand"))))
10552 (clobber (reg:CC FLAGS_REG))]
10553 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10554 [(set (match_dup 0)
10555 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10556 "operands[2] = gen_lowpart (SImode, operands[2]);")
10558 (define_insn "*<shift_insn><mode>3_1"
10559 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10561 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10562 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10563 (clobber (reg:CC FLAGS_REG))]
10564 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10566 if (operands[2] == const1_rtx
10567 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10568 return "<shift>{<imodesuffix>}\t%0";
10570 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10572 [(set_attr "type" "ishift")
10573 (set (attr "length_immediate")
10575 (and (match_operand 2 "const1_operand")
10576 (ior (match_test "TARGET_SHIFT1")
10577 (match_test "optimize_function_for_size_p (cfun)")))
10579 (const_string "*")))
10580 (set_attr "mode" "<MODE>")])
10582 (define_insn "*<shift_insn>qi3_1_slp"
10583 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10584 (any_shiftrt:QI (match_dup 0)
10585 (match_operand:QI 1 "nonmemory_operand" "cI")))
10586 (clobber (reg:CC FLAGS_REG))]
10587 "(optimize_function_for_size_p (cfun)
10588 || !TARGET_PARTIAL_REG_STALL
10589 || (operands[1] == const1_rtx
10590 && TARGET_SHIFT1))"
10592 if (operands[1] == const1_rtx
10593 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10594 return "<shift>{b}\t%0";
10596 return "<shift>{b}\t{%1, %0|%0, %1}";
10598 [(set_attr "type" "ishift1")
10599 (set (attr "length_immediate")
10601 (and (match_operand 1 "const1_operand")
10602 (ior (match_test "TARGET_SHIFT1")
10603 (match_test "optimize_function_for_size_p (cfun)")))
10605 (const_string "*")))
10606 (set_attr "mode" "QI")])
10608 ;; This pattern can't accept a variable shift count, since shifts by
10609 ;; zero don't affect the flags. We assume that shifts by constant
10610 ;; zero are optimized away.
10611 (define_insn "*<shift_insn><mode>3_cmp"
10612 [(set (reg FLAGS_REG)
10615 (match_operand:SWI 1 "nonimmediate_operand" "0")
10616 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10618 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10619 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10620 "(optimize_function_for_size_p (cfun)
10621 || !TARGET_PARTIAL_FLAG_REG_STALL
10622 || (operands[2] == const1_rtx
10624 && ix86_match_ccmode (insn, CCGOCmode)
10625 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10627 if (operands[2] == const1_rtx
10628 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10629 return "<shift>{<imodesuffix>}\t%0";
10631 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10633 [(set_attr "type" "ishift")
10634 (set (attr "length_immediate")
10636 (and (match_operand 2 "const1_operand")
10637 (ior (match_test "TARGET_SHIFT1")
10638 (match_test "optimize_function_for_size_p (cfun)")))
10640 (const_string "*")))
10641 (set_attr "mode" "<MODE>")])
10643 (define_insn "*<shift_insn>si3_cmp_zext"
10644 [(set (reg FLAGS_REG)
10646 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10647 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10649 (set (match_operand:DI 0 "register_operand" "=r")
10650 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10652 && (optimize_function_for_size_p (cfun)
10653 || !TARGET_PARTIAL_FLAG_REG_STALL
10654 || (operands[2] == const1_rtx
10656 && ix86_match_ccmode (insn, CCGOCmode)
10657 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10659 if (operands[2] == const1_rtx
10660 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10661 return "<shift>{l}\t%k0";
10663 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10665 [(set_attr "type" "ishift")
10666 (set (attr "length_immediate")
10668 (and (match_operand 2 "const1_operand")
10669 (ior (match_test "TARGET_SHIFT1")
10670 (match_test "optimize_function_for_size_p (cfun)")))
10672 (const_string "*")))
10673 (set_attr "mode" "SI")])
10675 (define_insn "*<shift_insn><mode>3_cconly"
10676 [(set (reg FLAGS_REG)
10679 (match_operand:SWI 1 "register_operand" "0")
10680 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10682 (clobber (match_scratch:SWI 0 "=<r>"))]
10683 "(optimize_function_for_size_p (cfun)
10684 || !TARGET_PARTIAL_FLAG_REG_STALL
10685 || (operands[2] == const1_rtx
10687 && ix86_match_ccmode (insn, CCGOCmode)"
10689 if (operands[2] == const1_rtx
10690 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10691 return "<shift>{<imodesuffix>}\t%0";
10693 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10695 [(set_attr "type" "ishift")
10696 (set (attr "length_immediate")
10698 (and (match_operand 2 "const1_operand")
10699 (ior (match_test "TARGET_SHIFT1")
10700 (match_test "optimize_function_for_size_p (cfun)")))
10702 (const_string "*")))
10703 (set_attr "mode" "<MODE>")])
10705 ;; Rotate instructions
10707 (define_expand "<rotate_insn>ti3"
10708 [(set (match_operand:TI 0 "register_operand")
10709 (any_rotate:TI (match_operand:TI 1 "register_operand")
10710 (match_operand:QI 2 "nonmemory_operand")))]
10713 if (const_1_to_63_operand (operands[2], VOIDmode))
10714 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10715 (operands[0], operands[1], operands[2]));
10722 (define_expand "<rotate_insn>di3"
10723 [(set (match_operand:DI 0 "shiftdi_operand")
10724 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10725 (match_operand:QI 2 "nonmemory_operand")))]
10729 ix86_expand_binary_operator (<CODE>, DImode, operands);
10730 else if (const_1_to_31_operand (operands[2], VOIDmode))
10731 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10732 (operands[0], operands[1], operands[2]));
10739 (define_expand "<rotate_insn><mode>3"
10740 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10741 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10742 (match_operand:QI 2 "nonmemory_operand")))]
10744 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10746 ;; Avoid useless masking of count operand.
10747 (define_insn "*<rotate_insn><mode>3_mask"
10748 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10750 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10753 (match_operand:SI 2 "register_operand" "c")
10754 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10755 (clobber (reg:CC FLAGS_REG))]
10756 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10757 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10758 == GET_MODE_BITSIZE (<MODE>mode)-1"
10760 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10762 [(set_attr "type" "rotate")
10763 (set_attr "mode" "<MODE>")])
10765 ;; Implement rotation using two double-precision
10766 ;; shift instructions and a scratch register.
10768 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10769 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10770 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10771 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10772 (clobber (reg:CC FLAGS_REG))
10773 (clobber (match_scratch:DWIH 3 "=&r"))]
10777 [(set (match_dup 3) (match_dup 4))
10779 [(set (match_dup 4)
10780 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10781 (lshiftrt:DWIH (match_dup 5)
10782 (minus:QI (match_dup 6) (match_dup 2)))))
10783 (clobber (reg:CC FLAGS_REG))])
10785 [(set (match_dup 5)
10786 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10787 (lshiftrt:DWIH (match_dup 3)
10788 (minus:QI (match_dup 6) (match_dup 2)))))
10789 (clobber (reg:CC FLAGS_REG))])]
10791 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10793 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10796 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10797 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10798 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10799 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10800 (clobber (reg:CC FLAGS_REG))
10801 (clobber (match_scratch:DWIH 3 "=&r"))]
10805 [(set (match_dup 3) (match_dup 4))
10807 [(set (match_dup 4)
10808 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10809 (ashift:DWIH (match_dup 5)
10810 (minus:QI (match_dup 6) (match_dup 2)))))
10811 (clobber (reg:CC FLAGS_REG))])
10813 [(set (match_dup 5)
10814 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10815 (ashift:DWIH (match_dup 3)
10816 (minus:QI (match_dup 6) (match_dup 2)))))
10817 (clobber (reg:CC FLAGS_REG))])]
10819 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10821 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10824 (define_insn "*bmi2_rorx<mode>3_1"
10825 [(set (match_operand:SWI48 0 "register_operand" "=r")
10826 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10827 (match_operand:QI 2 "immediate_operand" "<S>")))]
10829 "rorx\t{%2, %1, %0|%0, %1, %2}"
10830 [(set_attr "type" "rotatex")
10831 (set_attr "mode" "<MODE>")])
10833 (define_insn "*<rotate_insn><mode>3_1"
10834 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10836 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10837 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10838 (clobber (reg:CC FLAGS_REG))]
10839 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10841 switch (get_attr_type (insn))
10847 if (operands[2] == const1_rtx
10848 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10849 return "<rotate>{<imodesuffix>}\t%0";
10851 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10854 [(set_attr "isa" "*,bmi2")
10855 (set_attr "type" "rotate,rotatex")
10856 (set (attr "length_immediate")
10858 (and (eq_attr "type" "rotate")
10859 (and (match_operand 2 "const1_operand")
10860 (ior (match_test "TARGET_SHIFT1")
10861 (match_test "optimize_function_for_size_p (cfun)"))))
10863 (const_string "*")))
10864 (set_attr "mode" "<MODE>")])
10866 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10868 [(set (match_operand:SWI48 0 "register_operand")
10869 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10870 (match_operand:QI 2 "immediate_operand")))
10871 (clobber (reg:CC FLAGS_REG))]
10872 "TARGET_BMI2 && reload_completed"
10873 [(set (match_dup 0)
10874 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10877 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10881 [(set (match_operand:SWI48 0 "register_operand")
10882 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10883 (match_operand:QI 2 "immediate_operand")))
10884 (clobber (reg:CC FLAGS_REG))]
10885 "TARGET_BMI2 && reload_completed"
10886 [(set (match_dup 0)
10887 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10889 (define_insn "*bmi2_rorxsi3_1_zext"
10890 [(set (match_operand:DI 0 "register_operand" "=r")
10892 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10893 (match_operand:QI 2 "immediate_operand" "I"))))]
10894 "TARGET_64BIT && TARGET_BMI2"
10895 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10896 [(set_attr "type" "rotatex")
10897 (set_attr "mode" "SI")])
10899 (define_insn "*<rotate_insn>si3_1_zext"
10900 [(set (match_operand:DI 0 "register_operand" "=r,r")
10902 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10903 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10904 (clobber (reg:CC FLAGS_REG))]
10905 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10907 switch (get_attr_type (insn))
10913 if (operands[2] == const1_rtx
10914 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10915 return "<rotate>{l}\t%k0";
10917 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10920 [(set_attr "isa" "*,bmi2")
10921 (set_attr "type" "rotate,rotatex")
10922 (set (attr "length_immediate")
10924 (and (eq_attr "type" "rotate")
10925 (and (match_operand 2 "const1_operand")
10926 (ior (match_test "TARGET_SHIFT1")
10927 (match_test "optimize_function_for_size_p (cfun)"))))
10929 (const_string "*")))
10930 (set_attr "mode" "SI")])
10932 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10934 [(set (match_operand:DI 0 "register_operand")
10936 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10937 (match_operand:QI 2 "immediate_operand"))))
10938 (clobber (reg:CC FLAGS_REG))]
10939 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10940 [(set (match_dup 0)
10941 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10944 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10948 [(set (match_operand:DI 0 "register_operand")
10950 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10951 (match_operand:QI 2 "immediate_operand"))))
10952 (clobber (reg:CC FLAGS_REG))]
10953 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10954 [(set (match_dup 0)
10955 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10957 (define_insn "*<rotate_insn><mode>3_1"
10958 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10959 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10960 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10961 (clobber (reg:CC FLAGS_REG))]
10962 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10964 if (operands[2] == const1_rtx
10965 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10966 return "<rotate>{<imodesuffix>}\t%0";
10968 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10970 [(set_attr "type" "rotate")
10971 (set (attr "length_immediate")
10973 (and (match_operand 2 "const1_operand")
10974 (ior (match_test "TARGET_SHIFT1")
10975 (match_test "optimize_function_for_size_p (cfun)")))
10977 (const_string "*")))
10978 (set_attr "mode" "<MODE>")])
10980 (define_insn "*<rotate_insn>qi3_1_slp"
10981 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10982 (any_rotate:QI (match_dup 0)
10983 (match_operand:QI 1 "nonmemory_operand" "cI")))
10984 (clobber (reg:CC FLAGS_REG))]
10985 "(optimize_function_for_size_p (cfun)
10986 || !TARGET_PARTIAL_REG_STALL
10987 || (operands[1] == const1_rtx
10988 && TARGET_SHIFT1))"
10990 if (operands[1] == const1_rtx
10991 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10992 return "<rotate>{b}\t%0";
10994 return "<rotate>{b}\t{%1, %0|%0, %1}";
10996 [(set_attr "type" "rotate1")
10997 (set (attr "length_immediate")
10999 (and (match_operand 1 "const1_operand")
11000 (ior (match_test "TARGET_SHIFT1")
11001 (match_test "optimize_function_for_size_p (cfun)")))
11003 (const_string "*")))
11004 (set_attr "mode" "QI")])
11007 [(set (match_operand:HI 0 "register_operand")
11008 (any_rotate:HI (match_dup 0) (const_int 8)))
11009 (clobber (reg:CC FLAGS_REG))]
11011 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
11012 [(parallel [(set (strict_low_part (match_dup 0))
11013 (bswap:HI (match_dup 0)))
11014 (clobber (reg:CC FLAGS_REG))])])
11016 ;; Bit set / bit test instructions
11018 ;; %%% bts, btr, btc, bt.
11019 ;; In general these instructions are *slow* when applied to memory,
11020 ;; since they enforce atomic operation. When applied to registers,
11021 ;; it depends on the cpu implementation. They're never faster than
11022 ;; the corresponding and/ior/xor operations, so with 32-bit there's
11023 ;; no point. But in 64-bit, we can't hold the relevant immediates
11024 ;; within the instruction itself, so operating on bits in the high
11025 ;; 32-bits of a register becomes easier.
11027 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
11028 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
11029 ;; negdf respectively, so they can never be disabled entirely.
11031 (define_insn "*btsq"
11032 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
11034 (match_operand 1 "const_0_to_63_operand" "J"))
11036 (clobber (reg:CC FLAGS_REG))]
11037 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11038 "bts{q}\t{%1, %0|%0, %1}"
11039 [(set_attr "type" "alu1")
11040 (set_attr "prefix_0f" "1")
11041 (set_attr "znver1_decode" "double")
11042 (set_attr "mode" "DI")])
11044 (define_insn "*btrq"
11045 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
11047 (match_operand 1 "const_0_to_63_operand" "J"))
11049 (clobber (reg:CC FLAGS_REG))]
11050 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11051 "btr{q}\t{%1, %0|%0, %1}"
11052 [(set_attr "type" "alu1")
11053 (set_attr "prefix_0f" "1")
11054 (set_attr "znver1_decode" "double")
11055 (set_attr "mode" "DI")])
11057 (define_insn "*btcq"
11058 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
11060 (match_operand 1 "const_0_to_63_operand" "J"))
11061 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
11062 (clobber (reg:CC FLAGS_REG))]
11063 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11064 "btc{q}\t{%1, %0|%0, %1}"
11065 [(set_attr "type" "alu1")
11066 (set_attr "prefix_0f" "1")
11067 (set_attr "znver1_decode" "double")
11068 (set_attr "mode" "DI")])
11070 ;; Allow Nocona to avoid these instructions if a register is available.
11073 [(match_scratch:DI 2 "r")
11074 (parallel [(set (zero_extract:DI
11075 (match_operand:DI 0 "register_operand")
11077 (match_operand 1 "const_0_to_63_operand"))
11079 (clobber (reg:CC FLAGS_REG))])]
11080 "TARGET_64BIT && !TARGET_USE_BT"
11081 [(parallel [(set (match_dup 0)
11082 (ior:DI (match_dup 0) (match_dup 3)))
11083 (clobber (reg:CC FLAGS_REG))])]
11085 int i = INTVAL (operands[1]);
11087 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11089 if (!x86_64_immediate_operand (operands[3], DImode))
11091 emit_move_insn (operands[2], operands[3]);
11092 operands[3] = operands[2];
11097 [(match_scratch:DI 2 "r")
11098 (parallel [(set (zero_extract:DI
11099 (match_operand:DI 0 "register_operand")
11101 (match_operand 1 "const_0_to_63_operand"))
11103 (clobber (reg:CC FLAGS_REG))])]
11104 "TARGET_64BIT && !TARGET_USE_BT"
11105 [(parallel [(set (match_dup 0)
11106 (and:DI (match_dup 0) (match_dup 3)))
11107 (clobber (reg:CC FLAGS_REG))])]
11109 int i = INTVAL (operands[1]);
11111 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
11113 if (!x86_64_immediate_operand (operands[3], DImode))
11115 emit_move_insn (operands[2], operands[3]);
11116 operands[3] = operands[2];
11121 [(match_scratch:DI 2 "r")
11122 (parallel [(set (zero_extract:DI
11123 (match_operand:DI 0 "register_operand")
11125 (match_operand 1 "const_0_to_63_operand"))
11126 (not:DI (zero_extract:DI
11127 (match_dup 0) (const_int 1) (match_dup 1))))
11128 (clobber (reg:CC FLAGS_REG))])]
11129 "TARGET_64BIT && !TARGET_USE_BT"
11130 [(parallel [(set (match_dup 0)
11131 (xor:DI (match_dup 0) (match_dup 3)))
11132 (clobber (reg:CC FLAGS_REG))])]
11134 int i = INTVAL (operands[1]);
11136 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11138 if (!x86_64_immediate_operand (operands[3], DImode))
11140 emit_move_insn (operands[2], operands[3]);
11141 operands[3] = operands[2];
11145 (define_insn "*bt<mode>"
11146 [(set (reg:CCC FLAGS_REG)
11148 (zero_extract:SWI48
11149 (match_operand:SWI48 0 "register_operand" "r")
11151 (match_operand:SI 1 "nonmemory_operand" "rN"))
11155 switch (get_attr_mode (insn))
11158 return "bt{l}\t{%1, %k0|%k0, %1}";
11161 return "bt{q}\t{%q1, %0|%0, %q1}";
11164 gcc_unreachable ();
11167 [(set_attr "type" "alu1")
11168 (set_attr "prefix_0f" "1")
11171 (and (match_test "CONST_INT_P (operands[1])")
11172 (match_test "INTVAL (operands[1]) < 32"))
11173 (const_string "SI")
11174 (const_string "<MODE>")))])
11176 (define_insn_and_split "*jcc_bt<mode>"
11178 (if_then_else (match_operator 0 "bt_comparison_operator"
11179 [(zero_extract:SWI48
11180 (match_operand:SWI48 1 "register_operand")
11182 (match_operand:SI 2 "nonmemory_operand"))
11184 (label_ref (match_operand 3))
11186 (clobber (reg:CC FLAGS_REG))]
11187 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11188 && (CONST_INT_P (operands[2])
11189 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
11190 && INTVAL (operands[2])
11191 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
11192 : register_operand (operands[2], SImode))
11193 && can_create_pseudo_p ()"
11196 [(set (reg:CCC FLAGS_REG)
11198 (zero_extract:SWI48
11204 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11205 (label_ref (match_dup 3))
11208 operands[0] = shallow_copy_rtx (operands[0]);
11209 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11212 (define_insn_and_split "*jcc_bt<mode>_1"
11214 (if_then_else (match_operator 0 "bt_comparison_operator"
11215 [(zero_extract:SWI48
11216 (match_operand:SWI48 1 "register_operand")
11219 (match_operand:QI 2 "register_operand")))
11221 (label_ref (match_operand 3))
11223 (clobber (reg:CC FLAGS_REG))]
11224 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11225 && can_create_pseudo_p ()"
11228 [(set (reg:CCC FLAGS_REG)
11230 (zero_extract:SWI48
11236 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11237 (label_ref (match_dup 3))
11240 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11241 operands[0] = shallow_copy_rtx (operands[0]);
11242 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11245 ;; Avoid useless masking of bit offset operand.
11246 (define_insn_and_split "*jcc_bt<mode>_mask"
11248 (if_then_else (match_operator 0 "bt_comparison_operator"
11249 [(zero_extract:SWI48
11250 (match_operand:SWI48 1 "register_operand")
11253 (match_operand:SI 2 "register_operand")
11254 (match_operand 3 "const_int_operand")))])
11255 (label_ref (match_operand 4))
11257 (clobber (reg:CC FLAGS_REG))]
11258 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11259 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11260 == GET_MODE_BITSIZE (<MODE>mode)-1
11261 && can_create_pseudo_p ()"
11264 [(set (reg:CCC FLAGS_REG)
11266 (zero_extract:SWI48
11272 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11273 (label_ref (match_dup 4))
11276 operands[0] = shallow_copy_rtx (operands[0]);
11277 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11280 ;; Store-flag instructions.
11282 ;; For all sCOND expanders, also expand the compare or test insn that
11283 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
11285 (define_insn_and_split "*setcc_di_1"
11286 [(set (match_operand:DI 0 "register_operand" "=q")
11287 (match_operator:DI 1 "ix86_comparison_operator"
11288 [(reg FLAGS_REG) (const_int 0)]))]
11289 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
11291 "&& reload_completed"
11292 [(set (match_dup 2) (match_dup 1))
11293 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
11295 operands[1] = shallow_copy_rtx (operands[1]);
11296 PUT_MODE (operands[1], QImode);
11297 operands[2] = gen_lowpart (QImode, operands[0]);
11300 (define_insn_and_split "*setcc_si_1_and"
11301 [(set (match_operand:SI 0 "register_operand" "=q")
11302 (match_operator:SI 1 "ix86_comparison_operator"
11303 [(reg FLAGS_REG) (const_int 0)]))
11304 (clobber (reg:CC FLAGS_REG))]
11305 "!TARGET_PARTIAL_REG_STALL
11306 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
11308 "&& reload_completed"
11309 [(set (match_dup 2) (match_dup 1))
11310 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
11311 (clobber (reg:CC FLAGS_REG))])]
11313 operands[1] = shallow_copy_rtx (operands[1]);
11314 PUT_MODE (operands[1], QImode);
11315 operands[2] = gen_lowpart (QImode, operands[0]);
11318 (define_insn_and_split "*setcc_si_1_movzbl"
11319 [(set (match_operand:SI 0 "register_operand" "=q")
11320 (match_operator:SI 1 "ix86_comparison_operator"
11321 [(reg FLAGS_REG) (const_int 0)]))]
11322 "!TARGET_PARTIAL_REG_STALL
11323 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
11325 "&& reload_completed"
11326 [(set (match_dup 2) (match_dup 1))
11327 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
11329 operands[1] = shallow_copy_rtx (operands[1]);
11330 PUT_MODE (operands[1], QImode);
11331 operands[2] = gen_lowpart (QImode, operands[0]);
11334 (define_insn "*setcc_qi"
11335 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11336 (match_operator:QI 1 "ix86_comparison_operator"
11337 [(reg FLAGS_REG) (const_int 0)]))]
11340 [(set_attr "type" "setcc")
11341 (set_attr "mode" "QI")])
11343 (define_insn "*setcc_qi_slp"
11344 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11345 (match_operator:QI 1 "ix86_comparison_operator"
11346 [(reg FLAGS_REG) (const_int 0)]))]
11349 [(set_attr "type" "setcc")
11350 (set_attr "mode" "QI")])
11352 ;; In general it is not safe to assume too much about CCmode registers,
11353 ;; so simplify-rtx stops when it sees a second one. Under certain
11354 ;; conditions this is safe on x86, so help combine not create
11361 [(set (match_operand:QI 0 "nonimmediate_operand")
11362 (ne:QI (match_operator 1 "ix86_comparison_operator"
11363 [(reg FLAGS_REG) (const_int 0)])
11366 [(set (match_dup 0) (match_dup 1))]
11368 operands[1] = shallow_copy_rtx (operands[1]);
11369 PUT_MODE (operands[1], QImode);
11373 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11374 (ne:QI (match_operator 1 "ix86_comparison_operator"
11375 [(reg FLAGS_REG) (const_int 0)])
11378 [(set (match_dup 0) (match_dup 1))]
11380 operands[1] = shallow_copy_rtx (operands[1]);
11381 PUT_MODE (operands[1], QImode);
11385 [(set (match_operand:QI 0 "nonimmediate_operand")
11386 (eq:QI (match_operator 1 "ix86_comparison_operator"
11387 [(reg FLAGS_REG) (const_int 0)])
11390 [(set (match_dup 0) (match_dup 1))]
11392 operands[1] = shallow_copy_rtx (operands[1]);
11393 PUT_MODE (operands[1], QImode);
11394 PUT_CODE (operands[1],
11395 ix86_reverse_condition (GET_CODE (operands[1]),
11396 GET_MODE (XEXP (operands[1], 0))));
11398 /* Make sure that (a) the CCmode we have for the flags is strong
11399 enough for the reversed compare or (b) we have a valid FP compare. */
11400 if (! ix86_comparison_operator (operands[1], VOIDmode))
11405 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11406 (eq:QI (match_operator 1 "ix86_comparison_operator"
11407 [(reg FLAGS_REG) (const_int 0)])
11410 [(set (match_dup 0) (match_dup 1))]
11412 operands[1] = shallow_copy_rtx (operands[1]);
11413 PUT_MODE (operands[1], QImode);
11414 PUT_CODE (operands[1],
11415 ix86_reverse_condition (GET_CODE (operands[1]),
11416 GET_MODE (XEXP (operands[1], 0))));
11418 /* Make sure that (a) the CCmode we have for the flags is strong
11419 enough for the reversed compare or (b) we have a valid FP compare. */
11420 if (! ix86_comparison_operator (operands[1], VOIDmode))
11424 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
11425 ;; subsequent logical operations are used to imitate conditional moves.
11426 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
11429 (define_insn "setcc_<mode>_sse"
11430 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
11431 (match_operator:MODEF 3 "sse_comparison_operator"
11432 [(match_operand:MODEF 1 "register_operand" "0,x")
11433 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
11434 "SSE_FLOAT_MODE_P (<MODE>mode)"
11436 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
11437 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
11438 [(set_attr "isa" "noavx,avx")
11439 (set_attr "type" "ssecmp")
11440 (set_attr "length_immediate" "1")
11441 (set_attr "prefix" "orig,vex")
11442 (set_attr "mode" "<MODE>")])
11444 ;; Basic conditional jump instructions.
11445 ;; We ignore the overflow flag for signed branch instructions.
11447 (define_insn "*jcc_1"
11449 (if_then_else (match_operator 1 "ix86_comparison_operator"
11450 [(reg FLAGS_REG) (const_int 0)])
11451 (label_ref (match_operand 0))
11455 [(set_attr "type" "ibr")
11456 (set_attr "modrm" "0")
11457 (set (attr "length")
11459 (and (ge (minus (match_dup 0) (pc))
11461 (lt (minus (match_dup 0) (pc))
11465 (set_attr "maybe_prefix_bnd" "1")])
11467 (define_insn "*jcc_2"
11469 (if_then_else (match_operator 1 "ix86_comparison_operator"
11470 [(reg FLAGS_REG) (const_int 0)])
11472 (label_ref (match_operand 0))))]
11475 [(set_attr "type" "ibr")
11476 (set_attr "modrm" "0")
11477 (set (attr "length")
11479 (and (ge (minus (match_dup 0) (pc))
11481 (lt (minus (match_dup 0) (pc))
11485 (set_attr "maybe_prefix_bnd" "1")])
11487 ;; In general it is not safe to assume too much about CCmode registers,
11488 ;; so simplify-rtx stops when it sees a second one. Under certain
11489 ;; conditions this is safe on x86, so help combine not create
11497 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11498 [(reg FLAGS_REG) (const_int 0)])
11500 (label_ref (match_operand 1))
11504 (if_then_else (match_dup 0)
11505 (label_ref (match_dup 1))
11508 operands[0] = shallow_copy_rtx (operands[0]);
11509 PUT_MODE (operands[0], VOIDmode);
11514 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11515 [(reg FLAGS_REG) (const_int 0)])
11517 (label_ref (match_operand 1))
11521 (if_then_else (match_dup 0)
11522 (label_ref (match_dup 1))
11525 operands[0] = shallow_copy_rtx (operands[0]);
11526 PUT_MODE (operands[0], VOIDmode);
11527 PUT_CODE (operands[0],
11528 ix86_reverse_condition (GET_CODE (operands[0]),
11529 GET_MODE (XEXP (operands[0], 0))));
11531 /* Make sure that (a) the CCmode we have for the flags is strong
11532 enough for the reversed compare or (b) we have a valid FP compare. */
11533 if (! ix86_comparison_operator (operands[0], VOIDmode))
11537 ;; Define combination compare-and-branch fp compare instructions to help
11540 (define_insn "*jcc<mode>_0_i387"
11542 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11543 [(match_operand:X87MODEF 1 "register_operand" "f")
11544 (match_operand:X87MODEF 2 "const0_operand")])
11545 (label_ref (match_operand 3))
11547 (clobber (reg:CCFP FPSR_REG))
11548 (clobber (reg:CCFP FLAGS_REG))
11549 (clobber (match_scratch:HI 4 "=a"))]
11550 "TARGET_80387 && !TARGET_CMOVE"
11553 (define_insn "*jcc<mode>_0_r_i387"
11555 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11556 [(match_operand:X87MODEF 1 "register_operand" "f")
11557 (match_operand:X87MODEF 2 "const0_operand")])
11559 (label_ref (match_operand 3))))
11560 (clobber (reg:CCFP FPSR_REG))
11561 (clobber (reg:CCFP FLAGS_REG))
11562 (clobber (match_scratch:HI 4 "=a"))]
11563 "TARGET_80387 && !TARGET_CMOVE"
11566 (define_insn "*jccxf_i387"
11568 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11569 [(match_operand:XF 1 "register_operand" "f")
11570 (match_operand:XF 2 "register_operand" "f")])
11571 (label_ref (match_operand 3))
11573 (clobber (reg:CCFP FPSR_REG))
11574 (clobber (reg:CCFP FLAGS_REG))
11575 (clobber (match_scratch:HI 4 "=a"))]
11576 "TARGET_80387 && !TARGET_CMOVE"
11579 (define_insn "*jccxf_r_i387"
11581 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11582 [(match_operand:XF 1 "register_operand" "f")
11583 (match_operand:XF 2 "register_operand" "f")])
11585 (label_ref (match_operand 3))))
11586 (clobber (reg:CCFP FPSR_REG))
11587 (clobber (reg:CCFP FLAGS_REG))
11588 (clobber (match_scratch:HI 4 "=a"))]
11589 "TARGET_80387 && !TARGET_CMOVE"
11592 (define_insn "*jcc<mode>_i387"
11594 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11595 [(match_operand:MODEF 1 "register_operand" "f")
11596 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11597 (label_ref (match_operand 3))
11599 (clobber (reg:CCFP FPSR_REG))
11600 (clobber (reg:CCFP FLAGS_REG))
11601 (clobber (match_scratch:HI 4 "=a"))]
11602 "TARGET_80387 && !TARGET_CMOVE"
11605 (define_insn "*jcc<mode>_r_i387"
11607 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11608 [(match_operand:MODEF 1 "register_operand" "f")
11609 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11611 (label_ref (match_operand 3))))
11612 (clobber (reg:CCFP FPSR_REG))
11613 (clobber (reg:CCFP FLAGS_REG))
11614 (clobber (match_scratch:HI 4 "=a"))]
11615 "TARGET_80387 && !TARGET_CMOVE"
11618 (define_insn "*jccu<mode>_i387"
11620 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11621 [(match_operand:X87MODEF 1 "register_operand" "f")
11622 (match_operand:X87MODEF 2 "register_operand" "f")])
11623 (label_ref (match_operand 3))
11625 (clobber (reg:CCFP FPSR_REG))
11626 (clobber (reg:CCFP FLAGS_REG))
11627 (clobber (match_scratch:HI 4 "=a"))]
11628 "TARGET_80387 && !TARGET_CMOVE"
11631 (define_insn "*jccu<mode>_r_i387"
11633 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11634 [(match_operand:X87MODEF 1 "register_operand" "f")
11635 (match_operand:X87MODEF 2 "register_operand" "f")])
11637 (label_ref (match_operand 3))))
11638 (clobber (reg:CCFP FPSR_REG))
11639 (clobber (reg:CCFP FLAGS_REG))
11640 (clobber (match_scratch:HI 4 "=a"))]
11641 "TARGET_80387 && !TARGET_CMOVE"
11646 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11647 [(match_operand:X87MODEF 1 "register_operand")
11648 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11650 (match_operand 4)))
11651 (clobber (reg:CCFP FPSR_REG))
11652 (clobber (reg:CCFP FLAGS_REG))]
11653 "TARGET_80387 && !TARGET_CMOVE
11654 && reload_completed"
11657 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11658 operands[3], operands[4], NULL_RTX);
11664 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11665 [(match_operand:X87MODEF 1 "register_operand")
11666 (match_operand:X87MODEF 2 "general_operand")])
11668 (match_operand 4)))
11669 (clobber (reg:CCFP FPSR_REG))
11670 (clobber (reg:CCFP FLAGS_REG))
11671 (clobber (match_scratch:HI 5))]
11672 "TARGET_80387 && !TARGET_CMOVE
11673 && reload_completed"
11676 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11677 operands[3], operands[4], operands[5]);
11681 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11682 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11683 ;; with a precedence over other operators and is always put in the first
11684 ;; place. Swap condition and operands to match ficom instruction.
11686 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11689 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11690 [(match_operator:X87MODEF 1 "float_operator"
11691 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11692 (match_operand:X87MODEF 3 "register_operand" "f")])
11693 (label_ref (match_operand 4))
11695 (clobber (reg:CCFP FPSR_REG))
11696 (clobber (reg:CCFP FLAGS_REG))
11697 (clobber (match_scratch:HI 5 "=a"))]
11698 "TARGET_80387 && !TARGET_CMOVE
11699 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11700 || optimize_function_for_size_p (cfun))"
11703 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11706 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11707 [(match_operator:X87MODEF 1 "float_operator"
11708 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11709 (match_operand:X87MODEF 3 "register_operand" "f")])
11711 (label_ref (match_operand 4))))
11712 (clobber (reg:CCFP FPSR_REG))
11713 (clobber (reg:CCFP FLAGS_REG))
11714 (clobber (match_scratch:HI 5 "=a"))]
11715 "TARGET_80387 && !TARGET_CMOVE
11716 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11717 || optimize_function_for_size_p (cfun))"
11723 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11724 [(match_operator:X87MODEF 1 "float_operator"
11725 [(match_operand:SWI24 2 "memory_operand")])
11726 (match_operand:X87MODEF 3 "register_operand")])
11728 (match_operand 5)))
11729 (clobber (reg:CCFP FPSR_REG))
11730 (clobber (reg:CCFP FLAGS_REG))
11731 (clobber (match_scratch:HI 6))]
11732 "TARGET_80387 && !TARGET_CMOVE
11733 && reload_completed"
11736 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11737 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11738 operands[4], operands[5], operands[6]);
11742 ;; Unconditional and other jump instructions
11744 (define_insn "jump"
11746 (label_ref (match_operand 0)))]
11749 [(set_attr "type" "ibr")
11750 (set_attr "modrm" "0")
11751 (set (attr "length")
11753 (and (ge (minus (match_dup 0) (pc))
11755 (lt (minus (match_dup 0) (pc))
11759 (set_attr "maybe_prefix_bnd" "1")])
11761 (define_expand "indirect_jump"
11762 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11766 operands[0] = convert_memory_address (word_mode, operands[0]);
11769 (define_insn "*indirect_jump"
11770 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11773 [(set_attr "type" "ibr")
11774 (set_attr "length_immediate" "0")
11775 (set_attr "maybe_prefix_bnd" "1")])
11777 (define_expand "tablejump"
11778 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11779 (use (label_ref (match_operand 1)))])]
11782 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11783 relative. Convert the relative address to an absolute address. */
11787 enum rtx_code code;
11789 /* We can't use @GOTOFF for text labels on VxWorks;
11790 see gotoff_operand. */
11791 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11795 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11797 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11801 op1 = pic_offset_table_rtx;
11806 op0 = pic_offset_table_rtx;
11810 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11815 operands[0] = convert_memory_address (word_mode, operands[0]);
11818 (define_insn "*tablejump_1"
11819 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11820 (use (label_ref (match_operand 1)))]
11823 [(set_attr "type" "ibr")
11824 (set_attr "length_immediate" "0")
11825 (set_attr "maybe_prefix_bnd" "1")])
11827 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11830 [(set (reg FLAGS_REG) (match_operand 0))
11831 (set (match_operand:QI 1 "register_operand")
11832 (match_operator:QI 2 "ix86_comparison_operator"
11833 [(reg FLAGS_REG) (const_int 0)]))
11834 (set (match_operand 3 "any_QIreg_operand")
11835 (zero_extend (match_dup 1)))]
11836 "(peep2_reg_dead_p (3, operands[1])
11837 || operands_match_p (operands[1], operands[3]))
11838 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11839 [(set (match_dup 4) (match_dup 0))
11840 (set (strict_low_part (match_dup 5))
11843 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11844 operands[5] = gen_lowpart (QImode, operands[3]);
11845 ix86_expand_clear (operands[3]);
11849 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11850 (match_operand 4)])
11851 (set (match_operand:QI 1 "register_operand")
11852 (match_operator:QI 2 "ix86_comparison_operator"
11853 [(reg FLAGS_REG) (const_int 0)]))
11854 (set (match_operand 3 "any_QIreg_operand")
11855 (zero_extend (match_dup 1)))]
11856 "(peep2_reg_dead_p (3, operands[1])
11857 || operands_match_p (operands[1], operands[3]))
11858 && ! reg_overlap_mentioned_p (operands[3], operands[0])
11859 && ! reg_set_p (operands[3], operands[4])"
11860 [(parallel [(set (match_dup 5) (match_dup 0))
11862 (set (strict_low_part (match_dup 6))
11865 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11866 operands[6] = gen_lowpart (QImode, operands[3]);
11867 ix86_expand_clear (operands[3]);
11870 ;; Similar, but match zero extend with andsi3.
11873 [(set (reg FLAGS_REG) (match_operand 0))
11874 (set (match_operand:QI 1 "register_operand")
11875 (match_operator:QI 2 "ix86_comparison_operator"
11876 [(reg FLAGS_REG) (const_int 0)]))
11877 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
11878 (and:SI (match_dup 3) (const_int 255)))
11879 (clobber (reg:CC FLAGS_REG))])]
11880 "REGNO (operands[1]) == REGNO (operands[3])
11881 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11882 [(set (match_dup 4) (match_dup 0))
11883 (set (strict_low_part (match_dup 5))
11886 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11887 operands[5] = gen_lowpart (QImode, operands[3]);
11888 ix86_expand_clear (operands[3]);
11892 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11893 (match_operand 4)])
11894 (set (match_operand:QI 1 "register_operand")
11895 (match_operator:QI 2 "ix86_comparison_operator"
11896 [(reg FLAGS_REG) (const_int 0)]))
11897 (parallel [(set (match_operand 3 "any_QIreg_operand")
11898 (zero_extend (match_dup 1)))
11899 (clobber (reg:CC FLAGS_REG))])]
11900 "(peep2_reg_dead_p (3, operands[1])
11901 || operands_match_p (operands[1], operands[3]))
11902 && ! reg_overlap_mentioned_p (operands[3], operands[0])
11903 && ! reg_set_p (operands[3], operands[4])"
11904 [(parallel [(set (match_dup 5) (match_dup 0))
11906 (set (strict_low_part (match_dup 6))
11909 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11910 operands[6] = gen_lowpart (QImode, operands[3]);
11911 ix86_expand_clear (operands[3]);
11914 ;; Call instructions.
11916 ;; The predicates normally associated with named expanders are not properly
11917 ;; checked for calls. This is a bug in the generic code, but it isn't that
11918 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11920 ;; P6 processors will jump to the address after the decrement when %esp
11921 ;; is used as a call operand, so they will execute return address as a code.
11922 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11924 ;; Register constraint for call instruction.
11925 (define_mode_attr c [(SI "l") (DI "r")])
11927 ;; Call subroutine returning no value.
11929 (define_expand "call"
11930 [(call (match_operand:QI 0)
11932 (use (match_operand 2))]
11935 ix86_expand_call (NULL, operands[0], operands[1],
11936 operands[2], NULL, false);
11940 (define_expand "sibcall"
11941 [(call (match_operand:QI 0)
11943 (use (match_operand 2))]
11946 ix86_expand_call (NULL, operands[0], operands[1],
11947 operands[2], NULL, true);
11951 (define_insn "*call"
11952 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11953 (match_operand 1))]
11954 "!SIBLING_CALL_P (insn)"
11955 "* return ix86_output_call_insn (insn, operands[0]);"
11956 [(set_attr "type" "call")])
11958 ;; This covers both call and sibcall since only GOT slot is allowed.
11959 (define_insn "*call_got_x32"
11960 [(call (mem:QI (zero_extend:DI
11961 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
11962 (match_operand 1))]
11964 "* return ix86_output_call_insn (insn, operands[0]);"
11965 [(set_attr "type" "call")])
11967 ;; Since sibcall never returns, we can only use call-clobbered register
11969 (define_insn "*sibcall_GOT_32"
11972 (match_operand:SI 0 "register_no_elim_operand" "U")
11973 (match_operand:SI 1 "GOT32_symbol_operand"))))
11974 (match_operand 2))]
11975 "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11977 rtx fnaddr = gen_rtx_PLUS (Pmode, operands[0], operands[1]);
11978 fnaddr = gen_const_mem (Pmode, fnaddr);
11979 return ix86_output_call_insn (insn, fnaddr);
11981 [(set_attr "type" "call")])
11983 (define_insn "*sibcall"
11984 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11985 (match_operand 1))]
11986 "SIBLING_CALL_P (insn)"
11987 "* return ix86_output_call_insn (insn, operands[0]);"
11988 [(set_attr "type" "call")])
11990 (define_insn "*sibcall_memory"
11991 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11993 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11995 "* return ix86_output_call_insn (insn, operands[0]);"
11996 [(set_attr "type" "call")])
11999 [(set (match_operand:W 0 "register_operand")
12000 (match_operand:W 1 "memory_operand"))
12001 (call (mem:QI (match_dup 0))
12002 (match_operand 3))]
12003 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
12004 && !reg_mentioned_p (operands[0],
12005 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12006 [(parallel [(call (mem:QI (match_dup 1))
12008 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12011 [(set (match_operand:W 0 "register_operand")
12012 (match_operand:W 1 "memory_operand"))
12013 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12014 (call (mem:QI (match_dup 0))
12015 (match_operand 3))]
12016 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
12017 && !reg_mentioned_p (operands[0],
12018 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12019 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12020 (parallel [(call (mem:QI (match_dup 1))
12022 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12024 (define_expand "call_pop"
12025 [(parallel [(call (match_operand:QI 0)
12026 (match_operand:SI 1))
12027 (set (reg:SI SP_REG)
12028 (plus:SI (reg:SI SP_REG)
12029 (match_operand:SI 3)))])]
12032 ix86_expand_call (NULL, operands[0], operands[1],
12033 operands[2], operands[3], false);
12037 (define_insn "*call_pop"
12038 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
12040 (set (reg:SI SP_REG)
12041 (plus:SI (reg:SI SP_REG)
12042 (match_operand:SI 2 "immediate_operand" "i")))]
12043 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12044 "* return ix86_output_call_insn (insn, operands[0]);"
12045 [(set_attr "type" "call")])
12047 (define_insn "*sibcall_pop"
12048 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
12050 (set (reg:SI SP_REG)
12051 (plus:SI (reg:SI SP_REG)
12052 (match_operand:SI 2 "immediate_operand" "i")))]
12053 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12054 "* return ix86_output_call_insn (insn, operands[0]);"
12055 [(set_attr "type" "call")])
12057 (define_insn "*sibcall_pop_memory"
12058 [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
12060 (set (reg:SI SP_REG)
12061 (plus:SI (reg:SI SP_REG)
12062 (match_operand:SI 2 "immediate_operand" "i")))
12063 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12065 "* return ix86_output_call_insn (insn, operands[0]);"
12066 [(set_attr "type" "call")])
12069 [(set (match_operand:SI 0 "register_operand")
12070 (match_operand:SI 1 "memory_operand"))
12071 (parallel [(call (mem:QI (match_dup 0))
12073 (set (reg:SI SP_REG)
12074 (plus:SI (reg:SI SP_REG)
12075 (match_operand:SI 4 "immediate_operand")))])]
12076 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12077 && !reg_mentioned_p (operands[0],
12078 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12079 [(parallel [(call (mem:QI (match_dup 1))
12081 (set (reg:SI SP_REG)
12082 (plus:SI (reg:SI SP_REG)
12084 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12087 [(set (match_operand:SI 0 "register_operand")
12088 (match_operand:SI 1 "memory_operand"))
12089 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12090 (parallel [(call (mem:QI (match_dup 0))
12092 (set (reg:SI SP_REG)
12093 (plus:SI (reg:SI SP_REG)
12094 (match_operand:SI 4 "immediate_operand")))])]
12095 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12096 && !reg_mentioned_p (operands[0],
12097 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12098 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12099 (parallel [(call (mem:QI (match_dup 1))
12101 (set (reg:SI SP_REG)
12102 (plus:SI (reg:SI SP_REG)
12104 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12106 ;; Combining simple memory jump instruction
12109 [(set (match_operand:W 0 "register_operand")
12110 (match_operand:W 1 "memory_operand"))
12111 (set (pc) (match_dup 0))]
12112 "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
12113 [(set (pc) (match_dup 1))])
12115 ;; Call subroutine, returning value in operand 0
12117 (define_expand "call_value"
12118 [(set (match_operand 0)
12119 (call (match_operand:QI 1)
12120 (match_operand 2)))
12121 (use (match_operand 3))]
12124 ix86_expand_call (operands[0], operands[1], operands[2],
12125 operands[3], NULL, false);
12129 (define_expand "sibcall_value"
12130 [(set (match_operand 0)
12131 (call (match_operand:QI 1)
12132 (match_operand 2)))
12133 (use (match_operand 3))]
12136 ix86_expand_call (operands[0], operands[1], operands[2],
12137 operands[3], NULL, true);
12141 (define_insn "*call_value"
12142 [(set (match_operand 0)
12143 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
12144 (match_operand 2)))]
12145 "!SIBLING_CALL_P (insn)"
12146 "* return ix86_output_call_insn (insn, operands[1]);"
12147 [(set_attr "type" "callv")])
12149 ;; This covers both call and sibcall since only GOT slot is allowed.
12150 (define_insn "*call_value_got_x32"
12151 [(set (match_operand 0)
12154 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
12155 (match_operand 2)))]
12157 "* return ix86_output_call_insn (insn, operands[1]);"
12158 [(set_attr "type" "callv")])
12160 ;; Since sibcall never returns, we can only use call-clobbered register
12162 (define_insn "*sibcall_value_GOT_32"
12163 [(set (match_operand 0)
12166 (match_operand:SI 1 "register_no_elim_operand" "U")
12167 (match_operand:SI 2 "GOT32_symbol_operand"))))
12168 (match_operand 3)))]
12169 "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
12171 rtx fnaddr = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
12172 fnaddr = gen_const_mem (Pmode, fnaddr);
12173 return ix86_output_call_insn (insn, fnaddr);
12175 [(set_attr "type" "callv")])
12177 (define_insn "*sibcall_value"
12178 [(set (match_operand 0)
12179 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
12180 (match_operand 2)))]
12181 "SIBLING_CALL_P (insn)"
12182 "* return ix86_output_call_insn (insn, operands[1]);"
12183 [(set_attr "type" "callv")])
12185 (define_insn "*sibcall_value_memory"
12186 [(set (match_operand 0)
12187 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
12188 (match_operand 2)))
12189 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12191 "* return ix86_output_call_insn (insn, operands[1]);"
12192 [(set_attr "type" "callv")])
12195 [(set (match_operand:W 0 "register_operand")
12196 (match_operand:W 1 "memory_operand"))
12197 (set (match_operand 2)
12198 (call (mem:QI (match_dup 0))
12199 (match_operand 3)))]
12200 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
12201 && !reg_mentioned_p (operands[0],
12202 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12203 [(parallel [(set (match_dup 2)
12204 (call (mem:QI (match_dup 1))
12206 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12209 [(set (match_operand:W 0 "register_operand")
12210 (match_operand:W 1 "memory_operand"))
12211 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12212 (set (match_operand 2)
12213 (call (mem:QI (match_dup 0))
12214 (match_operand 3)))]
12215 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
12216 && !reg_mentioned_p (operands[0],
12217 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12218 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12219 (parallel [(set (match_dup 2)
12220 (call (mem:QI (match_dup 1))
12222 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12224 (define_expand "call_value_pop"
12225 [(parallel [(set (match_operand 0)
12226 (call (match_operand:QI 1)
12227 (match_operand:SI 2)))
12228 (set (reg:SI SP_REG)
12229 (plus:SI (reg:SI SP_REG)
12230 (match_operand:SI 4)))])]
12233 ix86_expand_call (operands[0], operands[1], operands[2],
12234 operands[3], operands[4], false);
12238 (define_insn "*call_value_pop"
12239 [(set (match_operand 0)
12240 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
12241 (match_operand 2)))
12242 (set (reg:SI SP_REG)
12243 (plus:SI (reg:SI SP_REG)
12244 (match_operand:SI 3 "immediate_operand" "i")))]
12245 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12246 "* return ix86_output_call_insn (insn, operands[1]);"
12247 [(set_attr "type" "callv")])
12249 (define_insn "*sibcall_value_pop"
12250 [(set (match_operand 0)
12251 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
12252 (match_operand 2)))
12253 (set (reg:SI SP_REG)
12254 (plus:SI (reg:SI SP_REG)
12255 (match_operand:SI 3 "immediate_operand" "i")))]
12256 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12257 "* return ix86_output_call_insn (insn, operands[1]);"
12258 [(set_attr "type" "callv")])
12260 (define_insn "*sibcall_value_pop_memory"
12261 [(set (match_operand 0)
12262 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
12263 (match_operand 2)))
12264 (set (reg:SI SP_REG)
12265 (plus:SI (reg:SI SP_REG)
12266 (match_operand:SI 3 "immediate_operand" "i")))
12267 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12269 "* return ix86_output_call_insn (insn, operands[1]);"
12270 [(set_attr "type" "callv")])
12273 [(set (match_operand:SI 0 "register_operand")
12274 (match_operand:SI 1 "memory_operand"))
12275 (parallel [(set (match_operand 2)
12276 (call (mem:QI (match_dup 0))
12277 (match_operand 3)))
12278 (set (reg:SI SP_REG)
12279 (plus:SI (reg:SI SP_REG)
12280 (match_operand:SI 4 "immediate_operand")))])]
12281 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12282 && !reg_mentioned_p (operands[0],
12283 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12284 [(parallel [(set (match_dup 2)
12285 (call (mem:QI (match_dup 1))
12287 (set (reg:SI SP_REG)
12288 (plus:SI (reg:SI SP_REG)
12290 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12293 [(set (match_operand:SI 0 "register_operand")
12294 (match_operand:SI 1 "memory_operand"))
12295 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12296 (parallel [(set (match_operand 2)
12297 (call (mem:QI (match_dup 0))
12298 (match_operand 3)))
12299 (set (reg:SI SP_REG)
12300 (plus:SI (reg:SI SP_REG)
12301 (match_operand:SI 4 "immediate_operand")))])]
12302 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12303 && !reg_mentioned_p (operands[0],
12304 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12305 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12306 (parallel [(set (match_dup 2)
12307 (call (mem:QI (match_dup 1))
12309 (set (reg:SI SP_REG)
12310 (plus:SI (reg:SI SP_REG)
12312 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12314 ;; Call subroutine returning any type.
12316 (define_expand "untyped_call"
12317 [(parallel [(call (match_operand 0)
12320 (match_operand 2)])]
12325 /* In order to give reg-stack an easier job in validating two
12326 coprocessor registers as containing a possible return value,
12327 simply pretend the untyped call returns a complex long double
12330 We can't use SSE_REGPARM_MAX here since callee is unprototyped
12331 and should have the default ABI. */
12333 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12334 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12335 operands[0], const0_rtx,
12336 GEN_INT ((TARGET_64BIT
12337 ? (ix86_abi == SYSV_ABI
12338 ? X86_64_SSE_REGPARM_MAX
12339 : X86_64_MS_SSE_REGPARM_MAX)
12340 : X86_32_SSE_REGPARM_MAX)
12344 for (i = 0; i < XVECLEN (operands[2], 0); i++)
12346 rtx set = XVECEXP (operands[2], 0, i);
12347 emit_move_insn (SET_DEST (set), SET_SRC (set));
12350 /* The optimizer does not know that the call sets the function value
12351 registers we stored in the result block. We avoid problems by
12352 claiming that all hard registers are used and clobbered at this
12354 emit_insn (gen_blockage ());
12359 ;; Prologue and epilogue instructions
12361 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12362 ;; all of memory. This blocks insns from being moved across this point.
12364 (define_insn "blockage"
12365 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12368 [(set_attr "length" "0")])
12370 ;; Do not schedule instructions accessing memory across this point.
12372 (define_expand "memory_blockage"
12373 [(set (match_dup 0)
12374 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12377 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12378 MEM_VOLATILE_P (operands[0]) = 1;
12381 (define_insn "*memory_blockage"
12382 [(set (match_operand:BLK 0)
12383 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12386 [(set_attr "length" "0")])
12388 ;; As USE insns aren't meaningful after reload, this is used instead
12389 ;; to prevent deleting instructions setting registers for PIC code
12390 (define_insn "prologue_use"
12391 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12394 [(set_attr "length" "0")])
12396 ;; Insn emitted into the body of a function to return from a function.
12397 ;; This is only done if the function's epilogue is known to be simple.
12398 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12400 (define_expand "return"
12402 "ix86_can_use_return_insn_p ()"
12404 if (crtl->args.pops_args)
12406 rtx popc = GEN_INT (crtl->args.pops_args);
12407 emit_jump_insn (gen_simple_return_pop_internal (popc));
12412 ;; We need to disable this for TARGET_SEH, as otherwise
12413 ;; shrink-wrapped prologue gets enabled too. This might exceed
12414 ;; the maximum size of prologue in unwind information.
12415 ;; Also disallow shrink-wrapping if using stack slot to pass the
12416 ;; static chain pointer - the first instruction has to be pushl %esi
12417 ;; and it can't be moved around, as we use alternate entry points
12420 (define_expand "simple_return"
12422 "!TARGET_SEH && !ix86_static_chain_on_stack"
12424 if (crtl->args.pops_args)
12426 rtx popc = GEN_INT (crtl->args.pops_args);
12427 emit_jump_insn (gen_simple_return_pop_internal (popc));
12432 (define_insn "simple_return_internal"
12436 [(set_attr "length" "1")
12437 (set_attr "atom_unit" "jeu")
12438 (set_attr "length_immediate" "0")
12439 (set_attr "modrm" "0")
12440 (set_attr "maybe_prefix_bnd" "1")])
12442 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12443 ;; instruction Athlon and K8 have.
12445 (define_insn "simple_return_internal_long"
12447 (unspec [(const_int 0)] UNSPEC_REP)]
12450 if (ix86_bnd_prefixed_insn_p (insn))
12453 return "rep%; ret";
12455 [(set_attr "length" "2")
12456 (set_attr "atom_unit" "jeu")
12457 (set_attr "length_immediate" "0")
12458 (set_attr "prefix_rep" "1")
12459 (set_attr "modrm" "0")])
12461 (define_insn "simple_return_pop_internal"
12463 (use (match_operand:SI 0 "const_int_operand"))]
12466 [(set_attr "length" "3")
12467 (set_attr "atom_unit" "jeu")
12468 (set_attr "length_immediate" "2")
12469 (set_attr "modrm" "0")
12470 (set_attr "maybe_prefix_bnd" "1")])
12472 (define_insn "simple_return_indirect_internal"
12474 (use (match_operand:SI 0 "register_operand" "r"))]
12477 [(set_attr "type" "ibr")
12478 (set_attr "length_immediate" "0")
12479 (set_attr "maybe_prefix_bnd" "1")])
12485 [(set_attr "length" "1")
12486 (set_attr "length_immediate" "0")
12487 (set_attr "modrm" "0")])
12489 ;; Generate nops. Operand 0 is the number of nops, up to 8.
12490 (define_insn "nops"
12491 [(unspec_volatile [(match_operand 0 "const_int_operand")]
12495 int num = INTVAL (operands[0]);
12497 gcc_assert (IN_RANGE (num, 1, 8));
12500 fputs ("\tnop\n", asm_out_file);
12504 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12505 (set_attr "length_immediate" "0")
12506 (set_attr "modrm" "0")])
12508 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12509 ;; branch prediction penalty for the third jump in a 16-byte
12513 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12516 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12517 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12519 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12520 The align insn is used to avoid 3 jump instructions in the row to improve
12521 branch prediction and the benefits hardly outweigh the cost of extra 8
12522 nops on the average inserted by full alignment pseudo operation. */
12526 [(set_attr "length" "16")])
12528 (define_expand "prologue"
12531 "ix86_expand_prologue (); DONE;")
12533 (define_expand "set_got"
12535 [(set (match_operand:SI 0 "register_operand" "=r")
12536 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12537 (clobber (reg:CC FLAGS_REG))])]
12540 if (flag_pic && !TARGET_VXWORKS_RTP)
12541 ix86_pc_thunk_call_expanded = true;
12544 (define_insn "*set_got"
12545 [(set (match_operand:SI 0 "register_operand" "=r")
12546 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12547 (clobber (reg:CC FLAGS_REG))]
12549 "* return output_set_got (operands[0], NULL_RTX);"
12550 [(set_attr "type" "multi")
12551 (set_attr "length" "12")])
12553 (define_expand "set_got_labelled"
12555 [(set (match_operand:SI 0 "register_operand" "=r")
12556 (unspec:SI [(label_ref (match_operand 1))]
12558 (clobber (reg:CC FLAGS_REG))])]
12561 if (flag_pic && !TARGET_VXWORKS_RTP)
12562 ix86_pc_thunk_call_expanded = true;
12565 (define_insn "*set_got_labelled"
12566 [(set (match_operand:SI 0 "register_operand" "=r")
12567 (unspec:SI [(label_ref (match_operand 1))]
12569 (clobber (reg:CC FLAGS_REG))]
12571 "* return output_set_got (operands[0], operands[1]);"
12572 [(set_attr "type" "multi")
12573 (set_attr "length" "12")])
12575 (define_insn "set_got_rex64"
12576 [(set (match_operand:DI 0 "register_operand" "=r")
12577 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12579 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12580 [(set_attr "type" "lea")
12581 (set_attr "length_address" "4")
12582 (set_attr "modrm_class" "unknown")
12583 (set_attr "mode" "DI")])
12585 (define_insn "set_rip_rex64"
12586 [(set (match_operand:DI 0 "register_operand" "=r")
12587 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12589 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12590 [(set_attr "type" "lea")
12591 (set_attr "length_address" "4")
12592 (set_attr "mode" "DI")])
12594 (define_insn "set_got_offset_rex64"
12595 [(set (match_operand:DI 0 "register_operand" "=r")
12597 [(label_ref (match_operand 1))]
12598 UNSPEC_SET_GOT_OFFSET))]
12600 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12601 [(set_attr "type" "imov")
12602 (set_attr "length_immediate" "0")
12603 (set_attr "length_address" "8")
12604 (set_attr "mode" "DI")])
12606 (define_expand "epilogue"
12609 "ix86_expand_epilogue (1); DONE;")
12611 (define_expand "sibcall_epilogue"
12614 "ix86_expand_epilogue (0); DONE;")
12616 (define_expand "eh_return"
12617 [(use (match_operand 0 "register_operand"))]
12620 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12622 /* Tricky bit: we write the address of the handler to which we will
12623 be returning into someone else's stack frame, one word below the
12624 stack address we wish to restore. */
12625 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12626 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12627 tmp = gen_rtx_MEM (Pmode, tmp);
12628 emit_move_insn (tmp, ra);
12630 emit_jump_insn (gen_eh_return_internal ());
12635 (define_insn_and_split "eh_return_internal"
12639 "epilogue_completed"
12641 "ix86_expand_epilogue (2); DONE;")
12643 (define_insn "leave"
12644 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12645 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12646 (clobber (mem:BLK (scratch)))]
12649 [(set_attr "type" "leave")])
12651 (define_insn "leave_rex64"
12652 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12653 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12654 (clobber (mem:BLK (scratch)))]
12657 [(set_attr "type" "leave")])
12659 ;; Handle -fsplit-stack.
12661 (define_expand "split_stack_prologue"
12665 ix86_expand_split_stack_prologue ();
12669 ;; In order to support the call/return predictor, we use a return
12670 ;; instruction which the middle-end doesn't see.
12671 (define_insn "split_stack_return"
12672 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12673 UNSPECV_SPLIT_STACK_RETURN)]
12676 if (operands[0] == const0_rtx)
12681 [(set_attr "atom_unit" "jeu")
12682 (set_attr "modrm" "0")
12683 (set (attr "length")
12684 (if_then_else (match_operand:SI 0 "const0_operand")
12687 (set (attr "length_immediate")
12688 (if_then_else (match_operand:SI 0 "const0_operand")
12692 ;; If there are operand 0 bytes available on the stack, jump to
12695 (define_expand "split_stack_space_check"
12696 [(set (pc) (if_then_else
12697 (ltu (minus (reg SP_REG)
12698 (match_operand 0 "register_operand"))
12699 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12700 (label_ref (match_operand 1))
12704 rtx reg, size, limit;
12706 reg = gen_reg_rtx (Pmode);
12707 size = force_reg (Pmode, operands[0]);
12708 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12709 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12710 UNSPEC_STACK_CHECK);
12711 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12712 ix86_expand_branch (GEU, reg, limit, operands[1]);
12717 ;; Bit manipulation instructions.
12719 (define_expand "ffs<mode>2"
12720 [(set (match_dup 2) (const_int -1))
12721 (parallel [(set (match_dup 3) (match_dup 4))
12722 (set (match_operand:SWI48 0 "register_operand")
12724 (match_operand:SWI48 1 "nonimmediate_operand")))])
12725 (set (match_dup 0) (if_then_else:SWI48
12726 (eq (match_dup 3) (const_int 0))
12729 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12730 (clobber (reg:CC FLAGS_REG))])]
12733 machine_mode flags_mode;
12735 if (<MODE>mode == SImode && !TARGET_CMOVE)
12737 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12742 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12744 operands[2] = gen_reg_rtx (<MODE>mode);
12745 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12746 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12749 (define_insn_and_split "ffssi2_no_cmove"
12750 [(set (match_operand:SI 0 "register_operand" "=r")
12751 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12752 (clobber (match_scratch:SI 2 "=&q"))
12753 (clobber (reg:CC FLAGS_REG))]
12756 "&& reload_completed"
12757 [(parallel [(set (match_dup 4) (match_dup 5))
12758 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12759 (set (strict_low_part (match_dup 3))
12760 (eq:QI (match_dup 4) (const_int 0)))
12761 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12762 (clobber (reg:CC FLAGS_REG))])
12763 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12764 (clobber (reg:CC FLAGS_REG))])
12765 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12766 (clobber (reg:CC FLAGS_REG))])]
12768 machine_mode flags_mode
12769 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12771 operands[3] = gen_lowpart (QImode, operands[2]);
12772 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12773 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12775 ix86_expand_clear (operands[2]);
12778 (define_insn "*tzcnt<mode>_1"
12779 [(set (reg:CCC FLAGS_REG)
12780 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12782 (set (match_operand:SWI48 0 "register_operand" "=r")
12783 (ctz:SWI48 (match_dup 1)))]
12784 "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
12785 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12786 [(set_attr "type" "alu1")
12787 (set_attr "prefix_0f" "1")
12788 (set_attr "prefix_rep" "1")
12789 (set_attr "btver2_decode" "double")
12790 (set_attr "mode" "<MODE>")])
12792 (define_insn "*bsf<mode>_1"
12793 [(set (reg:CCZ FLAGS_REG)
12794 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12796 (set (match_operand:SWI48 0 "register_operand" "=r")
12797 (ctz:SWI48 (match_dup 1)))]
12799 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12800 [(set_attr "type" "alu1")
12801 (set_attr "prefix_0f" "1")
12802 (set_attr "btver2_decode" "double")
12803 (set_attr "znver1_decode" "vector")
12804 (set_attr "mode" "<MODE>")])
12806 (define_expand "ctz<mode>2"
12808 [(set (match_operand:SWI248 0 "register_operand")
12810 (match_operand:SWI248 1 "nonimmediate_operand")))
12811 (clobber (reg:CC FLAGS_REG))])])
12813 ; False dependency happens when destination is only updated by tzcnt,
12814 ; lzcnt or popcnt. There is no false dependency when destination is
12815 ; also used in source.
12816 (define_insn_and_split "*ctz<mode>2_falsedep_1"
12817 [(set (match_operand:SWI48 0 "register_operand" "=r")
12819 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12820 (clobber (reg:CC FLAGS_REG))]
12821 "(TARGET_BMI || TARGET_GENERIC)
12822 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12824 "&& reload_completed"
12826 [(set (match_dup 0)
12827 (ctz:SWI48 (match_dup 1)))
12828 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12829 (clobber (reg:CC FLAGS_REG))])]
12831 if (!reg_mentioned_p (operands[0], operands[1]))
12832 ix86_expand_clear (operands[0]);
12835 (define_insn "*ctz<mode>2_falsedep"
12836 [(set (match_operand:SWI48 0 "register_operand" "=r")
12838 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12839 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12840 UNSPEC_INSN_FALSE_DEP)
12841 (clobber (reg:CC FLAGS_REG))]
12845 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12846 else if (TARGET_GENERIC)
12847 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12848 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12850 gcc_unreachable ();
12852 [(set_attr "type" "alu1")
12853 (set_attr "prefix_0f" "1")
12854 (set_attr "prefix_rep" "1")
12855 (set_attr "mode" "<MODE>")])
12857 (define_insn "*ctz<mode>2"
12858 [(set (match_operand:SWI248 0 "register_operand" "=r")
12859 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12860 (clobber (reg:CC FLAGS_REG))]
12864 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12865 else if (optimize_function_for_size_p (cfun))
12867 else if (TARGET_GENERIC)
12868 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12869 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12871 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12873 [(set_attr "type" "alu1")
12874 (set_attr "prefix_0f" "1")
12875 (set (attr "prefix_rep")
12877 (ior (match_test "TARGET_BMI")
12878 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12879 (match_test "TARGET_GENERIC")))
12881 (const_string "0")))
12882 (set_attr "mode" "<MODE>")])
12884 (define_expand "clz<mode>2"
12886 [(set (match_operand:SWI248 0 "register_operand")
12889 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12890 (clobber (reg:CC FLAGS_REG))])
12892 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12893 (clobber (reg:CC FLAGS_REG))])]
12898 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12901 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12904 (define_expand "clz<mode>2_lzcnt"
12906 [(set (match_operand:SWI248 0 "register_operand")
12908 (match_operand:SWI248 1 "nonimmediate_operand")))
12909 (clobber (reg:CC FLAGS_REG))])]
12912 (define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
12913 [(set (match_operand:SWI48 0 "register_operand" "=r")
12915 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12916 (clobber (reg:CC FLAGS_REG))]
12918 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12920 "&& reload_completed"
12922 [(set (match_dup 0)
12923 (clz:SWI48 (match_dup 1)))
12924 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12925 (clobber (reg:CC FLAGS_REG))])]
12927 if (!reg_mentioned_p (operands[0], operands[1]))
12928 ix86_expand_clear (operands[0]);
12931 (define_insn "*clz<mode>2_lzcnt_falsedep"
12932 [(set (match_operand:SWI48 0 "register_operand" "=r")
12934 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12935 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12936 UNSPEC_INSN_FALSE_DEP)
12937 (clobber (reg:CC FLAGS_REG))]
12939 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12940 [(set_attr "prefix_rep" "1")
12941 (set_attr "type" "bitmanip")
12942 (set_attr "mode" "<MODE>")])
12944 (define_insn "*clz<mode>2_lzcnt"
12945 [(set (match_operand:SWI248 0 "register_operand" "=r")
12946 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12947 (clobber (reg:CC FLAGS_REG))]
12949 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12950 [(set_attr "prefix_rep" "1")
12951 (set_attr "type" "bitmanip")
12952 (set_attr "mode" "<MODE>")])
12954 ;; BMI instructions.
12955 (define_insn "*bmi_andn_<mode>"
12956 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12958 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
12959 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12960 (clobber (reg:CC FLAGS_REG))]
12962 "andn\t{%2, %1, %0|%0, %1, %2}"
12963 [(set_attr "type" "bitmanip")
12964 (set_attr "btver2_decode" "direct, double")
12965 (set_attr "mode" "<MODE>")])
12967 (define_insn "*bmi_andn_<mode>_ccno"
12968 [(set (reg FLAGS_REG)
12971 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
12972 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
12974 (clobber (match_scratch:SWI48 0 "=r,r"))]
12975 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
12976 "andn\t{%2, %1, %0|%0, %1, %2}"
12977 [(set_attr "type" "bitmanip")
12978 (set_attr "btver2_decode" "direct, double")
12979 (set_attr "mode" "<MODE>")])
12981 (define_insn "bmi_bextr_<mode>"
12982 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12983 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12984 (match_operand:SWI48 2 "register_operand" "r,r")]
12986 (clobber (reg:CC FLAGS_REG))]
12988 "bextr\t{%2, %1, %0|%0, %1, %2}"
12989 [(set_attr "type" "bitmanip")
12990 (set_attr "btver2_decode" "direct, double")
12991 (set_attr "mode" "<MODE>")])
12993 (define_insn "*bmi_bextr_<mode>_ccz"
12994 [(set (reg:CCZ FLAGS_REG)
12996 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12997 (match_operand:SWI48 2 "register_operand" "r,r")]
13000 (clobber (match_scratch:SWI48 0 "=r,r"))]
13002 "bextr\t{%2, %1, %0|%0, %1, %2}"
13003 [(set_attr "type" "bitmanip")
13004 (set_attr "btver2_decode" "direct, double")
13005 (set_attr "mode" "<MODE>")])
13007 (define_insn "*bmi_blsi_<mode>"
13008 [(set (match_operand:SWI48 0 "register_operand" "=r")
13011 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
13013 (clobber (reg:CC FLAGS_REG))]
13015 "blsi\t{%1, %0|%0, %1}"
13016 [(set_attr "type" "bitmanip")
13017 (set_attr "btver2_decode" "double")
13018 (set_attr "mode" "<MODE>")])
13020 (define_insn "*bmi_blsmsk_<mode>"
13021 [(set (match_operand:SWI48 0 "register_operand" "=r")
13024 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13027 (clobber (reg:CC FLAGS_REG))]
13029 "blsmsk\t{%1, %0|%0, %1}"
13030 [(set_attr "type" "bitmanip")
13031 (set_attr "btver2_decode" "double")
13032 (set_attr "mode" "<MODE>")])
13034 (define_insn "*bmi_blsr_<mode>"
13035 [(set (match_operand:SWI48 0 "register_operand" "=r")
13038 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13041 (clobber (reg:CC FLAGS_REG))]
13043 "blsr\t{%1, %0|%0, %1}"
13044 [(set_attr "type" "bitmanip")
13045 (set_attr "btver2_decode" "double")
13046 (set_attr "mode" "<MODE>")])
13048 ;; BMI2 instructions.
13049 (define_expand "bmi2_bzhi_<mode>3"
13051 [(set (match_operand:SWI48 0 "register_operand")
13052 (zero_extract:SWI48
13053 (match_operand:SWI48 1 "nonimmediate_operand")
13055 (and:SWI48 (match_operand:SWI48 2 "register_operand")
13059 (clobber (reg:CC FLAGS_REG))])]
13061 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
13063 (define_insn "*bmi2_bzhi_<mode>3"
13064 [(set (match_operand:SWI48 0 "register_operand" "=r")
13065 (zero_extract:SWI48
13066 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13068 (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
13070 (match_operand:SWI48 3 "const_int_operand" "n"))
13072 (clobber (reg:CC FLAGS_REG))]
13073 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13074 "bzhi\t{%2, %1, %0|%0, %1, %2}"
13075 [(set_attr "type" "bitmanip")
13076 (set_attr "prefix" "vex")
13077 (set_attr "mode" "<MODE>")])
13079 (define_mode_attr k [(SI "k") (DI "q")])
13081 (define_insn "*bmi2_bzhi_<mode>3_1"
13082 [(set (match_operand:SWI48 0 "register_operand" "=r")
13083 (zero_extract:SWI48
13084 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13086 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13087 (match_operand:SWI48 3 "const_int_operand" "n"))
13089 (clobber (reg:CC FLAGS_REG))]
13090 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13091 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13092 [(set_attr "type" "bitmanip")
13093 (set_attr "prefix" "vex")
13094 (set_attr "mode" "<MODE>")])
13096 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
13097 [(set (reg:CCZ FLAGS_REG)
13099 (zero_extract:SWI48
13100 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13102 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13103 (match_operand:SWI48 3 "const_int_operand" "n"))
13106 (clobber (match_scratch:SWI48 0 "=r"))]
13107 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13108 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13109 [(set_attr "type" "bitmanip")
13110 (set_attr "prefix" "vex")
13111 (set_attr "mode" "<MODE>")])
13113 (define_insn "bmi2_pdep_<mode>3"
13114 [(set (match_operand:SWI48 0 "register_operand" "=r")
13115 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13116 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13119 "pdep\t{%2, %1, %0|%0, %1, %2}"
13120 [(set_attr "type" "bitmanip")
13121 (set_attr "prefix" "vex")
13122 (set_attr "mode" "<MODE>")])
13124 (define_insn "bmi2_pext_<mode>3"
13125 [(set (match_operand:SWI48 0 "register_operand" "=r")
13126 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13127 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13130 "pext\t{%2, %1, %0|%0, %1, %2}"
13131 [(set_attr "type" "bitmanip")
13132 (set_attr "prefix" "vex")
13133 (set_attr "mode" "<MODE>")])
13135 ;; TBM instructions.
13136 (define_insn "tbm_bextri_<mode>"
13137 [(set (match_operand:SWI48 0 "register_operand" "=r")
13138 (zero_extract:SWI48
13139 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13140 (match_operand 2 "const_0_to_255_operand" "N")
13141 (match_operand 3 "const_0_to_255_operand" "N")))
13142 (clobber (reg:CC FLAGS_REG))]
13145 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
13146 return "bextr\t{%2, %1, %0|%0, %1, %2}";
13148 [(set_attr "type" "bitmanip")
13149 (set_attr "mode" "<MODE>")])
13151 (define_insn "*tbm_blcfill_<mode>"
13152 [(set (match_operand:SWI48 0 "register_operand" "=r")
13155 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13158 (clobber (reg:CC FLAGS_REG))]
13160 "blcfill\t{%1, %0|%0, %1}"
13161 [(set_attr "type" "bitmanip")
13162 (set_attr "mode" "<MODE>")])
13164 (define_insn "*tbm_blci_<mode>"
13165 [(set (match_operand:SWI48 0 "register_operand" "=r")
13169 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13172 (clobber (reg:CC FLAGS_REG))]
13174 "blci\t{%1, %0|%0, %1}"
13175 [(set_attr "type" "bitmanip")
13176 (set_attr "mode" "<MODE>")])
13178 (define_insn "*tbm_blcic_<mode>"
13179 [(set (match_operand:SWI48 0 "register_operand" "=r")
13182 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13186 (clobber (reg:CC FLAGS_REG))]
13188 "blcic\t{%1, %0|%0, %1}"
13189 [(set_attr "type" "bitmanip")
13190 (set_attr "mode" "<MODE>")])
13192 (define_insn "*tbm_blcmsk_<mode>"
13193 [(set (match_operand:SWI48 0 "register_operand" "=r")
13196 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13199 (clobber (reg:CC FLAGS_REG))]
13201 "blcmsk\t{%1, %0|%0, %1}"
13202 [(set_attr "type" "bitmanip")
13203 (set_attr "mode" "<MODE>")])
13205 (define_insn "*tbm_blcs_<mode>"
13206 [(set (match_operand:SWI48 0 "register_operand" "=r")
13209 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13212 (clobber (reg:CC FLAGS_REG))]
13214 "blcs\t{%1, %0|%0, %1}"
13215 [(set_attr "type" "bitmanip")
13216 (set_attr "mode" "<MODE>")])
13218 (define_insn "*tbm_blsfill_<mode>"
13219 [(set (match_operand:SWI48 0 "register_operand" "=r")
13222 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13225 (clobber (reg:CC FLAGS_REG))]
13227 "blsfill\t{%1, %0|%0, %1}"
13228 [(set_attr "type" "bitmanip")
13229 (set_attr "mode" "<MODE>")])
13231 (define_insn "*tbm_blsic_<mode>"
13232 [(set (match_operand:SWI48 0 "register_operand" "=r")
13235 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13239 (clobber (reg:CC FLAGS_REG))]
13241 "blsic\t{%1, %0|%0, %1}"
13242 [(set_attr "type" "bitmanip")
13243 (set_attr "mode" "<MODE>")])
13245 (define_insn "*tbm_t1mskc_<mode>"
13246 [(set (match_operand:SWI48 0 "register_operand" "=r")
13249 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13253 (clobber (reg:CC FLAGS_REG))]
13255 "t1mskc\t{%1, %0|%0, %1}"
13256 [(set_attr "type" "bitmanip")
13257 (set_attr "mode" "<MODE>")])
13259 (define_insn "*tbm_tzmsk_<mode>"
13260 [(set (match_operand:SWI48 0 "register_operand" "=r")
13263 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13267 (clobber (reg:CC FLAGS_REG))]
13269 "tzmsk\t{%1, %0|%0, %1}"
13270 [(set_attr "type" "bitmanip")
13271 (set_attr "mode" "<MODE>")])
13273 (define_insn "bsr_rex64"
13274 [(set (match_operand:DI 0 "register_operand" "=r")
13275 (minus:DI (const_int 63)
13276 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13277 (clobber (reg:CC FLAGS_REG))]
13279 "bsr{q}\t{%1, %0|%0, %1}"
13280 [(set_attr "type" "alu1")
13281 (set_attr "prefix_0f" "1")
13282 (set_attr "znver1_decode" "vector")
13283 (set_attr "mode" "DI")])
13286 [(set (match_operand:SI 0 "register_operand" "=r")
13287 (minus:SI (const_int 31)
13288 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13289 (clobber (reg:CC FLAGS_REG))]
13291 "bsr{l}\t{%1, %0|%0, %1}"
13292 [(set_attr "type" "alu1")
13293 (set_attr "prefix_0f" "1")
13294 (set_attr "znver1_decode" "vector")
13295 (set_attr "mode" "SI")])
13297 (define_insn "*bsrhi"
13298 [(set (match_operand:HI 0 "register_operand" "=r")
13299 (minus:HI (const_int 15)
13300 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13301 (clobber (reg:CC FLAGS_REG))]
13303 "bsr{w}\t{%1, %0|%0, %1}"
13304 [(set_attr "type" "alu1")
13305 (set_attr "prefix_0f" "1")
13306 (set_attr "znver1_decode" "vector")
13307 (set_attr "mode" "HI")])
13309 (define_expand "popcount<mode>2"
13311 [(set (match_operand:SWI248 0 "register_operand")
13313 (match_operand:SWI248 1 "nonimmediate_operand")))
13314 (clobber (reg:CC FLAGS_REG))])]
13317 (define_insn_and_split "*popcount<mode>2_falsedep_1"
13318 [(set (match_operand:SWI48 0 "register_operand" "=r")
13320 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13321 (clobber (reg:CC FLAGS_REG))]
13323 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
13325 "&& reload_completed"
13327 [(set (match_dup 0)
13328 (popcount:SWI48 (match_dup 1)))
13329 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13330 (clobber (reg:CC FLAGS_REG))])]
13332 if (!reg_mentioned_p (operands[0], operands[1]))
13333 ix86_expand_clear (operands[0]);
13336 (define_insn "*popcount<mode>2_falsedep"
13337 [(set (match_operand:SWI48 0 "register_operand" "=r")
13339 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13340 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13341 UNSPEC_INSN_FALSE_DEP)
13342 (clobber (reg:CC FLAGS_REG))]
13346 return "popcnt\t{%1, %0|%0, %1}";
13348 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13351 [(set_attr "prefix_rep" "1")
13352 (set_attr "type" "bitmanip")
13353 (set_attr "mode" "<MODE>")])
13355 (define_insn "*popcount<mode>2"
13356 [(set (match_operand:SWI248 0 "register_operand" "=r")
13358 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
13359 (clobber (reg:CC FLAGS_REG))]
13363 return "popcnt\t{%1, %0|%0, %1}";
13365 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13368 [(set_attr "prefix_rep" "1")
13369 (set_attr "type" "bitmanip")
13370 (set_attr "mode" "<MODE>")])
13372 (define_expand "bswapdi2"
13373 [(set (match_operand:DI 0 "register_operand")
13374 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
13378 operands[1] = force_reg (DImode, operands[1]);
13381 (define_expand "bswapsi2"
13382 [(set (match_operand:SI 0 "register_operand")
13383 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
13388 else if (TARGET_BSWAP)
13389 operands[1] = force_reg (SImode, operands[1]);
13392 rtx x = operands[0];
13394 emit_move_insn (x, operands[1]);
13395 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13396 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
13397 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13402 (define_insn "*bswap<mode>2_movbe"
13403 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
13404 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
13406 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13409 movbe\t{%1, %0|%0, %1}
13410 movbe\t{%1, %0|%0, %1}"
13411 [(set_attr "type" "bitmanip,imov,imov")
13412 (set_attr "modrm" "0,1,1")
13413 (set_attr "prefix_0f" "*,1,1")
13414 (set_attr "prefix_extra" "*,1,1")
13415 (set_attr "mode" "<MODE>")])
13417 (define_insn "*bswap<mode>2"
13418 [(set (match_operand:SWI48 0 "register_operand" "=r")
13419 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
13422 [(set_attr "type" "bitmanip")
13423 (set_attr "modrm" "0")
13424 (set_attr "mode" "<MODE>")])
13426 (define_insn "*bswaphi_lowpart_1"
13427 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
13428 (bswap:HI (match_dup 0)))
13429 (clobber (reg:CC FLAGS_REG))]
13430 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
13432 xchg{b}\t{%h0, %b0|%b0, %h0}
13433 rol{w}\t{$8, %0|%0, 8}"
13434 [(set_attr "length" "2,4")
13435 (set_attr "mode" "QI,HI")])
13437 (define_insn "bswaphi_lowpart"
13438 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
13439 (bswap:HI (match_dup 0)))
13440 (clobber (reg:CC FLAGS_REG))]
13442 "rol{w}\t{$8, %0|%0, 8}"
13443 [(set_attr "length" "4")
13444 (set_attr "mode" "HI")])
13446 (define_expand "paritydi2"
13447 [(set (match_operand:DI 0 "register_operand")
13448 (parity:DI (match_operand:DI 1 "register_operand")))]
13451 rtx scratch = gen_reg_rtx (QImode);
13454 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
13455 NULL_RTX, operands[1]));
13457 cond = gen_rtx_fmt_ee (ORDERED, QImode,
13458 gen_rtx_REG (CCmode, FLAGS_REG),
13460 emit_insn (gen_rtx_SET (scratch, cond));
13463 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
13466 rtx tmp = gen_reg_rtx (SImode);
13468 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
13469 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
13474 (define_expand "paritysi2"
13475 [(set (match_operand:SI 0 "register_operand")
13476 (parity:SI (match_operand:SI 1 "register_operand")))]
13479 rtx scratch = gen_reg_rtx (QImode);
13482 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
13484 cond = gen_rtx_fmt_ee (ORDERED, QImode,
13485 gen_rtx_REG (CCmode, FLAGS_REG),
13487 emit_insn (gen_rtx_SET (scratch, cond));
13489 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
13493 (define_insn_and_split "paritydi2_cmp"
13494 [(set (reg:CC FLAGS_REG)
13495 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
13497 (clobber (match_scratch:DI 0 "=r"))
13498 (clobber (match_scratch:SI 1 "=&r"))
13499 (clobber (match_scratch:HI 2 "=Q"))]
13502 "&& reload_completed"
13504 [(set (match_dup 1)
13505 (xor:SI (match_dup 1) (match_dup 4)))
13506 (clobber (reg:CC FLAGS_REG))])
13508 [(set (reg:CC FLAGS_REG)
13509 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13510 (clobber (match_dup 1))
13511 (clobber (match_dup 2))])]
13513 operands[4] = gen_lowpart (SImode, operands[3]);
13517 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
13518 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
13521 operands[1] = gen_highpart (SImode, operands[3]);
13524 (define_insn_and_split "paritysi2_cmp"
13525 [(set (reg:CC FLAGS_REG)
13526 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
13528 (clobber (match_scratch:SI 0 "=r"))
13529 (clobber (match_scratch:HI 1 "=&Q"))]
13532 "&& reload_completed"
13534 [(set (match_dup 1)
13535 (xor:HI (match_dup 1) (match_dup 3)))
13536 (clobber (reg:CC FLAGS_REG))])
13538 [(set (reg:CC FLAGS_REG)
13539 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13540 (clobber (match_dup 1))])]
13542 operands[3] = gen_lowpart (HImode, operands[2]);
13544 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
13545 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
13548 (define_insn "*parityhi2_cmp"
13549 [(set (reg:CC FLAGS_REG)
13550 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
13552 (clobber (match_scratch:HI 0 "=Q"))]
13554 "xor{b}\t{%h0, %b0|%b0, %h0}"
13555 [(set_attr "length" "2")
13556 (set_attr "mode" "HI")])
13559 ;; Thread-local storage patterns for ELF.
13561 ;; Note that these code sequences must appear exactly as shown
13562 ;; in order to allow linker relaxation.
13564 (define_insn "*tls_global_dynamic_32_gnu"
13565 [(set (match_operand:SI 0 "register_operand" "=a")
13567 [(match_operand:SI 1 "register_operand" "b")
13568 (match_operand 2 "tls_symbolic_operand")
13569 (match_operand 3 "constant_call_address_operand" "Bz")
13572 (clobber (match_scratch:SI 4 "=d"))
13573 (clobber (match_scratch:SI 5 "=c"))
13574 (clobber (reg:CC FLAGS_REG))]
13575 "!TARGET_64BIT && TARGET_GNU_TLS"
13578 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
13579 if (TARGET_SUN_TLS)
13580 #ifdef HAVE_AS_IX86_TLSGDPLT
13581 return "call\t%a2@tlsgdplt";
13583 return "call\t%p3@plt";
13585 return "call\t%P3";
13587 [(set_attr "type" "multi")
13588 (set_attr "length" "12")])
13590 (define_expand "tls_global_dynamic_32"
13592 [(set (match_operand:SI 0 "register_operand")
13593 (unspec:SI [(match_operand:SI 2 "register_operand")
13594 (match_operand 1 "tls_symbolic_operand")
13595 (match_operand 3 "constant_call_address_operand")
13598 (clobber (match_scratch:SI 4))
13599 (clobber (match_scratch:SI 5))
13600 (clobber (reg:CC FLAGS_REG))])]
13602 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13604 (define_insn "*tls_global_dynamic_64_<mode>"
13605 [(set (match_operand:P 0 "register_operand" "=a")
13607 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
13608 (match_operand 3)))
13609 (unspec:P [(match_operand 1 "tls_symbolic_operand")
13615 fputs (ASM_BYTE "0x66\n", asm_out_file);
13617 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13618 fputs (ASM_SHORT "0x6666\n", asm_out_file);
13619 fputs ("\trex64\n", asm_out_file);
13620 if (TARGET_SUN_TLS)
13621 return "call\t%p2@plt";
13622 return "call\t%P2";
13624 [(set_attr "type" "multi")
13625 (set (attr "length")
13626 (symbol_ref "TARGET_X32 ? 15 : 16"))])
13628 (define_insn "*tls_global_dynamic_64_largepic"
13629 [(set (match_operand:DI 0 "register_operand" "=a")
13631 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
13632 (match_operand:DI 3 "immediate_operand" "i")))
13633 (match_operand 4)))
13634 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13637 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13638 && GET_CODE (operands[3]) == CONST
13639 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13640 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13643 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13644 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13645 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13646 return "call\t{*%%rax|rax}";
13648 [(set_attr "type" "multi")
13649 (set_attr "length" "22")])
13651 (define_expand "tls_global_dynamic_64_<mode>"
13653 [(set (match_operand:P 0 "register_operand")
13655 (mem:QI (match_operand 2))
13657 (unspec:P [(match_operand 1 "tls_symbolic_operand")
13661 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13663 (define_insn "*tls_local_dynamic_base_32_gnu"
13664 [(set (match_operand:SI 0 "register_operand" "=a")
13666 [(match_operand:SI 1 "register_operand" "b")
13667 (match_operand 2 "constant_call_address_operand" "Bz")
13669 UNSPEC_TLS_LD_BASE))
13670 (clobber (match_scratch:SI 3 "=d"))
13671 (clobber (match_scratch:SI 4 "=c"))
13672 (clobber (reg:CC FLAGS_REG))]
13673 "!TARGET_64BIT && TARGET_GNU_TLS"
13676 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13677 if (TARGET_SUN_TLS)
13679 if (HAVE_AS_IX86_TLSLDMPLT)
13680 return "call\t%&@tlsldmplt";
13682 return "call\t%p2@plt";
13684 return "call\t%P2";
13686 [(set_attr "type" "multi")
13687 (set_attr "length" "11")])
13689 (define_expand "tls_local_dynamic_base_32"
13691 [(set (match_operand:SI 0 "register_operand")
13693 [(match_operand:SI 1 "register_operand")
13694 (match_operand 2 "constant_call_address_operand")
13696 UNSPEC_TLS_LD_BASE))
13697 (clobber (match_scratch:SI 3))
13698 (clobber (match_scratch:SI 4))
13699 (clobber (reg:CC FLAGS_REG))])]
13701 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13703 (define_insn "*tls_local_dynamic_base_64_<mode>"
13704 [(set (match_operand:P 0 "register_operand" "=a")
13706 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13707 (match_operand 2)))
13708 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
13712 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13713 if (TARGET_SUN_TLS)
13714 return "call\t%p1@plt";
13715 return "call\t%P1";
13717 [(set_attr "type" "multi")
13718 (set_attr "length" "12")])
13720 (define_insn "*tls_local_dynamic_base_64_largepic"
13721 [(set (match_operand:DI 0 "register_operand" "=a")
13723 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13724 (match_operand:DI 2 "immediate_operand" "i")))
13725 (match_operand 3)))
13726 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
13727 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13728 && GET_CODE (operands[2]) == CONST
13729 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13730 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13733 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13734 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13735 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13736 return "call\t{*%%rax|rax}";
13738 [(set_attr "type" "multi")
13739 (set_attr "length" "22")])
13741 (define_expand "tls_local_dynamic_base_64_<mode>"
13743 [(set (match_operand:P 0 "register_operand")
13745 (mem:QI (match_operand 1))
13747 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
13749 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13751 ;; Local dynamic of a single variable is a lose. Show combine how
13752 ;; to convert that back to global dynamic.
13754 (define_insn_and_split "*tls_local_dynamic_32_once"
13755 [(set (match_operand:SI 0 "register_operand" "=a")
13757 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13758 (match_operand 2 "constant_call_address_operand" "Bz")
13760 UNSPEC_TLS_LD_BASE)
13761 (const:SI (unspec:SI
13762 [(match_operand 3 "tls_symbolic_operand")]
13764 (clobber (match_scratch:SI 4 "=d"))
13765 (clobber (match_scratch:SI 5 "=c"))
13766 (clobber (reg:CC FLAGS_REG))]
13771 [(set (match_dup 0)
13772 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13775 (clobber (match_dup 4))
13776 (clobber (match_dup 5))
13777 (clobber (reg:CC FLAGS_REG))])])
13779 ;; Segment register for the thread base ptr load
13780 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13782 ;; Load and add the thread base pointer from %<tp_seg>:0.
13783 (define_insn "*load_tp_x32"
13784 [(set (match_operand:SI 0 "register_operand" "=r")
13785 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13787 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13788 [(set_attr "type" "imov")
13789 (set_attr "modrm" "0")
13790 (set_attr "length" "7")
13791 (set_attr "memory" "load")
13792 (set_attr "imm_disp" "false")])
13794 (define_insn "*load_tp_x32_zext"
13795 [(set (match_operand:DI 0 "register_operand" "=r")
13796 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13798 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13799 [(set_attr "type" "imov")
13800 (set_attr "modrm" "0")
13801 (set_attr "length" "7")
13802 (set_attr "memory" "load")
13803 (set_attr "imm_disp" "false")])
13805 (define_insn "*load_tp_<mode>"
13806 [(set (match_operand:P 0 "register_operand" "=r")
13807 (unspec:P [(const_int 0)] UNSPEC_TP))]
13809 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13810 [(set_attr "type" "imov")
13811 (set_attr "modrm" "0")
13812 (set_attr "length" "7")
13813 (set_attr "memory" "load")
13814 (set_attr "imm_disp" "false")])
13816 (define_insn "*add_tp_x32"
13817 [(set (match_operand:SI 0 "register_operand" "=r")
13818 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13819 (match_operand:SI 1 "register_operand" "0")))
13820 (clobber (reg:CC FLAGS_REG))]
13822 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13823 [(set_attr "type" "alu")
13824 (set_attr "modrm" "0")
13825 (set_attr "length" "7")
13826 (set_attr "memory" "load")
13827 (set_attr "imm_disp" "false")])
13829 (define_insn "*add_tp_x32_zext"
13830 [(set (match_operand:DI 0 "register_operand" "=r")
13832 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13833 (match_operand:SI 1 "register_operand" "0"))))
13834 (clobber (reg:CC FLAGS_REG))]
13836 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13837 [(set_attr "type" "alu")
13838 (set_attr "modrm" "0")
13839 (set_attr "length" "7")
13840 (set_attr "memory" "load")
13841 (set_attr "imm_disp" "false")])
13843 (define_insn "*add_tp_<mode>"
13844 [(set (match_operand:P 0 "register_operand" "=r")
13845 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13846 (match_operand:P 1 "register_operand" "0")))
13847 (clobber (reg:CC FLAGS_REG))]
13849 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13850 [(set_attr "type" "alu")
13851 (set_attr "modrm" "0")
13852 (set_attr "length" "7")
13853 (set_attr "memory" "load")
13854 (set_attr "imm_disp" "false")])
13856 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13857 ;; %rax as destination of the initial executable code sequence.
13858 (define_insn "tls_initial_exec_64_sun"
13859 [(set (match_operand:DI 0 "register_operand" "=a")
13861 [(match_operand 1 "tls_symbolic_operand")]
13862 UNSPEC_TLS_IE_SUN))
13863 (clobber (reg:CC FLAGS_REG))]
13864 "TARGET_64BIT && TARGET_SUN_TLS"
13867 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13868 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13870 [(set_attr "type" "multi")])
13872 ;; GNU2 TLS patterns can be split.
13874 (define_expand "tls_dynamic_gnu2_32"
13875 [(set (match_dup 3)
13876 (plus:SI (match_operand:SI 2 "register_operand")
13878 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13881 [(set (match_operand:SI 0 "register_operand")
13882 (unspec:SI [(match_dup 1) (match_dup 3)
13883 (match_dup 2) (reg:SI SP_REG)]
13885 (clobber (reg:CC FLAGS_REG))])]
13886 "!TARGET_64BIT && TARGET_GNU2_TLS"
13888 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13889 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13892 (define_insn "*tls_dynamic_gnu2_lea_32"
13893 [(set (match_operand:SI 0 "register_operand" "=r")
13894 (plus:SI (match_operand:SI 1 "register_operand" "b")
13896 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13897 UNSPEC_TLSDESC))))]
13898 "!TARGET_64BIT && TARGET_GNU2_TLS"
13899 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13900 [(set_attr "type" "lea")
13901 (set_attr "mode" "SI")
13902 (set_attr "length" "6")
13903 (set_attr "length_address" "4")])
13905 (define_insn "*tls_dynamic_gnu2_call_32"
13906 [(set (match_operand:SI 0 "register_operand" "=a")
13907 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13908 (match_operand:SI 2 "register_operand" "0")
13909 ;; we have to make sure %ebx still points to the GOT
13910 (match_operand:SI 3 "register_operand" "b")
13913 (clobber (reg:CC FLAGS_REG))]
13914 "!TARGET_64BIT && TARGET_GNU2_TLS"
13915 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13916 [(set_attr "type" "call")
13917 (set_attr "length" "2")
13918 (set_attr "length_address" "0")])
13920 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13921 [(set (match_operand:SI 0 "register_operand" "=&a")
13923 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13924 (match_operand:SI 4)
13925 (match_operand:SI 2 "register_operand" "b")
13928 (const:SI (unspec:SI
13929 [(match_operand 1 "tls_symbolic_operand")]
13931 (clobber (reg:CC FLAGS_REG))]
13932 "!TARGET_64BIT && TARGET_GNU2_TLS"
13935 [(set (match_dup 0) (match_dup 5))]
13937 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13938 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13941 (define_expand "tls_dynamic_gnu2_64"
13942 [(set (match_dup 2)
13943 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13946 [(set (match_operand:DI 0 "register_operand")
13947 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13949 (clobber (reg:CC FLAGS_REG))])]
13950 "TARGET_64BIT && TARGET_GNU2_TLS"
13952 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13953 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13956 (define_insn "*tls_dynamic_gnu2_lea_64"
13957 [(set (match_operand:DI 0 "register_operand" "=r")
13958 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13960 "TARGET_64BIT && TARGET_GNU2_TLS"
13961 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13962 [(set_attr "type" "lea")
13963 (set_attr "mode" "DI")
13964 (set_attr "length" "7")
13965 (set_attr "length_address" "4")])
13967 (define_insn "*tls_dynamic_gnu2_call_64"
13968 [(set (match_operand:DI 0 "register_operand" "=a")
13969 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13970 (match_operand:DI 2 "register_operand" "0")
13973 (clobber (reg:CC FLAGS_REG))]
13974 "TARGET_64BIT && TARGET_GNU2_TLS"
13975 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13976 [(set_attr "type" "call")
13977 (set_attr "length" "2")
13978 (set_attr "length_address" "0")])
13980 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13981 [(set (match_operand:DI 0 "register_operand" "=&a")
13983 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13984 (match_operand:DI 3)
13987 (const:DI (unspec:DI
13988 [(match_operand 1 "tls_symbolic_operand")]
13990 (clobber (reg:CC FLAGS_REG))]
13991 "TARGET_64BIT && TARGET_GNU2_TLS"
13994 [(set (match_dup 0) (match_dup 4))]
13996 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13997 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14000 ;; These patterns match the binary 387 instructions for addM3, subM3,
14001 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14002 ;; SFmode. The first is the normal insn, the second the same insn but
14003 ;; with one operand a conversion, and the third the same insn but with
14004 ;; the other operand a conversion. The conversion may be SFmode or
14005 ;; SImode if the target mode DFmode, but only SImode if the target mode
14008 ;; Gcc is slightly more smart about handling normal two address instructions
14009 ;; so use special patterns for add and mull.
14011 (define_insn "*fop_<mode>_comm_mixed"
14012 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
14013 (match_operator:MODEF 3 "binary_fp_operator"
14014 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
14015 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
14016 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14017 && COMMUTATIVE_ARITH_P (operands[3])
14018 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14019 "* return output_387_binary_op (insn, operands);"
14020 [(set (attr "type")
14021 (if_then_else (eq_attr "alternative" "1,2")
14022 (if_then_else (match_operand:MODEF 3 "mult_operator")
14023 (const_string "ssemul")
14024 (const_string "sseadd"))
14025 (if_then_else (match_operand:MODEF 3 "mult_operator")
14026 (const_string "fmul")
14027 (const_string "fop"))))
14028 (set_attr "isa" "*,noavx,avx")
14029 (set_attr "prefix" "orig,orig,vex")
14030 (set_attr "mode" "<MODE>")
14031 (set (attr "enabled")
14032 (cond [(eq_attr "alternative" "0")
14033 (symbol_ref "TARGET_MIX_SSE_I387")
14035 (const_string "*")))])
14037 (define_insn "*fop_<mode>_comm_i387"
14038 [(set (match_operand:MODEF 0 "register_operand" "=f")
14039 (match_operator:MODEF 3 "binary_fp_operator"
14040 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
14041 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
14042 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
14043 && COMMUTATIVE_ARITH_P (operands[3])
14044 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14045 "* return output_387_binary_op (insn, operands);"
14046 [(set (attr "type")
14047 (if_then_else (match_operand:MODEF 3 "mult_operator")
14048 (const_string "fmul")
14049 (const_string "fop")))
14050 (set_attr "mode" "<MODE>")])
14052 (define_insn "*rcpsf2_sse"
14053 [(set (match_operand:SF 0 "register_operand" "=x")
14054 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14057 "%vrcpss\t{%1, %d0|%d0, %1}"
14058 [(set_attr "type" "sse")
14059 (set_attr "atom_sse_attr" "rcp")
14060 (set_attr "btver2_sse_attr" "rcp")
14061 (set_attr "prefix" "maybe_vex")
14062 (set_attr "mode" "SF")])
14064 (define_insn "*fop_<mode>_1_mixed"
14065 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
14066 (match_operator:MODEF 3 "binary_fp_operator"
14067 [(match_operand:MODEF 1
14068 "register_mixssei387nonimm_operand" "0,fm,0,v")
14069 (match_operand:MODEF 2
14070 "nonimmediate_operand" "fm,0,xm,vm")]))]
14071 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14072 && !COMMUTATIVE_ARITH_P (operands[3])
14073 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14074 "* return output_387_binary_op (insn, operands);"
14075 [(set (attr "type")
14076 (cond [(and (eq_attr "alternative" "2,3")
14077 (match_operand:MODEF 3 "mult_operator"))
14078 (const_string "ssemul")
14079 (and (eq_attr "alternative" "2,3")
14080 (match_operand:MODEF 3 "div_operator"))
14081 (const_string "ssediv")
14082 (eq_attr "alternative" "2,3")
14083 (const_string "sseadd")
14084 (match_operand:MODEF 3 "mult_operator")
14085 (const_string "fmul")
14086 (match_operand:MODEF 3 "div_operator")
14087 (const_string "fdiv")
14089 (const_string "fop")))
14090 (set_attr "isa" "*,*,noavx,avx")
14091 (set_attr "prefix" "orig,orig,orig,vex")
14092 (set_attr "mode" "<MODE>")
14093 (set (attr "enabled")
14094 (cond [(eq_attr "alternative" "0,1")
14095 (symbol_ref "TARGET_MIX_SSE_I387")
14097 (const_string "*")))])
14099 ;; This pattern is not fully shadowed by the pattern above.
14100 (define_insn "*fop_<mode>_1_i387"
14101 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
14102 (match_operator:MODEF 3 "binary_fp_operator"
14103 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
14104 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
14105 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
14106 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14107 && !COMMUTATIVE_ARITH_P (operands[3])
14108 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14109 "* return output_387_binary_op (insn, operands);"
14110 [(set (attr "type")
14111 (cond [(match_operand:MODEF 3 "mult_operator")
14112 (const_string "fmul")
14113 (match_operand:MODEF 3 "div_operator")
14114 (const_string "fdiv")
14116 (const_string "fop")))
14117 (set_attr "mode" "<MODE>")])
14119 ;; ??? Add SSE splitters for these!
14120 (define_insn "*fop_<MODEF:mode>_2_i387"
14121 [(set (match_operand:MODEF 0 "register_operand" "=f")
14122 (match_operator:MODEF 3 "binary_fp_operator"
14124 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14125 (match_operand:MODEF 2 "register_operand" "0")]))]
14126 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14127 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14128 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14129 || optimize_function_for_size_p (cfun))"
14130 { return output_387_binary_op (insn, operands); }
14131 [(set (attr "type")
14132 (cond [(match_operand:MODEF 3 "mult_operator")
14133 (const_string "fmul")
14134 (match_operand:MODEF 3 "div_operator")
14135 (const_string "fdiv")
14137 (const_string "fop")))
14138 (set_attr "fp_int_src" "true")
14139 (set_attr "mode" "<SWI24:MODE>")])
14141 (define_insn "*fop_<MODEF:mode>_3_i387"
14142 [(set (match_operand:MODEF 0 "register_operand" "=f")
14143 (match_operator:MODEF 3 "binary_fp_operator"
14144 [(match_operand:MODEF 1 "register_operand" "0")
14146 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14147 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14148 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14149 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14150 || optimize_function_for_size_p (cfun))"
14151 { return output_387_binary_op (insn, operands); }
14152 [(set (attr "type")
14153 (cond [(match_operand:MODEF 3 "mult_operator")
14154 (const_string "fmul")
14155 (match_operand:MODEF 3 "div_operator")
14156 (const_string "fdiv")
14158 (const_string "fop")))
14159 (set_attr "fp_int_src" "true")
14160 (set_attr "mode" "<MODE>")])
14162 (define_insn "*fop_df_4_i387"
14163 [(set (match_operand:DF 0 "register_operand" "=f,f")
14164 (match_operator:DF 3 "binary_fp_operator"
14166 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14167 (match_operand:DF 2 "register_operand" "0,f")]))]
14168 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14169 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14170 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14171 "* return output_387_binary_op (insn, operands);"
14172 [(set (attr "type")
14173 (cond [(match_operand:DF 3 "mult_operator")
14174 (const_string "fmul")
14175 (match_operand:DF 3 "div_operator")
14176 (const_string "fdiv")
14178 (const_string "fop")))
14179 (set_attr "mode" "SF")])
14181 (define_insn "*fop_df_5_i387"
14182 [(set (match_operand:DF 0 "register_operand" "=f,f")
14183 (match_operator:DF 3 "binary_fp_operator"
14184 [(match_operand:DF 1 "register_operand" "0,f")
14186 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14187 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14188 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14189 "* return output_387_binary_op (insn, operands);"
14190 [(set (attr "type")
14191 (cond [(match_operand:DF 3 "mult_operator")
14192 (const_string "fmul")
14193 (match_operand:DF 3 "div_operator")
14194 (const_string "fdiv")
14196 (const_string "fop")))
14197 (set_attr "mode" "SF")])
14199 (define_insn "*fop_df_6_i387"
14200 [(set (match_operand:DF 0 "register_operand" "=f,f")
14201 (match_operator:DF 3 "binary_fp_operator"
14203 (match_operand:SF 1 "register_operand" "0,f"))
14205 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14206 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14207 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14208 "* return output_387_binary_op (insn, operands);"
14209 [(set (attr "type")
14210 (cond [(match_operand:DF 3 "mult_operator")
14211 (const_string "fmul")
14212 (match_operand:DF 3 "div_operator")
14213 (const_string "fdiv")
14215 (const_string "fop")))
14216 (set_attr "mode" "SF")])
14218 (define_insn "*fop_xf_comm_i387"
14219 [(set (match_operand:XF 0 "register_operand" "=f")
14220 (match_operator:XF 3 "binary_fp_operator"
14221 [(match_operand:XF 1 "register_operand" "%0")
14222 (match_operand:XF 2 "register_operand" "f")]))]
14224 && COMMUTATIVE_ARITH_P (operands[3])"
14225 "* return output_387_binary_op (insn, operands);"
14226 [(set (attr "type")
14227 (if_then_else (match_operand:XF 3 "mult_operator")
14228 (const_string "fmul")
14229 (const_string "fop")))
14230 (set_attr "mode" "XF")])
14232 (define_insn "*fop_xf_1_i387"
14233 [(set (match_operand:XF 0 "register_operand" "=f,f")
14234 (match_operator:XF 3 "binary_fp_operator"
14235 [(match_operand:XF 1 "register_operand" "0,f")
14236 (match_operand:XF 2 "register_operand" "f,0")]))]
14238 && !COMMUTATIVE_ARITH_P (operands[3])"
14239 "* return output_387_binary_op (insn, operands);"
14240 [(set (attr "type")
14241 (cond [(match_operand:XF 3 "mult_operator")
14242 (const_string "fmul")
14243 (match_operand:XF 3 "div_operator")
14244 (const_string "fdiv")
14246 (const_string "fop")))
14247 (set_attr "mode" "XF")])
14249 (define_insn "*fop_xf_2_i387"
14250 [(set (match_operand:XF 0 "register_operand" "=f")
14251 (match_operator:XF 3 "binary_fp_operator"
14253 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14254 (match_operand:XF 2 "register_operand" "0")]))]
14256 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14257 { return output_387_binary_op (insn, operands); }
14258 [(set (attr "type")
14259 (cond [(match_operand:XF 3 "mult_operator")
14260 (const_string "fmul")
14261 (match_operand:XF 3 "div_operator")
14262 (const_string "fdiv")
14264 (const_string "fop")))
14265 (set_attr "fp_int_src" "true")
14266 (set_attr "mode" "<MODE>")])
14268 (define_insn "*fop_xf_3_i387"
14269 [(set (match_operand:XF 0 "register_operand" "=f")
14270 (match_operator:XF 3 "binary_fp_operator"
14271 [(match_operand:XF 1 "register_operand" "0")
14273 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14275 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14276 { return output_387_binary_op (insn, operands); }
14277 [(set (attr "type")
14278 (cond [(match_operand:XF 3 "mult_operator")
14279 (const_string "fmul")
14280 (match_operand:XF 3 "div_operator")
14281 (const_string "fdiv")
14283 (const_string "fop")))
14284 (set_attr "fp_int_src" "true")
14285 (set_attr "mode" "<MODE>")])
14287 (define_insn "*fop_xf_4_i387"
14288 [(set (match_operand:XF 0 "register_operand" "=f,f")
14289 (match_operator:XF 3 "binary_fp_operator"
14291 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
14292 (match_operand:XF 2 "register_operand" "0,f")]))]
14294 "* return output_387_binary_op (insn, operands);"
14295 [(set (attr "type")
14296 (cond [(match_operand:XF 3 "mult_operator")
14297 (const_string "fmul")
14298 (match_operand:XF 3 "div_operator")
14299 (const_string "fdiv")
14301 (const_string "fop")))
14302 (set_attr "mode" "<MODE>")])
14304 (define_insn "*fop_xf_5_i387"
14305 [(set (match_operand:XF 0 "register_operand" "=f,f")
14306 (match_operator:XF 3 "binary_fp_operator"
14307 [(match_operand:XF 1 "register_operand" "0,f")
14309 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14311 "* return output_387_binary_op (insn, operands);"
14312 [(set (attr "type")
14313 (cond [(match_operand:XF 3 "mult_operator")
14314 (const_string "fmul")
14315 (match_operand:XF 3 "div_operator")
14316 (const_string "fdiv")
14318 (const_string "fop")))
14319 (set_attr "mode" "<MODE>")])
14321 (define_insn "*fop_xf_6_i387"
14322 [(set (match_operand:XF 0 "register_operand" "=f,f")
14323 (match_operator:XF 3 "binary_fp_operator"
14325 (match_operand:MODEF 1 "register_operand" "0,f"))
14327 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14329 "* return output_387_binary_op (insn, operands);"
14330 [(set (attr "type")
14331 (cond [(match_operand:XF 3 "mult_operator")
14332 (const_string "fmul")
14333 (match_operand:XF 3 "div_operator")
14334 (const_string "fdiv")
14336 (const_string "fop")))
14337 (set_attr "mode" "<MODE>")])
14339 ;; FPU special functions.
14341 ;; This pattern implements a no-op XFmode truncation for
14342 ;; all fancy i386 XFmode math functions.
14344 (define_insn "truncxf<mode>2_i387_noop_unspec"
14345 [(set (match_operand:MODEF 0 "register_operand" "=f")
14346 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
14347 UNSPEC_TRUNC_NOOP))]
14348 "TARGET_USE_FANCY_MATH_387"
14349 "* return output_387_reg_move (insn, operands);"
14350 [(set_attr "type" "fmov")
14351 (set_attr "mode" "<MODE>")])
14353 (define_insn "sqrtxf2"
14354 [(set (match_operand:XF 0 "register_operand" "=f")
14355 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14356 "TARGET_USE_FANCY_MATH_387"
14358 [(set_attr "type" "fpspc")
14359 (set_attr "mode" "XF")
14360 (set_attr "athlon_decode" "direct")
14361 (set_attr "amdfam10_decode" "direct")
14362 (set_attr "bdver1_decode" "direct")])
14364 (define_insn "sqrt_extend<mode>xf2_i387"
14365 [(set (match_operand:XF 0 "register_operand" "=f")
14368 (match_operand:MODEF 1 "register_operand" "0"))))]
14369 "TARGET_USE_FANCY_MATH_387"
14371 [(set_attr "type" "fpspc")
14372 (set_attr "mode" "XF")
14373 (set_attr "athlon_decode" "direct")
14374 (set_attr "amdfam10_decode" "direct")
14375 (set_attr "bdver1_decode" "direct")])
14377 (define_insn "*rsqrtsf2_sse"
14378 [(set (match_operand:SF 0 "register_operand" "=x")
14379 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14382 "%vrsqrtss\t{%1, %d0|%d0, %1}"
14383 [(set_attr "type" "sse")
14384 (set_attr "atom_sse_attr" "rcp")
14385 (set_attr "btver2_sse_attr" "rcp")
14386 (set_attr "prefix" "maybe_vex")
14387 (set_attr "mode" "SF")])
14389 (define_expand "rsqrtsf2"
14390 [(set (match_operand:SF 0 "register_operand")
14391 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
14395 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
14399 (define_insn "*sqrt<mode>2_sse"
14400 [(set (match_operand:MODEF 0 "register_operand" "=v")
14402 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
14403 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14404 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
14405 [(set_attr "type" "sse")
14406 (set_attr "atom_sse_attr" "sqrt")
14407 (set_attr "btver2_sse_attr" "sqrt")
14408 (set_attr "prefix" "maybe_vex")
14409 (set_attr "mode" "<MODE>")
14410 (set_attr "athlon_decode" "*")
14411 (set_attr "amdfam10_decode" "*")
14412 (set_attr "bdver1_decode" "*")])
14414 (define_expand "sqrt<mode>2"
14415 [(set (match_operand:MODEF 0 "register_operand")
14417 (match_operand:MODEF 1 "nonimmediate_operand")))]
14418 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
14419 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14421 if (<MODE>mode == SFmode
14423 && TARGET_RECIP_SQRT
14424 && !optimize_function_for_size_p (cfun)
14425 && flag_finite_math_only && !flag_trapping_math
14426 && flag_unsafe_math_optimizations)
14428 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
14432 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
14434 rtx op0 = gen_reg_rtx (XFmode);
14435 rtx op1 = force_reg (<MODE>mode, operands[1]);
14437 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
14438 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
14443 (define_insn "fpremxf4_i387"
14444 [(set (match_operand:XF 0 "register_operand" "=f")
14445 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14446 (match_operand:XF 3 "register_operand" "1")]
14448 (set (match_operand:XF 1 "register_operand" "=u")
14449 (unspec:XF [(match_dup 2) (match_dup 3)]
14451 (set (reg:CCFP FPSR_REG)
14452 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14454 "TARGET_USE_FANCY_MATH_387
14455 && flag_finite_math_only"
14457 [(set_attr "type" "fpspc")
14458 (set_attr "znver1_decode" "vector")
14459 (set_attr "mode" "XF")])
14461 (define_expand "fmodxf3"
14462 [(use (match_operand:XF 0 "register_operand"))
14463 (use (match_operand:XF 1 "general_operand"))
14464 (use (match_operand:XF 2 "general_operand"))]
14465 "TARGET_USE_FANCY_MATH_387
14466 && flag_finite_math_only"
14468 rtx_code_label *label = gen_label_rtx ();
14470 rtx op1 = gen_reg_rtx (XFmode);
14471 rtx op2 = gen_reg_rtx (XFmode);
14473 emit_move_insn (op2, operands[2]);
14474 emit_move_insn (op1, operands[1]);
14476 emit_label (label);
14477 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14478 ix86_emit_fp_unordered_jump (label);
14479 LABEL_NUSES (label) = 1;
14481 emit_move_insn (operands[0], op1);
14485 (define_expand "fmod<mode>3"
14486 [(use (match_operand:MODEF 0 "register_operand"))
14487 (use (match_operand:MODEF 1 "general_operand"))
14488 (use (match_operand:MODEF 2 "general_operand"))]
14489 "TARGET_USE_FANCY_MATH_387
14490 && flag_finite_math_only"
14492 rtx (*gen_truncxf) (rtx, rtx);
14494 rtx_code_label *label = gen_label_rtx ();
14496 rtx op1 = gen_reg_rtx (XFmode);
14497 rtx op2 = gen_reg_rtx (XFmode);
14499 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14500 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14502 emit_label (label);
14503 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14504 ix86_emit_fp_unordered_jump (label);
14505 LABEL_NUSES (label) = 1;
14507 /* Truncate the result properly for strict SSE math. */
14508 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14509 && !TARGET_MIX_SSE_I387)
14510 gen_truncxf = gen_truncxf<mode>2;
14512 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14514 emit_insn (gen_truncxf (operands[0], op1));
14518 (define_insn "fprem1xf4_i387"
14519 [(set (match_operand:XF 0 "register_operand" "=f")
14520 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14521 (match_operand:XF 3 "register_operand" "1")]
14523 (set (match_operand:XF 1 "register_operand" "=u")
14524 (unspec:XF [(match_dup 2) (match_dup 3)]
14526 (set (reg:CCFP FPSR_REG)
14527 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14529 "TARGET_USE_FANCY_MATH_387
14530 && flag_finite_math_only"
14532 [(set_attr "type" "fpspc")
14533 (set_attr "znver1_decode" "vector")
14534 (set_attr "mode" "XF")])
14536 (define_expand "remainderxf3"
14537 [(use (match_operand:XF 0 "register_operand"))
14538 (use (match_operand:XF 1 "general_operand"))
14539 (use (match_operand:XF 2 "general_operand"))]
14540 "TARGET_USE_FANCY_MATH_387
14541 && flag_finite_math_only"
14543 rtx_code_label *label = gen_label_rtx ();
14545 rtx op1 = gen_reg_rtx (XFmode);
14546 rtx op2 = gen_reg_rtx (XFmode);
14548 emit_move_insn (op2, operands[2]);
14549 emit_move_insn (op1, operands[1]);
14551 emit_label (label);
14552 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14553 ix86_emit_fp_unordered_jump (label);
14554 LABEL_NUSES (label) = 1;
14556 emit_move_insn (operands[0], op1);
14560 (define_expand "remainder<mode>3"
14561 [(use (match_operand:MODEF 0 "register_operand"))
14562 (use (match_operand:MODEF 1 "general_operand"))
14563 (use (match_operand:MODEF 2 "general_operand"))]
14564 "TARGET_USE_FANCY_MATH_387
14565 && flag_finite_math_only"
14567 rtx (*gen_truncxf) (rtx, rtx);
14569 rtx_code_label *label = gen_label_rtx ();
14571 rtx op1 = gen_reg_rtx (XFmode);
14572 rtx op2 = gen_reg_rtx (XFmode);
14574 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14575 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14577 emit_label (label);
14579 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14580 ix86_emit_fp_unordered_jump (label);
14581 LABEL_NUSES (label) = 1;
14583 /* Truncate the result properly for strict SSE math. */
14584 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14585 && !TARGET_MIX_SSE_I387)
14586 gen_truncxf = gen_truncxf<mode>2;
14588 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14590 emit_insn (gen_truncxf (operands[0], op1));
14594 (define_int_iterator SINCOS
14598 (define_int_attr sincos
14599 [(UNSPEC_SIN "sin")
14600 (UNSPEC_COS "cos")])
14602 (define_insn "*<sincos>xf2_i387"
14603 [(set (match_operand:XF 0 "register_operand" "=f")
14604 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14606 "TARGET_USE_FANCY_MATH_387
14607 && flag_unsafe_math_optimizations"
14609 [(set_attr "type" "fpspc")
14610 (set_attr "znver1_decode" "vector")
14611 (set_attr "mode" "XF")])
14613 (define_insn "*<sincos>_extend<mode>xf2_i387"
14614 [(set (match_operand:XF 0 "register_operand" "=f")
14615 (unspec:XF [(float_extend:XF
14616 (match_operand:MODEF 1 "register_operand" "0"))]
14618 "TARGET_USE_FANCY_MATH_387
14619 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14620 || TARGET_MIX_SSE_I387)
14621 && flag_unsafe_math_optimizations"
14623 [(set_attr "type" "fpspc")
14624 (set_attr "znver1_decode" "vector")
14625 (set_attr "mode" "XF")])
14627 ;; When sincos pattern is defined, sin and cos builtin functions will be
14628 ;; expanded to sincos pattern with one of its outputs left unused.
14629 ;; CSE pass will figure out if two sincos patterns can be combined,
14630 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14631 ;; depending on the unused output.
14633 (define_insn "sincosxf3"
14634 [(set (match_operand:XF 0 "register_operand" "=f")
14635 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14636 UNSPEC_SINCOS_COS))
14637 (set (match_operand:XF 1 "register_operand" "=u")
14638 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14639 "TARGET_USE_FANCY_MATH_387
14640 && flag_unsafe_math_optimizations"
14642 [(set_attr "type" "fpspc")
14643 (set_attr "znver1_decode" "vector")
14644 (set_attr "mode" "XF")])
14647 [(set (match_operand:XF 0 "register_operand")
14648 (unspec:XF [(match_operand:XF 2 "register_operand")]
14649 UNSPEC_SINCOS_COS))
14650 (set (match_operand:XF 1 "register_operand")
14651 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14652 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14653 && can_create_pseudo_p ()"
14654 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14657 [(set (match_operand:XF 0 "register_operand")
14658 (unspec:XF [(match_operand:XF 2 "register_operand")]
14659 UNSPEC_SINCOS_COS))
14660 (set (match_operand:XF 1 "register_operand")
14661 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14662 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14663 && can_create_pseudo_p ()"
14664 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14666 (define_insn "sincos_extend<mode>xf3_i387"
14667 [(set (match_operand:XF 0 "register_operand" "=f")
14668 (unspec:XF [(float_extend:XF
14669 (match_operand:MODEF 2 "register_operand" "0"))]
14670 UNSPEC_SINCOS_COS))
14671 (set (match_operand:XF 1 "register_operand" "=u")
14672 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14673 "TARGET_USE_FANCY_MATH_387
14674 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14675 || TARGET_MIX_SSE_I387)
14676 && flag_unsafe_math_optimizations"
14678 [(set_attr "type" "fpspc")
14679 (set_attr "znver1_decode" "vector")
14680 (set_attr "mode" "XF")])
14683 [(set (match_operand:XF 0 "register_operand")
14684 (unspec:XF [(float_extend:XF
14685 (match_operand:MODEF 2 "register_operand"))]
14686 UNSPEC_SINCOS_COS))
14687 (set (match_operand:XF 1 "register_operand")
14688 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14689 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14690 && can_create_pseudo_p ()"
14691 [(set (match_dup 1)
14692 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14695 [(set (match_operand:XF 0 "register_operand")
14696 (unspec:XF [(float_extend:XF
14697 (match_operand:MODEF 2 "register_operand"))]
14698 UNSPEC_SINCOS_COS))
14699 (set (match_operand:XF 1 "register_operand")
14700 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14701 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14702 && can_create_pseudo_p ()"
14703 [(set (match_dup 0)
14704 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14706 (define_expand "sincos<mode>3"
14707 [(use (match_operand:MODEF 0 "register_operand"))
14708 (use (match_operand:MODEF 1 "register_operand"))
14709 (use (match_operand:MODEF 2 "register_operand"))]
14710 "TARGET_USE_FANCY_MATH_387
14711 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14712 || TARGET_MIX_SSE_I387)
14713 && flag_unsafe_math_optimizations"
14715 rtx op0 = gen_reg_rtx (XFmode);
14716 rtx op1 = gen_reg_rtx (XFmode);
14718 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14719 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14720 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14724 (define_insn "fptanxf4_i387"
14725 [(set (match_operand:XF 0 "register_operand" "=f")
14726 (match_operand:XF 3 "const_double_operand" "F"))
14727 (set (match_operand:XF 1 "register_operand" "=u")
14728 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14730 "TARGET_USE_FANCY_MATH_387
14731 && flag_unsafe_math_optimizations
14732 && standard_80387_constant_p (operands[3]) == 2"
14734 [(set_attr "type" "fpspc")
14735 (set_attr "znver1_decode" "vector")
14736 (set_attr "mode" "XF")])
14738 (define_insn "fptan_extend<mode>xf4_i387"
14739 [(set (match_operand:MODEF 0 "register_operand" "=f")
14740 (match_operand:MODEF 3 "const_double_operand" "F"))
14741 (set (match_operand:XF 1 "register_operand" "=u")
14742 (unspec:XF [(float_extend:XF
14743 (match_operand:MODEF 2 "register_operand" "0"))]
14745 "TARGET_USE_FANCY_MATH_387
14746 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14747 || TARGET_MIX_SSE_I387)
14748 && flag_unsafe_math_optimizations
14749 && standard_80387_constant_p (operands[3]) == 2"
14751 [(set_attr "type" "fpspc")
14752 (set_attr "znver1_decode" "vector")
14753 (set_attr "mode" "XF")])
14755 (define_expand "tanxf2"
14756 [(use (match_operand:XF 0 "register_operand"))
14757 (use (match_operand:XF 1 "register_operand"))]
14758 "TARGET_USE_FANCY_MATH_387
14759 && flag_unsafe_math_optimizations"
14761 rtx one = gen_reg_rtx (XFmode);
14762 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14764 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14768 (define_expand "tan<mode>2"
14769 [(use (match_operand:MODEF 0 "register_operand"))
14770 (use (match_operand:MODEF 1 "register_operand"))]
14771 "TARGET_USE_FANCY_MATH_387
14772 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14773 || TARGET_MIX_SSE_I387)
14774 && flag_unsafe_math_optimizations"
14776 rtx op0 = gen_reg_rtx (XFmode);
14778 rtx one = gen_reg_rtx (<MODE>mode);
14779 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14781 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14782 operands[1], op2));
14783 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14787 (define_insn "*fpatanxf3_i387"
14788 [(set (match_operand:XF 0 "register_operand" "=f")
14789 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14790 (match_operand:XF 2 "register_operand" "u")]
14792 (clobber (match_scratch:XF 3 "=2"))]
14793 "TARGET_USE_FANCY_MATH_387
14794 && flag_unsafe_math_optimizations"
14796 [(set_attr "type" "fpspc")
14797 (set_attr "znver1_decode" "vector")
14798 (set_attr "mode" "XF")])
14800 (define_insn "fpatan_extend<mode>xf3_i387"
14801 [(set (match_operand:XF 0 "register_operand" "=f")
14802 (unspec:XF [(float_extend:XF
14803 (match_operand:MODEF 1 "register_operand" "0"))
14805 (match_operand:MODEF 2 "register_operand" "u"))]
14807 (clobber (match_scratch:XF 3 "=2"))]
14808 "TARGET_USE_FANCY_MATH_387
14809 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14810 || TARGET_MIX_SSE_I387)
14811 && flag_unsafe_math_optimizations"
14813 [(set_attr "type" "fpspc")
14814 (set_attr "znver1_decode" "vector")
14815 (set_attr "mode" "XF")])
14817 (define_expand "atan2xf3"
14818 [(parallel [(set (match_operand:XF 0 "register_operand")
14819 (unspec:XF [(match_operand:XF 2 "register_operand")
14820 (match_operand:XF 1 "register_operand")]
14822 (clobber (match_scratch:XF 3))])]
14823 "TARGET_USE_FANCY_MATH_387
14824 && flag_unsafe_math_optimizations")
14826 (define_expand "atan2<mode>3"
14827 [(use (match_operand:MODEF 0 "register_operand"))
14828 (use (match_operand:MODEF 1 "register_operand"))
14829 (use (match_operand:MODEF 2 "register_operand"))]
14830 "TARGET_USE_FANCY_MATH_387
14831 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14832 || TARGET_MIX_SSE_I387)
14833 && flag_unsafe_math_optimizations"
14835 rtx op0 = gen_reg_rtx (XFmode);
14837 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14838 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14842 (define_expand "atanxf2"
14843 [(parallel [(set (match_operand:XF 0 "register_operand")
14844 (unspec:XF [(match_dup 2)
14845 (match_operand:XF 1 "register_operand")]
14847 (clobber (match_scratch:XF 3))])]
14848 "TARGET_USE_FANCY_MATH_387
14849 && flag_unsafe_math_optimizations"
14851 operands[2] = gen_reg_rtx (XFmode);
14852 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14855 (define_expand "atan<mode>2"
14856 [(use (match_operand:MODEF 0 "register_operand"))
14857 (use (match_operand:MODEF 1 "register_operand"))]
14858 "TARGET_USE_FANCY_MATH_387
14859 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14860 || TARGET_MIX_SSE_I387)
14861 && flag_unsafe_math_optimizations"
14863 rtx op0 = gen_reg_rtx (XFmode);
14865 rtx op2 = gen_reg_rtx (<MODE>mode);
14866 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14868 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14869 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14873 (define_expand "asinxf2"
14874 [(set (match_dup 2)
14875 (mult:XF (match_operand:XF 1 "register_operand")
14877 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14878 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14879 (parallel [(set (match_operand:XF 0 "register_operand")
14880 (unspec:XF [(match_dup 5) (match_dup 1)]
14882 (clobber (match_scratch:XF 6))])]
14883 "TARGET_USE_FANCY_MATH_387
14884 && flag_unsafe_math_optimizations"
14888 for (i = 2; i < 6; i++)
14889 operands[i] = gen_reg_rtx (XFmode);
14891 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14894 (define_expand "asin<mode>2"
14895 [(use (match_operand:MODEF 0 "register_operand"))
14896 (use (match_operand:MODEF 1 "general_operand"))]
14897 "TARGET_USE_FANCY_MATH_387
14898 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14899 || TARGET_MIX_SSE_I387)
14900 && flag_unsafe_math_optimizations"
14902 rtx op0 = gen_reg_rtx (XFmode);
14903 rtx op1 = gen_reg_rtx (XFmode);
14905 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14906 emit_insn (gen_asinxf2 (op0, op1));
14907 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14911 (define_expand "acosxf2"
14912 [(set (match_dup 2)
14913 (mult:XF (match_operand:XF 1 "register_operand")
14915 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14916 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14917 (parallel [(set (match_operand:XF 0 "register_operand")
14918 (unspec:XF [(match_dup 1) (match_dup 5)]
14920 (clobber (match_scratch:XF 6))])]
14921 "TARGET_USE_FANCY_MATH_387
14922 && flag_unsafe_math_optimizations"
14926 for (i = 2; i < 6; i++)
14927 operands[i] = gen_reg_rtx (XFmode);
14929 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14932 (define_expand "acos<mode>2"
14933 [(use (match_operand:MODEF 0 "register_operand"))
14934 (use (match_operand:MODEF 1 "general_operand"))]
14935 "TARGET_USE_FANCY_MATH_387
14936 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14937 || TARGET_MIX_SSE_I387)
14938 && flag_unsafe_math_optimizations"
14940 rtx op0 = gen_reg_rtx (XFmode);
14941 rtx op1 = gen_reg_rtx (XFmode);
14943 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14944 emit_insn (gen_acosxf2 (op0, op1));
14945 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14949 (define_insn "fyl2xxf3_i387"
14950 [(set (match_operand:XF 0 "register_operand" "=f")
14951 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14952 (match_operand:XF 2 "register_operand" "u")]
14954 (clobber (match_scratch:XF 3 "=2"))]
14955 "TARGET_USE_FANCY_MATH_387
14956 && flag_unsafe_math_optimizations"
14958 [(set_attr "type" "fpspc")
14959 (set_attr "znver1_decode" "vector")
14960 (set_attr "mode" "XF")])
14962 (define_insn "fyl2x_extend<mode>xf3_i387"
14963 [(set (match_operand:XF 0 "register_operand" "=f")
14964 (unspec:XF [(float_extend:XF
14965 (match_operand:MODEF 1 "register_operand" "0"))
14966 (match_operand:XF 2 "register_operand" "u")]
14968 (clobber (match_scratch:XF 3 "=2"))]
14969 "TARGET_USE_FANCY_MATH_387
14970 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14971 || TARGET_MIX_SSE_I387)
14972 && flag_unsafe_math_optimizations"
14974 [(set_attr "type" "fpspc")
14975 (set_attr "znver1_decode" "vector")
14976 (set_attr "mode" "XF")])
14978 (define_expand "logxf2"
14979 [(parallel [(set (match_operand:XF 0 "register_operand")
14980 (unspec:XF [(match_operand:XF 1 "register_operand")
14981 (match_dup 2)] UNSPEC_FYL2X))
14982 (clobber (match_scratch:XF 3))])]
14983 "TARGET_USE_FANCY_MATH_387
14984 && flag_unsafe_math_optimizations"
14986 operands[2] = gen_reg_rtx (XFmode);
14987 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14990 (define_expand "log<mode>2"
14991 [(use (match_operand:MODEF 0 "register_operand"))
14992 (use (match_operand:MODEF 1 "register_operand"))]
14993 "TARGET_USE_FANCY_MATH_387
14994 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14995 || TARGET_MIX_SSE_I387)
14996 && flag_unsafe_math_optimizations"
14998 rtx op0 = gen_reg_rtx (XFmode);
15000 rtx op2 = gen_reg_rtx (XFmode);
15001 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
15003 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15004 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15008 (define_expand "log10xf2"
15009 [(parallel [(set (match_operand:XF 0 "register_operand")
15010 (unspec:XF [(match_operand:XF 1 "register_operand")
15011 (match_dup 2)] UNSPEC_FYL2X))
15012 (clobber (match_scratch:XF 3))])]
15013 "TARGET_USE_FANCY_MATH_387
15014 && flag_unsafe_math_optimizations"
15016 operands[2] = gen_reg_rtx (XFmode);
15017 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
15020 (define_expand "log10<mode>2"
15021 [(use (match_operand:MODEF 0 "register_operand"))
15022 (use (match_operand:MODEF 1 "register_operand"))]
15023 "TARGET_USE_FANCY_MATH_387
15024 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15025 || TARGET_MIX_SSE_I387)
15026 && flag_unsafe_math_optimizations"
15028 rtx op0 = gen_reg_rtx (XFmode);
15030 rtx op2 = gen_reg_rtx (XFmode);
15031 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
15033 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15034 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15038 (define_expand "log2xf2"
15039 [(parallel [(set (match_operand:XF 0 "register_operand")
15040 (unspec:XF [(match_operand:XF 1 "register_operand")
15041 (match_dup 2)] UNSPEC_FYL2X))
15042 (clobber (match_scratch:XF 3))])]
15043 "TARGET_USE_FANCY_MATH_387
15044 && flag_unsafe_math_optimizations"
15046 operands[2] = gen_reg_rtx (XFmode);
15047 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15050 (define_expand "log2<mode>2"
15051 [(use (match_operand:MODEF 0 "register_operand"))
15052 (use (match_operand:MODEF 1 "register_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);
15060 rtx op2 = gen_reg_rtx (XFmode);
15061 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15063 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15064 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15068 (define_insn "fyl2xp1xf3_i387"
15069 [(set (match_operand:XF 0 "register_operand" "=f")
15070 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15071 (match_operand:XF 2 "register_operand" "u")]
15073 (clobber (match_scratch:XF 3 "=2"))]
15074 "TARGET_USE_FANCY_MATH_387
15075 && flag_unsafe_math_optimizations"
15077 [(set_attr "type" "fpspc")
15078 (set_attr "znver1_decode" "vector")
15079 (set_attr "mode" "XF")])
15081 (define_insn "fyl2xp1_extend<mode>xf3_i387"
15082 [(set (match_operand:XF 0 "register_operand" "=f")
15083 (unspec:XF [(float_extend:XF
15084 (match_operand:MODEF 1 "register_operand" "0"))
15085 (match_operand:XF 2 "register_operand" "u")]
15087 (clobber (match_scratch:XF 3 "=2"))]
15088 "TARGET_USE_FANCY_MATH_387
15089 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15090 || TARGET_MIX_SSE_I387)
15091 && flag_unsafe_math_optimizations"
15093 [(set_attr "type" "fpspc")
15094 (set_attr "znver1_decode" "vector")
15095 (set_attr "mode" "XF")])
15097 (define_expand "log1pxf2"
15098 [(use (match_operand:XF 0 "register_operand"))
15099 (use (match_operand:XF 1 "register_operand"))]
15100 "TARGET_USE_FANCY_MATH_387
15101 && flag_unsafe_math_optimizations"
15103 ix86_emit_i387_log1p (operands[0], operands[1]);
15107 (define_expand "log1p<mode>2"
15108 [(use (match_operand:MODEF 0 "register_operand"))
15109 (use (match_operand:MODEF 1 "register_operand"))]
15110 "TARGET_USE_FANCY_MATH_387
15111 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15112 || TARGET_MIX_SSE_I387)
15113 && flag_unsafe_math_optimizations"
15117 op0 = gen_reg_rtx (XFmode);
15119 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
15121 ix86_emit_i387_log1p (op0, operands[1]);
15122 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15126 (define_insn "fxtractxf3_i387"
15127 [(set (match_operand:XF 0 "register_operand" "=f")
15128 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15129 UNSPEC_XTRACT_FRACT))
15130 (set (match_operand:XF 1 "register_operand" "=u")
15131 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15132 "TARGET_USE_FANCY_MATH_387
15133 && flag_unsafe_math_optimizations"
15135 [(set_attr "type" "fpspc")
15136 (set_attr "znver1_decode" "vector")
15137 (set_attr "mode" "XF")])
15139 (define_insn "fxtract_extend<mode>xf3_i387"
15140 [(set (match_operand:XF 0 "register_operand" "=f")
15141 (unspec:XF [(float_extend:XF
15142 (match_operand:MODEF 2 "register_operand" "0"))]
15143 UNSPEC_XTRACT_FRACT))
15144 (set (match_operand:XF 1 "register_operand" "=u")
15145 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
15146 "TARGET_USE_FANCY_MATH_387
15147 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15148 || TARGET_MIX_SSE_I387)
15149 && flag_unsafe_math_optimizations"
15151 [(set_attr "type" "fpspc")
15152 (set_attr "znver1_decode" "vector")
15153 (set_attr "mode" "XF")])
15155 (define_expand "logbxf2"
15156 [(parallel [(set (match_dup 2)
15157 (unspec:XF [(match_operand:XF 1 "register_operand")]
15158 UNSPEC_XTRACT_FRACT))
15159 (set (match_operand:XF 0 "register_operand")
15160 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15161 "TARGET_USE_FANCY_MATH_387
15162 && flag_unsafe_math_optimizations"
15163 "operands[2] = gen_reg_rtx (XFmode);")
15165 (define_expand "logb<mode>2"
15166 [(use (match_operand:MODEF 0 "register_operand"))
15167 (use (match_operand:MODEF 1 "register_operand"))]
15168 "TARGET_USE_FANCY_MATH_387
15169 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15170 || TARGET_MIX_SSE_I387)
15171 && flag_unsafe_math_optimizations"
15173 rtx op0 = gen_reg_rtx (XFmode);
15174 rtx op1 = gen_reg_rtx (XFmode);
15176 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15177 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
15181 (define_expand "ilogbxf2"
15182 [(use (match_operand:SI 0 "register_operand"))
15183 (use (match_operand:XF 1 "register_operand"))]
15184 "TARGET_USE_FANCY_MATH_387
15185 && flag_unsafe_math_optimizations"
15189 if (optimize_insn_for_size_p ())
15192 op0 = gen_reg_rtx (XFmode);
15193 op1 = gen_reg_rtx (XFmode);
15195 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
15196 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15200 (define_expand "ilogb<mode>2"
15201 [(use (match_operand:SI 0 "register_operand"))
15202 (use (match_operand:MODEF 1 "register_operand"))]
15203 "TARGET_USE_FANCY_MATH_387
15204 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15205 || TARGET_MIX_SSE_I387)
15206 && flag_unsafe_math_optimizations"
15210 if (optimize_insn_for_size_p ())
15213 op0 = gen_reg_rtx (XFmode);
15214 op1 = gen_reg_rtx (XFmode);
15216 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15217 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15221 (define_insn "*f2xm1xf2_i387"
15222 [(set (match_operand:XF 0 "register_operand" "=f")
15223 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15225 "TARGET_USE_FANCY_MATH_387
15226 && flag_unsafe_math_optimizations"
15228 [(set_attr "type" "fpspc")
15229 (set_attr "znver1_decode" "vector")
15230 (set_attr "mode" "XF")])
15232 (define_insn "fscalexf4_i387"
15233 [(set (match_operand:XF 0 "register_operand" "=f")
15234 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15235 (match_operand:XF 3 "register_operand" "1")]
15236 UNSPEC_FSCALE_FRACT))
15237 (set (match_operand:XF 1 "register_operand" "=u")
15238 (unspec:XF [(match_dup 2) (match_dup 3)]
15239 UNSPEC_FSCALE_EXP))]
15240 "TARGET_USE_FANCY_MATH_387
15241 && flag_unsafe_math_optimizations"
15243 [(set_attr "type" "fpspc")
15244 (set_attr "znver1_decode" "vector")
15245 (set_attr "mode" "XF")])
15247 (define_expand "expNcorexf3"
15248 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15249 (match_operand:XF 2 "register_operand")))
15250 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15251 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15252 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15253 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15254 (parallel [(set (match_operand:XF 0 "register_operand")
15255 (unspec:XF [(match_dup 8) (match_dup 4)]
15256 UNSPEC_FSCALE_FRACT))
15258 (unspec:XF [(match_dup 8) (match_dup 4)]
15259 UNSPEC_FSCALE_EXP))])]
15260 "TARGET_USE_FANCY_MATH_387
15261 && flag_unsafe_math_optimizations"
15265 for (i = 3; i < 10; i++)
15266 operands[i] = gen_reg_rtx (XFmode);
15268 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15271 (define_expand "expxf2"
15272 [(use (match_operand:XF 0 "register_operand"))
15273 (use (match_operand:XF 1 "register_operand"))]
15274 "TARGET_USE_FANCY_MATH_387
15275 && flag_unsafe_math_optimizations"
15279 op2 = gen_reg_rtx (XFmode);
15280 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
15282 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15286 (define_expand "exp<mode>2"
15287 [(use (match_operand:MODEF 0 "register_operand"))
15288 (use (match_operand:MODEF 1 "general_operand"))]
15289 "TARGET_USE_FANCY_MATH_387
15290 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15291 || TARGET_MIX_SSE_I387)
15292 && flag_unsafe_math_optimizations"
15296 op0 = gen_reg_rtx (XFmode);
15297 op1 = gen_reg_rtx (XFmode);
15299 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15300 emit_insn (gen_expxf2 (op0, op1));
15301 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15305 (define_expand "exp10xf2"
15306 [(use (match_operand:XF 0 "register_operand"))
15307 (use (match_operand:XF 1 "register_operand"))]
15308 "TARGET_USE_FANCY_MATH_387
15309 && flag_unsafe_math_optimizations"
15313 op2 = gen_reg_rtx (XFmode);
15314 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
15316 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15320 (define_expand "exp10<mode>2"
15321 [(use (match_operand:MODEF 0 "register_operand"))
15322 (use (match_operand:MODEF 1 "general_operand"))]
15323 "TARGET_USE_FANCY_MATH_387
15324 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15325 || TARGET_MIX_SSE_I387)
15326 && flag_unsafe_math_optimizations"
15330 op0 = gen_reg_rtx (XFmode);
15331 op1 = gen_reg_rtx (XFmode);
15333 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15334 emit_insn (gen_exp10xf2 (op0, op1));
15335 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15339 (define_expand "exp2xf2"
15340 [(use (match_operand:XF 0 "register_operand"))
15341 (use (match_operand:XF 1 "register_operand"))]
15342 "TARGET_USE_FANCY_MATH_387
15343 && flag_unsafe_math_optimizations"
15347 op2 = gen_reg_rtx (XFmode);
15348 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15350 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15354 (define_expand "exp2<mode>2"
15355 [(use (match_operand:MODEF 0 "register_operand"))
15356 (use (match_operand:MODEF 1 "general_operand"))]
15357 "TARGET_USE_FANCY_MATH_387
15358 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15359 || TARGET_MIX_SSE_I387)
15360 && flag_unsafe_math_optimizations"
15364 op0 = gen_reg_rtx (XFmode);
15365 op1 = gen_reg_rtx (XFmode);
15367 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15368 emit_insn (gen_exp2xf2 (op0, op1));
15369 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15373 (define_expand "expm1xf2"
15374 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15376 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15377 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15378 (set (match_dup 9) (float_extend:XF (match_dup 13)))
15379 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15380 (parallel [(set (match_dup 7)
15381 (unspec:XF [(match_dup 6) (match_dup 4)]
15382 UNSPEC_FSCALE_FRACT))
15384 (unspec:XF [(match_dup 6) (match_dup 4)]
15385 UNSPEC_FSCALE_EXP))])
15386 (parallel [(set (match_dup 10)
15387 (unspec:XF [(match_dup 9) (match_dup 8)]
15388 UNSPEC_FSCALE_FRACT))
15389 (set (match_dup 11)
15390 (unspec:XF [(match_dup 9) (match_dup 8)]
15391 UNSPEC_FSCALE_EXP))])
15392 (set (match_dup 12) (minus:XF (match_dup 10)
15393 (float_extend:XF (match_dup 13))))
15394 (set (match_operand:XF 0 "register_operand")
15395 (plus:XF (match_dup 12) (match_dup 7)))]
15396 "TARGET_USE_FANCY_MATH_387
15397 && flag_unsafe_math_optimizations"
15401 for (i = 2; i < 13; i++)
15402 operands[i] = gen_reg_rtx (XFmode);
15405 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
15407 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
15410 (define_expand "expm1<mode>2"
15411 [(use (match_operand:MODEF 0 "register_operand"))
15412 (use (match_operand:MODEF 1 "general_operand"))]
15413 "TARGET_USE_FANCY_MATH_387
15414 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15415 || TARGET_MIX_SSE_I387)
15416 && flag_unsafe_math_optimizations"
15420 op0 = gen_reg_rtx (XFmode);
15421 op1 = gen_reg_rtx (XFmode);
15423 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15424 emit_insn (gen_expm1xf2 (op0, op1));
15425 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15429 (define_expand "ldexpxf3"
15430 [(match_operand:XF 0 "register_operand")
15431 (match_operand:XF 1 "register_operand")
15432 (match_operand:SI 2 "register_operand")]
15433 "TARGET_USE_FANCY_MATH_387
15434 && flag_unsafe_math_optimizations"
15438 tmp1 = gen_reg_rtx (XFmode);
15439 tmp2 = gen_reg_rtx (XFmode);
15441 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
15442 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
15443 operands[1], tmp1));
15447 (define_expand "ldexp<mode>3"
15448 [(use (match_operand:MODEF 0 "register_operand"))
15449 (use (match_operand:MODEF 1 "general_operand"))
15450 (use (match_operand:SI 2 "register_operand"))]
15451 "TARGET_USE_FANCY_MATH_387
15452 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15453 || TARGET_MIX_SSE_I387)
15454 && flag_unsafe_math_optimizations"
15458 op0 = gen_reg_rtx (XFmode);
15459 op1 = gen_reg_rtx (XFmode);
15461 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15462 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15463 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15467 (define_expand "scalbxf3"
15468 [(parallel [(set (match_operand:XF 0 " register_operand")
15469 (unspec:XF [(match_operand:XF 1 "register_operand")
15470 (match_operand:XF 2 "register_operand")]
15471 UNSPEC_FSCALE_FRACT))
15473 (unspec:XF [(match_dup 1) (match_dup 2)]
15474 UNSPEC_FSCALE_EXP))])]
15475 "TARGET_USE_FANCY_MATH_387
15476 && flag_unsafe_math_optimizations"
15478 operands[3] = gen_reg_rtx (XFmode);
15481 (define_expand "scalb<mode>3"
15482 [(use (match_operand:MODEF 0 "register_operand"))
15483 (use (match_operand:MODEF 1 "general_operand"))
15484 (use (match_operand:MODEF 2 "general_operand"))]
15485 "TARGET_USE_FANCY_MATH_387
15486 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15487 || TARGET_MIX_SSE_I387)
15488 && flag_unsafe_math_optimizations"
15492 op0 = gen_reg_rtx (XFmode);
15493 op1 = gen_reg_rtx (XFmode);
15494 op2 = gen_reg_rtx (XFmode);
15496 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15497 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15498 emit_insn (gen_scalbxf3 (op0, op1, op2));
15499 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15503 (define_expand "significandxf2"
15504 [(parallel [(set (match_operand:XF 0 "register_operand")
15505 (unspec:XF [(match_operand:XF 1 "register_operand")]
15506 UNSPEC_XTRACT_FRACT))
15508 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15509 "TARGET_USE_FANCY_MATH_387
15510 && flag_unsafe_math_optimizations"
15511 "operands[2] = gen_reg_rtx (XFmode);")
15513 (define_expand "significand<mode>2"
15514 [(use (match_operand:MODEF 0 "register_operand"))
15515 (use (match_operand:MODEF 1 "register_operand"))]
15516 "TARGET_USE_FANCY_MATH_387
15517 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15518 || TARGET_MIX_SSE_I387)
15519 && flag_unsafe_math_optimizations"
15521 rtx op0 = gen_reg_rtx (XFmode);
15522 rtx op1 = gen_reg_rtx (XFmode);
15524 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15525 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15530 (define_insn "sse4_1_round<mode>2"
15531 [(set (match_operand:MODEF 0 "register_operand" "=x")
15532 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
15533 (match_operand:SI 2 "const_0_to_15_operand" "n")]
15536 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15537 [(set_attr "type" "ssecvt")
15538 (set_attr "prefix_extra" "1")
15539 (set_attr "prefix" "maybe_vex")
15540 (set_attr "mode" "<MODE>")])
15542 (define_insn "rintxf2"
15543 [(set (match_operand:XF 0 "register_operand" "=f")
15544 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15546 "TARGET_USE_FANCY_MATH_387
15547 && flag_unsafe_math_optimizations"
15549 [(set_attr "type" "fpspc")
15550 (set_attr "znver1_decode" "vector")
15551 (set_attr "mode" "XF")])
15553 (define_expand "rint<mode>2"
15554 [(use (match_operand:MODEF 0 "register_operand"))
15555 (use (match_operand:MODEF 1 "register_operand"))]
15556 "(TARGET_USE_FANCY_MATH_387
15557 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15558 || TARGET_MIX_SSE_I387)
15559 && flag_unsafe_math_optimizations)
15560 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15561 && !flag_trapping_math)"
15563 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15564 && !flag_trapping_math)
15567 emit_insn (gen_sse4_1_round<mode>2
15568 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
15570 ix86_expand_rint (operands[0], operands[1]);
15574 rtx op0 = gen_reg_rtx (XFmode);
15575 rtx op1 = gen_reg_rtx (XFmode);
15577 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15578 emit_insn (gen_rintxf2 (op0, op1));
15580 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15585 (define_expand "round<mode>2"
15586 [(match_operand:X87MODEF 0 "register_operand")
15587 (match_operand:X87MODEF 1 "nonimmediate_operand")]
15588 "(TARGET_USE_FANCY_MATH_387
15589 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15590 || TARGET_MIX_SSE_I387)
15591 && flag_unsafe_math_optimizations)
15592 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15593 && !flag_trapping_math && !flag_rounding_math)"
15595 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15596 && !flag_trapping_math && !flag_rounding_math)
15600 operands[1] = force_reg (<MODE>mode, operands[1]);
15601 ix86_expand_round_sse4 (operands[0], operands[1]);
15603 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15604 ix86_expand_round (operands[0], operands[1]);
15606 ix86_expand_rounddf_32 (operands[0], operands[1]);
15610 operands[1] = force_reg (<MODE>mode, operands[1]);
15611 ix86_emit_i387_round (operands[0], operands[1]);
15616 (define_insn_and_split "*fistdi2_1"
15617 [(set (match_operand:DI 0 "nonimmediate_operand")
15618 (unspec:DI [(match_operand:XF 1 "register_operand")]
15620 "TARGET_USE_FANCY_MATH_387
15621 && can_create_pseudo_p ()"
15626 if (memory_operand (operands[0], VOIDmode))
15627 emit_insn (gen_fistdi2 (operands[0], operands[1]));
15630 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15631 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15636 [(set_attr "type" "fpspc")
15637 (set_attr "mode" "DI")])
15639 (define_insn "fistdi2"
15640 [(set (match_operand:DI 0 "memory_operand" "=m")
15641 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15643 (clobber (match_scratch:XF 2 "=&1f"))]
15644 "TARGET_USE_FANCY_MATH_387"
15645 "* return output_fix_trunc (insn, operands, false);"
15646 [(set_attr "type" "fpspc")
15647 (set_attr "mode" "DI")])
15649 (define_insn "fistdi2_with_temp"
15650 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15651 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15653 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15654 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15655 "TARGET_USE_FANCY_MATH_387"
15657 [(set_attr "type" "fpspc")
15658 (set_attr "mode" "DI")])
15661 [(set (match_operand:DI 0 "register_operand")
15662 (unspec:DI [(match_operand:XF 1 "register_operand")]
15664 (clobber (match_operand:DI 2 "memory_operand"))
15665 (clobber (match_scratch 3))]
15667 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15668 (clobber (match_dup 3))])
15669 (set (match_dup 0) (match_dup 2))])
15672 [(set (match_operand:DI 0 "memory_operand")
15673 (unspec:DI [(match_operand:XF 1 "register_operand")]
15675 (clobber (match_operand:DI 2 "memory_operand"))
15676 (clobber (match_scratch 3))]
15678 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15679 (clobber (match_dup 3))])])
15681 (define_insn_and_split "*fist<mode>2_1"
15682 [(set (match_operand:SWI24 0 "register_operand")
15683 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15685 "TARGET_USE_FANCY_MATH_387
15686 && can_create_pseudo_p ()"
15691 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15692 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15696 [(set_attr "type" "fpspc")
15697 (set_attr "mode" "<MODE>")])
15699 (define_insn "fist<mode>2"
15700 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15701 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15703 "TARGET_USE_FANCY_MATH_387"
15704 "* return output_fix_trunc (insn, operands, false);"
15705 [(set_attr "type" "fpspc")
15706 (set_attr "mode" "<MODE>")])
15708 (define_insn "fist<mode>2_with_temp"
15709 [(set (match_operand:SWI24 0 "register_operand" "=r")
15710 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15712 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15713 "TARGET_USE_FANCY_MATH_387"
15715 [(set_attr "type" "fpspc")
15716 (set_attr "mode" "<MODE>")])
15719 [(set (match_operand:SWI24 0 "register_operand")
15720 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15722 (clobber (match_operand:SWI24 2 "memory_operand"))]
15724 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15725 (set (match_dup 0) (match_dup 2))])
15728 [(set (match_operand:SWI24 0 "memory_operand")
15729 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15731 (clobber (match_operand:SWI24 2 "memory_operand"))]
15733 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15735 (define_expand "lrintxf<mode>2"
15736 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15737 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15739 "TARGET_USE_FANCY_MATH_387")
15741 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15742 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15743 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15744 UNSPEC_FIX_NOTRUNC))]
15745 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15747 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15748 [(match_operand:SWI248x 0 "nonimmediate_operand")
15749 (match_operand:X87MODEF 1 "register_operand")]
15750 "(TARGET_USE_FANCY_MATH_387
15751 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15752 || TARGET_MIX_SSE_I387)
15753 && flag_unsafe_math_optimizations)
15754 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15755 && <SWI248x:MODE>mode != HImode
15756 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15757 && !flag_trapping_math && !flag_rounding_math)"
15759 if (optimize_insn_for_size_p ())
15762 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15763 && <SWI248x:MODE>mode != HImode
15764 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15765 && !flag_trapping_math && !flag_rounding_math)
15766 ix86_expand_lround (operands[0], operands[1]);
15768 ix86_emit_i387_round (operands[0], operands[1]);
15772 (define_int_iterator FRNDINT_ROUNDING
15773 [UNSPEC_FRNDINT_FLOOR
15774 UNSPEC_FRNDINT_CEIL
15775 UNSPEC_FRNDINT_TRUNC])
15777 (define_int_iterator FIST_ROUNDING
15781 ;; Base name for define_insn
15782 (define_int_attr rounding_insn
15783 [(UNSPEC_FRNDINT_FLOOR "floor")
15784 (UNSPEC_FRNDINT_CEIL "ceil")
15785 (UNSPEC_FRNDINT_TRUNC "btrunc")
15786 (UNSPEC_FIST_FLOOR "floor")
15787 (UNSPEC_FIST_CEIL "ceil")])
15789 (define_int_attr rounding
15790 [(UNSPEC_FRNDINT_FLOOR "floor")
15791 (UNSPEC_FRNDINT_CEIL "ceil")
15792 (UNSPEC_FRNDINT_TRUNC "trunc")
15793 (UNSPEC_FIST_FLOOR "floor")
15794 (UNSPEC_FIST_CEIL "ceil")])
15796 (define_int_attr ROUNDING
15797 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15798 (UNSPEC_FRNDINT_CEIL "CEIL")
15799 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15800 (UNSPEC_FIST_FLOOR "FLOOR")
15801 (UNSPEC_FIST_CEIL "CEIL")])
15803 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15804 (define_insn_and_split "frndintxf2_<rounding>"
15805 [(set (match_operand:XF 0 "register_operand")
15806 (unspec:XF [(match_operand:XF 1 "register_operand")]
15808 (clobber (reg:CC FLAGS_REG))]
15809 "TARGET_USE_FANCY_MATH_387
15810 && flag_unsafe_math_optimizations
15811 && can_create_pseudo_p ()"
15816 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15818 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15819 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15821 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15822 operands[2], operands[3]));
15825 [(set_attr "type" "frndint")
15826 (set_attr "i387_cw" "<rounding>")
15827 (set_attr "mode" "XF")])
15829 (define_insn "frndintxf2_<rounding>_i387"
15830 [(set (match_operand:XF 0 "register_operand" "=f")
15831 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15833 (use (match_operand:HI 2 "memory_operand" "m"))
15834 (use (match_operand:HI 3 "memory_operand" "m"))]
15835 "TARGET_USE_FANCY_MATH_387
15836 && flag_unsafe_math_optimizations"
15837 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15838 [(set_attr "type" "frndint")
15839 (set_attr "i387_cw" "<rounding>")
15840 (set_attr "mode" "XF")])
15842 (define_expand "<rounding_insn>xf2"
15843 [(parallel [(set (match_operand:XF 0 "register_operand")
15844 (unspec:XF [(match_operand:XF 1 "register_operand")]
15846 (clobber (reg:CC FLAGS_REG))])]
15847 "TARGET_USE_FANCY_MATH_387
15848 && flag_unsafe_math_optimizations")
15850 (define_expand "<rounding_insn><mode>2"
15851 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15852 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15854 (clobber (reg:CC FLAGS_REG))])]
15855 "(TARGET_USE_FANCY_MATH_387
15856 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15857 || TARGET_MIX_SSE_I387)
15858 && flag_unsafe_math_optimizations)
15859 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15860 && !flag_trapping_math)"
15862 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15863 && !flag_trapping_math)
15866 emit_insn (gen_sse4_1_round<mode>2
15867 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15868 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15870 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15871 ix86_expand_floorceil (operands[0], operands[1], true);
15872 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15873 ix86_expand_floorceil (operands[0], operands[1], false);
15874 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15875 ix86_expand_trunc (operands[0], operands[1]);
15877 gcc_unreachable ();
15881 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15882 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15883 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15884 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15885 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15886 ix86_expand_truncdf_32 (operands[0], operands[1]);
15888 gcc_unreachable ();
15895 op0 = gen_reg_rtx (XFmode);
15896 op1 = gen_reg_rtx (XFmode);
15897 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15898 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15900 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15905 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15906 (define_insn_and_split "frndintxf2_mask_pm"
15907 [(set (match_operand:XF 0 "register_operand")
15908 (unspec:XF [(match_operand:XF 1 "register_operand")]
15909 UNSPEC_FRNDINT_MASK_PM))
15910 (clobber (reg:CC FLAGS_REG))]
15911 "TARGET_USE_FANCY_MATH_387
15912 && flag_unsafe_math_optimizations
15913 && can_create_pseudo_p ()"
15918 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15920 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15921 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15923 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15924 operands[2], operands[3]));
15927 [(set_attr "type" "frndint")
15928 (set_attr "i387_cw" "mask_pm")
15929 (set_attr "mode" "XF")])
15931 (define_insn "frndintxf2_mask_pm_i387"
15932 [(set (match_operand:XF 0 "register_operand" "=f")
15933 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15934 UNSPEC_FRNDINT_MASK_PM))
15935 (use (match_operand:HI 2 "memory_operand" "m"))
15936 (use (match_operand:HI 3 "memory_operand" "m"))]
15937 "TARGET_USE_FANCY_MATH_387
15938 && flag_unsafe_math_optimizations"
15939 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15940 [(set_attr "type" "frndint")
15941 (set_attr "i387_cw" "mask_pm")
15942 (set_attr "mode" "XF")])
15944 (define_expand "nearbyintxf2"
15945 [(parallel [(set (match_operand:XF 0 "register_operand")
15946 (unspec:XF [(match_operand:XF 1 "register_operand")]
15947 UNSPEC_FRNDINT_MASK_PM))
15948 (clobber (reg:CC FLAGS_REG))])]
15949 "TARGET_USE_FANCY_MATH_387
15950 && flag_unsafe_math_optimizations")
15952 (define_expand "nearbyint<mode>2"
15953 [(use (match_operand:MODEF 0 "register_operand"))
15954 (use (match_operand:MODEF 1 "register_operand"))]
15955 "TARGET_USE_FANCY_MATH_387
15956 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15957 || TARGET_MIX_SSE_I387)
15958 && flag_unsafe_math_optimizations"
15960 rtx op0 = gen_reg_rtx (XFmode);
15961 rtx op1 = gen_reg_rtx (XFmode);
15963 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15964 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15966 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15970 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15971 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15972 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15973 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15975 (clobber (reg:CC FLAGS_REG))]
15976 "TARGET_USE_FANCY_MATH_387
15977 && flag_unsafe_math_optimizations
15978 && can_create_pseudo_p ()"
15983 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15985 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15986 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15987 if (memory_operand (operands[0], VOIDmode))
15988 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15989 operands[2], operands[3]));
15992 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15993 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15994 (operands[0], operands[1], operands[2],
15995 operands[3], operands[4]));
15999 [(set_attr "type" "fistp")
16000 (set_attr "i387_cw" "<rounding>")
16001 (set_attr "mode" "<MODE>")])
16003 (define_insn "fistdi2_<rounding>"
16004 [(set (match_operand:DI 0 "memory_operand" "=m")
16005 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16007 (use (match_operand:HI 2 "memory_operand" "m"))
16008 (use (match_operand:HI 3 "memory_operand" "m"))
16009 (clobber (match_scratch:XF 4 "=&1f"))]
16010 "TARGET_USE_FANCY_MATH_387
16011 && flag_unsafe_math_optimizations"
16012 "* return output_fix_trunc (insn, operands, false);"
16013 [(set_attr "type" "fistp")
16014 (set_attr "i387_cw" "<rounding>")
16015 (set_attr "mode" "DI")])
16017 (define_insn "fistdi2_<rounding>_with_temp"
16018 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16019 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16021 (use (match_operand:HI 2 "memory_operand" "m,m"))
16022 (use (match_operand:HI 3 "memory_operand" "m,m"))
16023 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
16024 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16025 "TARGET_USE_FANCY_MATH_387
16026 && flag_unsafe_math_optimizations"
16028 [(set_attr "type" "fistp")
16029 (set_attr "i387_cw" "<rounding>")
16030 (set_attr "mode" "DI")])
16033 [(set (match_operand:DI 0 "register_operand")
16034 (unspec:DI [(match_operand:XF 1 "register_operand")]
16036 (use (match_operand:HI 2 "memory_operand"))
16037 (use (match_operand:HI 3 "memory_operand"))
16038 (clobber (match_operand:DI 4 "memory_operand"))
16039 (clobber (match_scratch 5))]
16041 [(parallel [(set (match_dup 4)
16042 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16043 (use (match_dup 2))
16044 (use (match_dup 3))
16045 (clobber (match_dup 5))])
16046 (set (match_dup 0) (match_dup 4))])
16049 [(set (match_operand:DI 0 "memory_operand")
16050 (unspec:DI [(match_operand:XF 1 "register_operand")]
16052 (use (match_operand:HI 2 "memory_operand"))
16053 (use (match_operand:HI 3 "memory_operand"))
16054 (clobber (match_operand:DI 4 "memory_operand"))
16055 (clobber (match_scratch 5))]
16057 [(parallel [(set (match_dup 0)
16058 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16059 (use (match_dup 2))
16060 (use (match_dup 3))
16061 (clobber (match_dup 5))])])
16063 (define_insn "fist<mode>2_<rounding>"
16064 [(set (match_operand:SWI24 0 "memory_operand" "=m")
16065 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16067 (use (match_operand:HI 2 "memory_operand" "m"))
16068 (use (match_operand:HI 3 "memory_operand" "m"))]
16069 "TARGET_USE_FANCY_MATH_387
16070 && flag_unsafe_math_optimizations"
16071 "* return output_fix_trunc (insn, operands, false);"
16072 [(set_attr "type" "fistp")
16073 (set_attr "i387_cw" "<rounding>")
16074 (set_attr "mode" "<MODE>")])
16076 (define_insn "fist<mode>2_<rounding>_with_temp"
16077 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
16078 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
16080 (use (match_operand:HI 2 "memory_operand" "m,m"))
16081 (use (match_operand:HI 3 "memory_operand" "m,m"))
16082 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
16083 "TARGET_USE_FANCY_MATH_387
16084 && flag_unsafe_math_optimizations"
16086 [(set_attr "type" "fistp")
16087 (set_attr "i387_cw" "<rounding>")
16088 (set_attr "mode" "<MODE>")])
16091 [(set (match_operand:SWI24 0 "register_operand")
16092 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16094 (use (match_operand:HI 2 "memory_operand"))
16095 (use (match_operand:HI 3 "memory_operand"))
16096 (clobber (match_operand:SWI24 4 "memory_operand"))]
16098 [(parallel [(set (match_dup 4)
16099 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16100 (use (match_dup 2))
16101 (use (match_dup 3))])
16102 (set (match_dup 0) (match_dup 4))])
16105 [(set (match_operand:SWI24 0 "memory_operand")
16106 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16108 (use (match_operand:HI 2 "memory_operand"))
16109 (use (match_operand:HI 3 "memory_operand"))
16110 (clobber (match_operand:SWI24 4 "memory_operand"))]
16112 [(parallel [(set (match_dup 0)
16113 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16114 (use (match_dup 2))
16115 (use (match_dup 3))])])
16117 (define_expand "l<rounding_insn>xf<mode>2"
16118 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16119 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16121 (clobber (reg:CC FLAGS_REG))])]
16122 "TARGET_USE_FANCY_MATH_387
16123 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16124 && flag_unsafe_math_optimizations")
16126 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
16127 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
16128 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16130 (clobber (reg:CC FLAGS_REG))])]
16131 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16132 && !flag_trapping_math"
16134 if (TARGET_64BIT && optimize_insn_for_size_p ())
16137 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16138 ix86_expand_lfloorceil (operands[0], operands[1], true);
16139 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16140 ix86_expand_lfloorceil (operands[0], operands[1], false);
16142 gcc_unreachable ();
16147 (define_insn "fxam<mode>2_i387"
16148 [(set (match_operand:HI 0 "register_operand" "=a")
16150 [(match_operand:X87MODEF 1 "register_operand" "f")]
16152 "TARGET_USE_FANCY_MATH_387"
16153 "fxam\n\tfnstsw\t%0"
16154 [(set_attr "type" "multi")
16155 (set_attr "length" "4")
16156 (set_attr "unit" "i387")
16157 (set_attr "mode" "<MODE>")])
16159 (define_insn_and_split "fxam<mode>2_i387_with_temp"
16160 [(set (match_operand:HI 0 "register_operand")
16162 [(match_operand:MODEF 1 "memory_operand")]
16164 "TARGET_USE_FANCY_MATH_387
16165 && can_create_pseudo_p ()"
16168 [(set (match_dup 2)(match_dup 1))
16170 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
16172 operands[2] = gen_reg_rtx (<MODE>mode);
16174 MEM_VOLATILE_P (operands[1]) = 1;
16176 [(set_attr "type" "multi")
16177 (set_attr "unit" "i387")
16178 (set_attr "mode" "<MODE>")])
16180 (define_expand "isinfxf2"
16181 [(use (match_operand:SI 0 "register_operand"))
16182 (use (match_operand:XF 1 "register_operand"))]
16183 "TARGET_USE_FANCY_MATH_387
16184 && ix86_libc_has_function (function_c99_misc)"
16186 rtx mask = GEN_INT (0x45);
16187 rtx val = GEN_INT (0x05);
16191 rtx scratch = gen_reg_rtx (HImode);
16192 rtx res = gen_reg_rtx (QImode);
16194 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16196 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
16197 emit_insn (gen_cmpqi_ext_3 (scratch, val));
16198 cond = gen_rtx_fmt_ee (EQ, QImode,
16199 gen_rtx_REG (CCmode, FLAGS_REG),
16201 emit_insn (gen_rtx_SET (res, cond));
16202 emit_insn (gen_zero_extendqisi2 (operands[0], res));
16206 (define_expand "isinf<mode>2"
16207 [(use (match_operand:SI 0 "register_operand"))
16208 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
16209 "TARGET_USE_FANCY_MATH_387
16210 && ix86_libc_has_function (function_c99_misc)
16211 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16213 rtx mask = GEN_INT (0x45);
16214 rtx val = GEN_INT (0x05);
16218 rtx scratch = gen_reg_rtx (HImode);
16219 rtx res = gen_reg_rtx (QImode);
16221 /* Remove excess precision by forcing value through memory. */
16222 if (memory_operand (operands[1], VOIDmode))
16223 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
16226 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16228 emit_move_insn (temp, operands[1]);
16229 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
16232 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
16233 emit_insn (gen_cmpqi_ext_3 (scratch, val));
16234 cond = gen_rtx_fmt_ee (EQ, QImode,
16235 gen_rtx_REG (CCmode, FLAGS_REG),
16237 emit_insn (gen_rtx_SET (res, cond));
16238 emit_insn (gen_zero_extendqisi2 (operands[0], res));
16242 (define_expand "signbitxf2"
16243 [(use (match_operand:SI 0 "register_operand"))
16244 (use (match_operand:XF 1 "register_operand"))]
16245 "TARGET_USE_FANCY_MATH_387"
16247 rtx scratch = gen_reg_rtx (HImode);
16249 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16250 emit_insn (gen_andsi3 (operands[0],
16251 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16255 (define_insn "movmsk_df"
16256 [(set (match_operand:SI 0 "register_operand" "=r")
16258 [(match_operand:DF 1 "register_operand" "x")]
16260 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
16261 "%vmovmskpd\t{%1, %0|%0, %1}"
16262 [(set_attr "type" "ssemov")
16263 (set_attr "prefix" "maybe_vex")
16264 (set_attr "mode" "DF")])
16266 ;; Use movmskpd in SSE mode to avoid store forwarding stall
16267 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
16268 (define_expand "signbitdf2"
16269 [(use (match_operand:SI 0 "register_operand"))
16270 (use (match_operand:DF 1 "register_operand"))]
16271 "TARGET_USE_FANCY_MATH_387
16272 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
16274 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
16276 emit_insn (gen_movmsk_df (operands[0], operands[1]));
16277 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
16281 rtx scratch = gen_reg_rtx (HImode);
16283 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
16284 emit_insn (gen_andsi3 (operands[0],
16285 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16290 (define_expand "signbitsf2"
16291 [(use (match_operand:SI 0 "register_operand"))
16292 (use (match_operand:SF 1 "register_operand"))]
16293 "TARGET_USE_FANCY_MATH_387
16294 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
16296 rtx scratch = gen_reg_rtx (HImode);
16298 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
16299 emit_insn (gen_andsi3 (operands[0],
16300 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16304 ;; Block operation instructions
16307 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16310 [(set_attr "length" "1")
16311 (set_attr "length_immediate" "0")
16312 (set_attr "modrm" "0")])
16314 (define_expand "movmem<mode>"
16315 [(use (match_operand:BLK 0 "memory_operand"))
16316 (use (match_operand:BLK 1 "memory_operand"))
16317 (use (match_operand:SWI48 2 "nonmemory_operand"))
16318 (use (match_operand:SWI48 3 "const_int_operand"))
16319 (use (match_operand:SI 4 "const_int_operand"))
16320 (use (match_operand:SI 5 "const_int_operand"))
16321 (use (match_operand:SI 6 ""))
16322 (use (match_operand:SI 7 ""))
16323 (use (match_operand:SI 8 ""))]
16326 if (ix86_expand_set_or_movmem (operands[0], operands[1],
16327 operands[2], NULL, operands[3],
16328 operands[4], operands[5],
16329 operands[6], operands[7],
16330 operands[8], false))
16336 ;; Most CPUs don't like single string operations
16337 ;; Handle this case here to simplify previous expander.
16339 (define_expand "strmov"
16340 [(set (match_dup 4) (match_operand 3 "memory_operand"))
16341 (set (match_operand 1 "memory_operand") (match_dup 4))
16342 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
16343 (clobber (reg:CC FLAGS_REG))])
16344 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
16345 (clobber (reg:CC FLAGS_REG))])]
16348 /* Can't use this for non-default address spaces. */
16349 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
16352 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16354 /* If .md ever supports :P for Pmode, these can be directly
16355 in the pattern above. */
16356 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16357 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16359 /* Can't use this if the user has appropriated esi or edi. */
16360 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16361 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16363 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16364 operands[2], operands[3],
16365 operands[5], operands[6]));
16369 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16372 (define_expand "strmov_singleop"
16373 [(parallel [(set (match_operand 1 "memory_operand")
16374 (match_operand 3 "memory_operand"))
16375 (set (match_operand 0 "register_operand")
16377 (set (match_operand 2 "register_operand")
16378 (match_operand 5))])]
16380 "ix86_current_function_needs_cld = 1;")
16382 (define_insn "*strmovdi_rex_1"
16383 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16384 (mem:DI (match_operand:P 3 "register_operand" "1")))
16385 (set (match_operand:P 0 "register_operand" "=D")
16386 (plus:P (match_dup 2)
16388 (set (match_operand:P 1 "register_operand" "=S")
16389 (plus:P (match_dup 3)
16392 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16393 && ix86_check_no_addr_space (insn)"
16395 [(set_attr "type" "str")
16396 (set_attr "memory" "both")
16397 (set_attr "mode" "DI")])
16399 (define_insn "*strmovsi_1"
16400 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16401 (mem:SI (match_operand:P 3 "register_operand" "1")))
16402 (set (match_operand:P 0 "register_operand" "=D")
16403 (plus:P (match_dup 2)
16405 (set (match_operand:P 1 "register_operand" "=S")
16406 (plus:P (match_dup 3)
16408 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16409 && ix86_check_no_addr_space (insn)"
16411 [(set_attr "type" "str")
16412 (set_attr "memory" "both")
16413 (set_attr "mode" "SI")])
16415 (define_insn "*strmovhi_1"
16416 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16417 (mem:HI (match_operand:P 3 "register_operand" "1")))
16418 (set (match_operand:P 0 "register_operand" "=D")
16419 (plus:P (match_dup 2)
16421 (set (match_operand:P 1 "register_operand" "=S")
16422 (plus:P (match_dup 3)
16424 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16425 && ix86_check_no_addr_space (insn)"
16427 [(set_attr "type" "str")
16428 (set_attr "memory" "both")
16429 (set_attr "mode" "HI")])
16431 (define_insn "*strmovqi_1"
16432 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16433 (mem:QI (match_operand:P 3 "register_operand" "1")))
16434 (set (match_operand:P 0 "register_operand" "=D")
16435 (plus:P (match_dup 2)
16437 (set (match_operand:P 1 "register_operand" "=S")
16438 (plus:P (match_dup 3)
16440 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16441 && ix86_check_no_addr_space (insn)"
16443 [(set_attr "type" "str")
16444 (set_attr "memory" "both")
16445 (set (attr "prefix_rex")
16447 (match_test "<P:MODE>mode == DImode")
16449 (const_string "*")))
16450 (set_attr "mode" "QI")])
16452 (define_expand "rep_mov"
16453 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16454 (set (match_operand 0 "register_operand")
16456 (set (match_operand 2 "register_operand")
16458 (set (match_operand 1 "memory_operand")
16459 (match_operand 3 "memory_operand"))
16460 (use (match_dup 4))])]
16462 "ix86_current_function_needs_cld = 1;")
16464 (define_insn "*rep_movdi_rex64"
16465 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16466 (set (match_operand:P 0 "register_operand" "=D")
16467 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16469 (match_operand:P 3 "register_operand" "0")))
16470 (set (match_operand:P 1 "register_operand" "=S")
16471 (plus:P (ashift:P (match_dup 5) (const_int 3))
16472 (match_operand:P 4 "register_operand" "1")))
16473 (set (mem:BLK (match_dup 3))
16474 (mem:BLK (match_dup 4)))
16475 (use (match_dup 5))]
16477 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16478 && ix86_check_no_addr_space (insn)"
16480 [(set_attr "type" "str")
16481 (set_attr "prefix_rep" "1")
16482 (set_attr "memory" "both")
16483 (set_attr "mode" "DI")])
16485 (define_insn "*rep_movsi"
16486 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16487 (set (match_operand:P 0 "register_operand" "=D")
16488 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16490 (match_operand:P 3 "register_operand" "0")))
16491 (set (match_operand:P 1 "register_operand" "=S")
16492 (plus:P (ashift:P (match_dup 5) (const_int 2))
16493 (match_operand:P 4 "register_operand" "1")))
16494 (set (mem:BLK (match_dup 3))
16495 (mem:BLK (match_dup 4)))
16496 (use (match_dup 5))]
16497 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16498 && ix86_check_no_addr_space (insn)"
16499 "%^rep{%;} movs{l|d}"
16500 [(set_attr "type" "str")
16501 (set_attr "prefix_rep" "1")
16502 (set_attr "memory" "both")
16503 (set_attr "mode" "SI")])
16505 (define_insn "*rep_movqi"
16506 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16507 (set (match_operand:P 0 "register_operand" "=D")
16508 (plus:P (match_operand:P 3 "register_operand" "0")
16509 (match_operand:P 5 "register_operand" "2")))
16510 (set (match_operand:P 1 "register_operand" "=S")
16511 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16512 (set (mem:BLK (match_dup 3))
16513 (mem:BLK (match_dup 4)))
16514 (use (match_dup 5))]
16515 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16516 && ix86_check_no_addr_space (insn)"
16518 [(set_attr "type" "str")
16519 (set_attr "prefix_rep" "1")
16520 (set_attr "memory" "both")
16521 (set_attr "mode" "QI")])
16523 (define_expand "setmem<mode>"
16524 [(use (match_operand:BLK 0 "memory_operand"))
16525 (use (match_operand:SWI48 1 "nonmemory_operand"))
16526 (use (match_operand:QI 2 "nonmemory_operand"))
16527 (use (match_operand 3 "const_int_operand"))
16528 (use (match_operand:SI 4 "const_int_operand"))
16529 (use (match_operand:SI 5 "const_int_operand"))
16530 (use (match_operand:SI 6 ""))
16531 (use (match_operand:SI 7 ""))
16532 (use (match_operand:SI 8 ""))]
16535 if (ix86_expand_set_or_movmem (operands[0], NULL,
16536 operands[1], operands[2],
16537 operands[3], operands[4],
16538 operands[5], operands[6],
16539 operands[7], operands[8], true))
16545 ;; Most CPUs don't like single string operations
16546 ;; Handle this case here to simplify previous expander.
16548 (define_expand "strset"
16549 [(set (match_operand 1 "memory_operand")
16550 (match_operand 2 "register_operand"))
16551 (parallel [(set (match_operand 0 "register_operand")
16553 (clobber (reg:CC FLAGS_REG))])]
16556 /* Can't use this for non-default address spaces. */
16557 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
16560 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16561 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16563 /* If .md ever supports :P for Pmode, this can be directly
16564 in the pattern above. */
16565 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16566 GEN_INT (GET_MODE_SIZE (GET_MODE
16568 /* Can't use this if the user has appropriated eax or edi. */
16569 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16570 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16572 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16578 (define_expand "strset_singleop"
16579 [(parallel [(set (match_operand 1 "memory_operand")
16580 (match_operand 2 "register_operand"))
16581 (set (match_operand 0 "register_operand")
16583 (unspec [(const_int 0)] UNSPEC_STOS)])]
16585 "ix86_current_function_needs_cld = 1;")
16587 (define_insn "*strsetdi_rex_1"
16588 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16589 (match_operand:DI 2 "register_operand" "a"))
16590 (set (match_operand:P 0 "register_operand" "=D")
16591 (plus:P (match_dup 1)
16593 (unspec [(const_int 0)] UNSPEC_STOS)]
16595 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16596 && ix86_check_no_addr_space (insn)"
16598 [(set_attr "type" "str")
16599 (set_attr "memory" "store")
16600 (set_attr "mode" "DI")])
16602 (define_insn "*strsetsi_1"
16603 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16604 (match_operand:SI 2 "register_operand" "a"))
16605 (set (match_operand:P 0 "register_operand" "=D")
16606 (plus:P (match_dup 1)
16608 (unspec [(const_int 0)] UNSPEC_STOS)]
16609 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16610 && ix86_check_no_addr_space (insn)"
16612 [(set_attr "type" "str")
16613 (set_attr "memory" "store")
16614 (set_attr "mode" "SI")])
16616 (define_insn "*strsethi_1"
16617 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16618 (match_operand:HI 2 "register_operand" "a"))
16619 (set (match_operand:P 0 "register_operand" "=D")
16620 (plus:P (match_dup 1)
16622 (unspec [(const_int 0)] UNSPEC_STOS)]
16623 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16624 && ix86_check_no_addr_space (insn)"
16626 [(set_attr "type" "str")
16627 (set_attr "memory" "store")
16628 (set_attr "mode" "HI")])
16630 (define_insn "*strsetqi_1"
16631 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16632 (match_operand:QI 2 "register_operand" "a"))
16633 (set (match_operand:P 0 "register_operand" "=D")
16634 (plus:P (match_dup 1)
16636 (unspec [(const_int 0)] UNSPEC_STOS)]
16637 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16638 && ix86_check_no_addr_space (insn)"
16640 [(set_attr "type" "str")
16641 (set_attr "memory" "store")
16642 (set (attr "prefix_rex")
16644 (match_test "<P:MODE>mode == DImode")
16646 (const_string "*")))
16647 (set_attr "mode" "QI")])
16649 (define_expand "rep_stos"
16650 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16651 (set (match_operand 0 "register_operand")
16653 (set (match_operand 2 "memory_operand") (const_int 0))
16654 (use (match_operand 3 "register_operand"))
16655 (use (match_dup 1))])]
16657 "ix86_current_function_needs_cld = 1;")
16659 (define_insn "*rep_stosdi_rex64"
16660 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16661 (set (match_operand:P 0 "register_operand" "=D")
16662 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16664 (match_operand:P 3 "register_operand" "0")))
16665 (set (mem:BLK (match_dup 3))
16667 (use (match_operand:DI 2 "register_operand" "a"))
16668 (use (match_dup 4))]
16670 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16671 && ix86_check_no_addr_space (insn)"
16673 [(set_attr "type" "str")
16674 (set_attr "prefix_rep" "1")
16675 (set_attr "memory" "store")
16676 (set_attr "mode" "DI")])
16678 (define_insn "*rep_stossi"
16679 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16680 (set (match_operand:P 0 "register_operand" "=D")
16681 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16683 (match_operand:P 3 "register_operand" "0")))
16684 (set (mem:BLK (match_dup 3))
16686 (use (match_operand:SI 2 "register_operand" "a"))
16687 (use (match_dup 4))]
16688 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16689 && ix86_check_no_addr_space (insn)"
16690 "%^rep{%;} stos{l|d}"
16691 [(set_attr "type" "str")
16692 (set_attr "prefix_rep" "1")
16693 (set_attr "memory" "store")
16694 (set_attr "mode" "SI")])
16696 (define_insn "*rep_stosqi"
16697 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16698 (set (match_operand:P 0 "register_operand" "=D")
16699 (plus:P (match_operand:P 3 "register_operand" "0")
16700 (match_operand:P 4 "register_operand" "1")))
16701 (set (mem:BLK (match_dup 3))
16703 (use (match_operand:QI 2 "register_operand" "a"))
16704 (use (match_dup 4))]
16705 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16706 && ix86_check_no_addr_space (insn)"
16708 [(set_attr "type" "str")
16709 (set_attr "prefix_rep" "1")
16710 (set_attr "memory" "store")
16711 (set (attr "prefix_rex")
16713 (match_test "<P:MODE>mode == DImode")
16715 (const_string "*")))
16716 (set_attr "mode" "QI")])
16718 (define_expand "cmpstrnsi"
16719 [(set (match_operand:SI 0 "register_operand")
16720 (compare:SI (match_operand:BLK 1 "general_operand")
16721 (match_operand:BLK 2 "general_operand")))
16722 (use (match_operand 3 "general_operand"))
16723 (use (match_operand 4 "immediate_operand"))]
16726 rtx addr1, addr2, out, outlow, count, countreg, align;
16728 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16731 /* Can't use this if the user has appropriated ecx, esi or edi. */
16732 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16737 out = gen_reg_rtx (SImode);
16739 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16740 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16741 if (addr1 != XEXP (operands[1], 0))
16742 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16743 if (addr2 != XEXP (operands[2], 0))
16744 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16746 count = operands[3];
16747 countreg = ix86_zero_extend_to_Pmode (count);
16749 /* %%% Iff we are testing strict equality, we can use known alignment
16750 to good advantage. This may be possible with combine, particularly
16751 once cc0 is dead. */
16752 align = operands[4];
16754 if (CONST_INT_P (count))
16756 if (INTVAL (count) == 0)
16758 emit_move_insn (operands[0], const0_rtx);
16761 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16762 operands[1], operands[2]));
16766 rtx (*gen_cmp) (rtx, rtx);
16768 gen_cmp = (TARGET_64BIT
16769 ? gen_cmpdi_1 : gen_cmpsi_1);
16771 emit_insn (gen_cmp (countreg, countreg));
16772 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16773 operands[1], operands[2]));
16776 outlow = gen_lowpart (QImode, out);
16777 emit_insn (gen_cmpintqi (outlow));
16778 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16780 if (operands[0] != out)
16781 emit_move_insn (operands[0], out);
16786 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16788 (define_expand "cmpintqi"
16789 [(set (match_dup 1)
16790 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16792 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16793 (parallel [(set (match_operand:QI 0 "register_operand")
16794 (minus:QI (match_dup 1)
16796 (clobber (reg:CC FLAGS_REG))])]
16799 operands[1] = gen_reg_rtx (QImode);
16800 operands[2] = gen_reg_rtx (QImode);
16803 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16804 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16806 (define_expand "cmpstrnqi_nz_1"
16807 [(parallel [(set (reg:CC FLAGS_REG)
16808 (compare:CC (match_operand 4 "memory_operand")
16809 (match_operand 5 "memory_operand")))
16810 (use (match_operand 2 "register_operand"))
16811 (use (match_operand:SI 3 "immediate_operand"))
16812 (clobber (match_operand 0 "register_operand"))
16813 (clobber (match_operand 1 "register_operand"))
16814 (clobber (match_dup 2))])]
16816 "ix86_current_function_needs_cld = 1;")
16818 (define_insn "*cmpstrnqi_nz_1"
16819 [(set (reg:CC FLAGS_REG)
16820 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16821 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16822 (use (match_operand:P 6 "register_operand" "2"))
16823 (use (match_operand:SI 3 "immediate_operand" "i"))
16824 (clobber (match_operand:P 0 "register_operand" "=S"))
16825 (clobber (match_operand:P 1 "register_operand" "=D"))
16826 (clobber (match_operand:P 2 "register_operand" "=c"))]
16827 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16828 && ix86_check_no_addr_space (insn)"
16830 [(set_attr "type" "str")
16831 (set_attr "mode" "QI")
16832 (set (attr "prefix_rex")
16834 (match_test "<P:MODE>mode == DImode")
16836 (const_string "*")))
16837 (set_attr "prefix_rep" "1")])
16839 ;; The same, but the count is not known to not be zero.
16841 (define_expand "cmpstrnqi_1"
16842 [(parallel [(set (reg:CC FLAGS_REG)
16843 (if_then_else:CC (ne (match_operand 2 "register_operand")
16845 (compare:CC (match_operand 4 "memory_operand")
16846 (match_operand 5 "memory_operand"))
16848 (use (match_operand:SI 3 "immediate_operand"))
16849 (use (reg:CC FLAGS_REG))
16850 (clobber (match_operand 0 "register_operand"))
16851 (clobber (match_operand 1 "register_operand"))
16852 (clobber (match_dup 2))])]
16854 "ix86_current_function_needs_cld = 1;")
16856 (define_insn "*cmpstrnqi_1"
16857 [(set (reg:CC FLAGS_REG)
16858 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16860 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16861 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16863 (use (match_operand:SI 3 "immediate_operand" "i"))
16864 (use (reg:CC FLAGS_REG))
16865 (clobber (match_operand:P 0 "register_operand" "=S"))
16866 (clobber (match_operand:P 1 "register_operand" "=D"))
16867 (clobber (match_operand:P 2 "register_operand" "=c"))]
16868 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16869 && ix86_check_no_addr_space (insn)"
16871 [(set_attr "type" "str")
16872 (set_attr "mode" "QI")
16873 (set (attr "prefix_rex")
16875 (match_test "<P:MODE>mode == DImode")
16877 (const_string "*")))
16878 (set_attr "prefix_rep" "1")])
16880 (define_expand "strlen<mode>"
16881 [(set (match_operand:P 0 "register_operand")
16882 (unspec:P [(match_operand:BLK 1 "general_operand")
16883 (match_operand:QI 2 "immediate_operand")
16884 (match_operand 3 "immediate_operand")]
16888 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16894 (define_expand "strlenqi_1"
16895 [(parallel [(set (match_operand 0 "register_operand")
16897 (clobber (match_operand 1 "register_operand"))
16898 (clobber (reg:CC FLAGS_REG))])]
16900 "ix86_current_function_needs_cld = 1;")
16902 (define_insn "*strlenqi_1"
16903 [(set (match_operand:P 0 "register_operand" "=&c")
16904 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16905 (match_operand:QI 2 "register_operand" "a")
16906 (match_operand:P 3 "immediate_operand" "i")
16907 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16908 (clobber (match_operand:P 1 "register_operand" "=D"))
16909 (clobber (reg:CC FLAGS_REG))]
16910 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16911 && ix86_check_no_addr_space (insn)"
16912 "%^repnz{%;} scasb"
16913 [(set_attr "type" "str")
16914 (set_attr "mode" "QI")
16915 (set (attr "prefix_rex")
16917 (match_test "<P:MODE>mode == DImode")
16919 (const_string "*")))
16920 (set_attr "prefix_rep" "1")])
16922 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16923 ;; handled in combine, but it is not currently up to the task.
16924 ;; When used for their truth value, the cmpstrn* expanders generate
16933 ;; The intermediate three instructions are unnecessary.
16935 ;; This one handles cmpstrn*_nz_1...
16938 (set (reg:CC FLAGS_REG)
16939 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16940 (mem:BLK (match_operand 5 "register_operand"))))
16941 (use (match_operand 6 "register_operand"))
16942 (use (match_operand:SI 3 "immediate_operand"))
16943 (clobber (match_operand 0 "register_operand"))
16944 (clobber (match_operand 1 "register_operand"))
16945 (clobber (match_operand 2 "register_operand"))])
16946 (set (match_operand:QI 7 "register_operand")
16947 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16948 (set (match_operand:QI 8 "register_operand")
16949 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16950 (set (reg FLAGS_REG)
16951 (compare (match_dup 7) (match_dup 8)))
16953 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16955 (set (reg:CC FLAGS_REG)
16956 (compare:CC (mem:BLK (match_dup 4))
16957 (mem:BLK (match_dup 5))))
16958 (use (match_dup 6))
16959 (use (match_dup 3))
16960 (clobber (match_dup 0))
16961 (clobber (match_dup 1))
16962 (clobber (match_dup 2))])])
16964 ;; ...and this one handles cmpstrn*_1.
16967 (set (reg:CC FLAGS_REG)
16968 (if_then_else:CC (ne (match_operand 6 "register_operand")
16970 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16971 (mem:BLK (match_operand 5 "register_operand")))
16973 (use (match_operand:SI 3 "immediate_operand"))
16974 (use (reg:CC FLAGS_REG))
16975 (clobber (match_operand 0 "register_operand"))
16976 (clobber (match_operand 1 "register_operand"))
16977 (clobber (match_operand 2 "register_operand"))])
16978 (set (match_operand:QI 7 "register_operand")
16979 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16980 (set (match_operand:QI 8 "register_operand")
16981 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16982 (set (reg FLAGS_REG)
16983 (compare (match_dup 7) (match_dup 8)))
16985 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16987 (set (reg:CC FLAGS_REG)
16988 (if_then_else:CC (ne (match_dup 6)
16990 (compare:CC (mem:BLK (match_dup 4))
16991 (mem:BLK (match_dup 5)))
16993 (use (match_dup 3))
16994 (use (reg:CC FLAGS_REG))
16995 (clobber (match_dup 0))
16996 (clobber (match_dup 1))
16997 (clobber (match_dup 2))])])
16999 ;; Conditional move instructions.
17001 (define_expand "mov<mode>cc"
17002 [(set (match_operand:SWIM 0 "register_operand")
17003 (if_then_else:SWIM (match_operand 1 "comparison_operator")
17004 (match_operand:SWIM 2 "<general_operand>")
17005 (match_operand:SWIM 3 "<general_operand>")))]
17007 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
17009 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17010 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17011 ;; So just document what we're doing explicitly.
17013 (define_expand "x86_mov<mode>cc_0_m1"
17015 [(set (match_operand:SWI48 0 "register_operand")
17016 (if_then_else:SWI48
17017 (match_operator:SWI48 2 "ix86_carry_flag_operator"
17018 [(match_operand 1 "flags_reg_operand")
17022 (clobber (reg:CC FLAGS_REG))])])
17024 (define_insn "*x86_mov<mode>cc_0_m1"
17025 [(set (match_operand:SWI48 0 "register_operand" "=r")
17026 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17027 [(reg FLAGS_REG) (const_int 0)])
17030 (clobber (reg:CC FLAGS_REG))]
17032 "sbb{<imodesuffix>}\t%0, %0"
17033 ; Since we don't have the proper number of operands for an alu insn,
17034 ; fill in all the blanks.
17035 [(set_attr "type" "alu")
17036 (set_attr "modrm_class" "op0")
17037 (set_attr "use_carry" "1")
17038 (set_attr "pent_pair" "pu")
17039 (set_attr "memory" "none")
17040 (set_attr "imm_disp" "false")
17041 (set_attr "mode" "<MODE>")
17042 (set_attr "length_immediate" "0")])
17044 (define_insn "*x86_mov<mode>cc_0_m1_se"
17045 [(set (match_operand:SWI48 0 "register_operand" "=r")
17046 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17047 [(reg FLAGS_REG) (const_int 0)])
17050 (clobber (reg:CC FLAGS_REG))]
17052 "sbb{<imodesuffix>}\t%0, %0"
17053 [(set_attr "type" "alu")
17054 (set_attr "modrm_class" "op0")
17055 (set_attr "use_carry" "1")
17056 (set_attr "pent_pair" "pu")
17057 (set_attr "memory" "none")
17058 (set_attr "imm_disp" "false")
17059 (set_attr "mode" "<MODE>")
17060 (set_attr "length_immediate" "0")])
17062 (define_insn "*x86_mov<mode>cc_0_m1_neg"
17063 [(set (match_operand:SWI48 0 "register_operand" "=r")
17064 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17065 [(reg FLAGS_REG) (const_int 0)])))
17066 (clobber (reg:CC FLAGS_REG))]
17068 "sbb{<imodesuffix>}\t%0, %0"
17069 [(set_attr "type" "alu")
17070 (set_attr "modrm_class" "op0")
17071 (set_attr "use_carry" "1")
17072 (set_attr "pent_pair" "pu")
17073 (set_attr "memory" "none")
17074 (set_attr "imm_disp" "false")
17075 (set_attr "mode" "<MODE>")
17076 (set_attr "length_immediate" "0")])
17078 (define_insn "*mov<mode>cc_noc"
17079 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
17080 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17081 [(reg FLAGS_REG) (const_int 0)])
17082 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
17083 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
17084 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17086 cmov%O2%C1\t{%2, %0|%0, %2}
17087 cmov%O2%c1\t{%3, %0|%0, %3}"
17088 [(set_attr "type" "icmov")
17089 (set_attr "mode" "<MODE>")])
17091 (define_insn "*movsicc_noc_zext"
17092 [(set (match_operand:DI 0 "register_operand" "=r,r")
17093 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17094 [(reg FLAGS_REG) (const_int 0)])
17096 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
17098 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
17100 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17102 cmov%O2%C1\t{%2, %k0|%k0, %2}
17103 cmov%O2%c1\t{%3, %k0|%k0, %3}"
17104 [(set_attr "type" "icmov")
17105 (set_attr "mode" "SI")])
17107 ;; Don't do conditional moves with memory inputs. This splitter helps
17108 ;; register starved x86_32 by forcing inputs into registers before reload.
17110 [(set (match_operand:SWI248 0 "register_operand")
17111 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17112 [(reg FLAGS_REG) (const_int 0)])
17113 (match_operand:SWI248 2 "nonimmediate_operand")
17114 (match_operand:SWI248 3 "nonimmediate_operand")))]
17115 "!TARGET_64BIT && TARGET_CMOVE
17116 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17117 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17118 && can_create_pseudo_p ()
17119 && optimize_insn_for_speed_p ()"
17120 [(set (match_dup 0)
17121 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17123 if (MEM_P (operands[2]))
17124 operands[2] = force_reg (<MODE>mode, operands[2]);
17125 if (MEM_P (operands[3]))
17126 operands[3] = force_reg (<MODE>mode, operands[3]);
17129 (define_insn "*movqicc_noc"
17130 [(set (match_operand:QI 0 "register_operand" "=r,r")
17131 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17132 [(reg FLAGS_REG) (const_int 0)])
17133 (match_operand:QI 2 "register_operand" "r,0")
17134 (match_operand:QI 3 "register_operand" "0,r")))]
17135 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17137 [(set_attr "type" "icmov")
17138 (set_attr "mode" "QI")])
17141 [(set (match_operand:SWI12 0 "register_operand")
17142 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
17143 [(reg FLAGS_REG) (const_int 0)])
17144 (match_operand:SWI12 2 "register_operand")
17145 (match_operand:SWI12 3 "register_operand")))]
17146 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
17147 && reload_completed"
17148 [(set (match_dup 0)
17149 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17151 operands[0] = gen_lowpart (SImode, operands[0]);
17152 operands[2] = gen_lowpart (SImode, operands[2]);
17153 operands[3] = gen_lowpart (SImode, operands[3]);
17156 ;; Don't do conditional moves with memory inputs
17158 [(match_scratch:SWI248 4 "r")
17159 (set (match_operand:SWI248 0 "register_operand")
17160 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17161 [(reg FLAGS_REG) (const_int 0)])
17162 (match_operand:SWI248 2 "nonimmediate_operand")
17163 (match_operand:SWI248 3 "nonimmediate_operand")))]
17164 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17165 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17166 && optimize_insn_for_speed_p ()"
17167 [(set (match_dup 4) (match_dup 5))
17169 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17171 if (MEM_P (operands[2]))
17173 operands[5] = operands[2];
17174 operands[2] = operands[4];
17176 else if (MEM_P (operands[3]))
17178 operands[5] = operands[3];
17179 operands[3] = operands[4];
17182 gcc_unreachable ();
17186 [(match_scratch:SI 4 "r")
17187 (set (match_operand:DI 0 "register_operand")
17188 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17189 [(reg FLAGS_REG) (const_int 0)])
17191 (match_operand:SI 2 "nonimmediate_operand"))
17193 (match_operand:SI 3 "nonimmediate_operand"))))]
17195 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17196 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17197 && optimize_insn_for_speed_p ()"
17198 [(set (match_dup 4) (match_dup 5))
17200 (if_then_else:DI (match_dup 1)
17201 (zero_extend:DI (match_dup 2))
17202 (zero_extend:DI (match_dup 3))))]
17204 if (MEM_P (operands[2]))
17206 operands[5] = operands[2];
17207 operands[2] = operands[4];
17209 else if (MEM_P (operands[3]))
17211 operands[5] = operands[3];
17212 operands[3] = operands[4];
17215 gcc_unreachable ();
17218 (define_expand "mov<mode>cc"
17219 [(set (match_operand:X87MODEF 0 "register_operand")
17220 (if_then_else:X87MODEF
17221 (match_operand 1 "comparison_operator")
17222 (match_operand:X87MODEF 2 "register_operand")
17223 (match_operand:X87MODEF 3 "register_operand")))]
17224 "(TARGET_80387 && TARGET_CMOVE)
17225 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17226 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
17228 (define_insn "*movxfcc_1"
17229 [(set (match_operand:XF 0 "register_operand" "=f,f")
17230 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17231 [(reg FLAGS_REG) (const_int 0)])
17232 (match_operand:XF 2 "register_operand" "f,0")
17233 (match_operand:XF 3 "register_operand" "0,f")))]
17234 "TARGET_80387 && TARGET_CMOVE"
17236 fcmov%F1\t{%2, %0|%0, %2}
17237 fcmov%f1\t{%3, %0|%0, %3}"
17238 [(set_attr "type" "fcmov")
17239 (set_attr "mode" "XF")])
17241 (define_insn "*movdfcc_1"
17242 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
17243 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17244 [(reg FLAGS_REG) (const_int 0)])
17245 (match_operand:DF 2 "nonimmediate_operand"
17247 (match_operand:DF 3 "nonimmediate_operand"
17248 "0 ,f,0 ,rm,0, rm")))]
17249 "TARGET_80387 && TARGET_CMOVE
17250 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17252 fcmov%F1\t{%2, %0|%0, %2}
17253 fcmov%f1\t{%3, %0|%0, %3}
17256 cmov%O2%C1\t{%2, %0|%0, %2}
17257 cmov%O2%c1\t{%3, %0|%0, %3}"
17258 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
17259 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
17260 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
17263 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
17264 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17265 [(reg FLAGS_REG) (const_int 0)])
17266 (match_operand:DF 2 "nonimmediate_operand")
17267 (match_operand:DF 3 "nonimmediate_operand")))]
17268 "!TARGET_64BIT && reload_completed"
17269 [(set (match_dup 2)
17270 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
17272 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
17274 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
17275 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
17278 (define_insn "*movsfcc_1_387"
17279 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
17280 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17281 [(reg FLAGS_REG) (const_int 0)])
17282 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
17283 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
17284 "TARGET_80387 && TARGET_CMOVE
17285 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17287 fcmov%F1\t{%2, %0|%0, %2}
17288 fcmov%f1\t{%3, %0|%0, %3}
17289 cmov%O2%C1\t{%2, %0|%0, %2}
17290 cmov%O2%c1\t{%3, %0|%0, %3}"
17291 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17292 (set_attr "mode" "SF,SF,SI,SI")])
17294 ;; Don't do conditional moves with memory inputs. This splitter helps
17295 ;; register starved x86_32 by forcing inputs into registers before reload.
17297 [(set (match_operand:MODEF 0 "register_operand")
17298 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
17299 [(reg FLAGS_REG) (const_int 0)])
17300 (match_operand:MODEF 2 "nonimmediate_operand")
17301 (match_operand:MODEF 3 "nonimmediate_operand")))]
17302 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17303 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17304 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17305 && can_create_pseudo_p ()
17306 && optimize_insn_for_speed_p ()"
17307 [(set (match_dup 0)
17308 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17310 if (MEM_P (operands[2]))
17311 operands[2] = force_reg (<MODE>mode, operands[2]);
17312 if (MEM_P (operands[3]))
17313 operands[3] = force_reg (<MODE>mode, operands[3]);
17316 ;; Don't do conditional moves with memory inputs
17318 [(match_scratch:MODEF 4 "r")
17319 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
17320 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
17321 [(reg FLAGS_REG) (const_int 0)])
17322 (match_operand:MODEF 2 "nonimmediate_operand")
17323 (match_operand:MODEF 3 "nonimmediate_operand")))]
17324 "(<MODE>mode != DFmode || TARGET_64BIT)
17325 && TARGET_80387 && TARGET_CMOVE
17326 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17327 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17328 && optimize_insn_for_speed_p ()"
17329 [(set (match_dup 4) (match_dup 5))
17331 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17333 if (MEM_P (operands[2]))
17335 operands[5] = operands[2];
17336 operands[2] = operands[4];
17338 else if (MEM_P (operands[3]))
17340 operands[5] = operands[3];
17341 operands[3] = operands[4];
17344 gcc_unreachable ();
17347 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
17348 ;; the scalar versions to have only XMM registers as operands.
17350 ;; XOP conditional move
17351 (define_insn "*xop_pcmov_<mode>"
17352 [(set (match_operand:MODEF 0 "register_operand" "=x")
17353 (if_then_else:MODEF
17354 (match_operand:MODEF 1 "register_operand" "x")
17355 (match_operand:MODEF 2 "register_operand" "x")
17356 (match_operand:MODEF 3 "register_operand" "x")))]
17358 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
17359 [(set_attr "type" "sse4arg")])
17361 ;; These versions of the min/max patterns are intentionally ignorant of
17362 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17363 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17364 ;; are undefined in this condition, we're certain this is correct.
17366 (define_insn "<code><mode>3"
17367 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17369 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
17370 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
17371 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17373 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
17374 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17375 [(set_attr "isa" "noavx,avx")
17376 (set_attr "prefix" "orig,vex")
17377 (set_attr "type" "sseadd")
17378 (set_attr "mode" "<MODE>")])
17380 ;; These versions of the min/max patterns implement exactly the operations
17381 ;; min = (op1 < op2 ? op1 : op2)
17382 ;; max = (!(op1 < op2) ? op1 : op2)
17383 ;; Their operands are not commutative, and thus they may be used in the
17384 ;; presence of -0.0 and NaN.
17386 (define_int_iterator IEEE_MAXMIN
17390 (define_int_attr ieee_maxmin
17391 [(UNSPEC_IEEE_MAX "max")
17392 (UNSPEC_IEEE_MIN "min")])
17394 (define_insn "*ieee_s<ieee_maxmin><mode>3"
17395 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17397 [(match_operand:MODEF 1 "register_operand" "0,v")
17398 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
17400 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17402 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
17403 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17404 [(set_attr "isa" "noavx,avx")
17405 (set_attr "prefix" "orig,maybe_evex")
17406 (set_attr "type" "sseadd")
17407 (set_attr "mode" "<MODE>")])
17409 ;; Make two stack loads independent:
17411 ;; fld %st(0) -> fld bb
17412 ;; fmul bb fmul %st(1), %st
17414 ;; Actually we only match the last two instructions for simplicity.
17416 [(set (match_operand 0 "fp_register_operand")
17417 (match_operand 1 "fp_register_operand"))
17419 (match_operator 2 "binary_fp_operator"
17421 (match_operand 3 "memory_operand")]))]
17422 "REGNO (operands[0]) != REGNO (operands[1])"
17423 [(set (match_dup 0) (match_dup 3))
17424 (set (match_dup 0) (match_dup 4))]
17426 ;; The % modifier is not operational anymore in peephole2's, so we have to
17427 ;; swap the operands manually in the case of addition and multiplication.
17431 if (COMMUTATIVE_ARITH_P (operands[2]))
17432 op0 = operands[0], op1 = operands[1];
17434 op0 = operands[1], op1 = operands[0];
17436 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
17437 GET_MODE (operands[2]),
17441 ;; Conditional addition patterns
17442 (define_expand "add<mode>cc"
17443 [(match_operand:SWI 0 "register_operand")
17444 (match_operand 1 "ordered_comparison_operator")
17445 (match_operand:SWI 2 "register_operand")
17446 (match_operand:SWI 3 "const_int_operand")]
17448 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17450 ;; Misc patterns (?)
17452 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17453 ;; Otherwise there will be nothing to keep
17455 ;; [(set (reg ebp) (reg esp))]
17456 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17457 ;; (clobber (eflags)]
17458 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17460 ;; in proper program order.
17462 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
17463 [(set (match_operand:P 0 "register_operand" "=r,r")
17464 (plus:P (match_operand:P 1 "register_operand" "0,r")
17465 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17466 (clobber (reg:CC FLAGS_REG))
17467 (clobber (mem:BLK (scratch)))]
17470 switch (get_attr_type (insn))
17473 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17476 gcc_assert (rtx_equal_p (operands[0], operands[1]));
17477 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17478 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17480 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17483 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17484 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17487 [(set (attr "type")
17488 (cond [(and (eq_attr "alternative" "0")
17489 (not (match_test "TARGET_OPT_AGU")))
17490 (const_string "alu")
17491 (match_operand:<MODE> 2 "const0_operand")
17492 (const_string "imov")
17494 (const_string "lea")))
17495 (set (attr "length_immediate")
17496 (cond [(eq_attr "type" "imov")
17498 (and (eq_attr "type" "alu")
17499 (match_operand 2 "const128_operand"))
17502 (const_string "*")))
17503 (set_attr "mode" "<MODE>")])
17505 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
17506 [(set (match_operand:P 0 "register_operand" "=r")
17507 (minus:P (match_operand:P 1 "register_operand" "0")
17508 (match_operand:P 2 "register_operand" "r")))
17509 (clobber (reg:CC FLAGS_REG))
17510 (clobber (mem:BLK (scratch)))]
17512 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17513 [(set_attr "type" "alu")
17514 (set_attr "mode" "<MODE>")])
17516 (define_insn "allocate_stack_worker_probe_<mode>"
17517 [(set (match_operand:P 0 "register_operand" "=a")
17518 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17519 UNSPECV_STACK_PROBE))
17520 (clobber (reg:CC FLAGS_REG))]
17521 "ix86_target_stack_probe ()"
17522 "call\t___chkstk_ms"
17523 [(set_attr "type" "multi")
17524 (set_attr "length" "5")])
17526 (define_expand "allocate_stack"
17527 [(match_operand 0 "register_operand")
17528 (match_operand 1 "general_operand")]
17529 "ix86_target_stack_probe ()"
17533 #ifndef CHECK_STACK_LIMIT
17534 #define CHECK_STACK_LIMIT 0
17537 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17538 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17542 rtx (*insn) (rtx, rtx);
17544 x = copy_to_mode_reg (Pmode, operands[1]);
17546 insn = (TARGET_64BIT
17547 ? gen_allocate_stack_worker_probe_di
17548 : gen_allocate_stack_worker_probe_si);
17550 emit_insn (insn (x, x));
17553 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17554 stack_pointer_rtx, 0, OPTAB_DIRECT);
17556 if (x != stack_pointer_rtx)
17557 emit_move_insn (stack_pointer_rtx, x);
17559 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17563 ;; Use IOR for stack probes, this is shorter.
17564 (define_expand "probe_stack"
17565 [(match_operand 0 "memory_operand")]
17568 rtx (*gen_ior3) (rtx, rtx, rtx);
17570 gen_ior3 = (GET_MODE (operands[0]) == DImode
17571 ? gen_iordi3 : gen_iorsi3);
17573 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
17577 (define_insn "adjust_stack_and_probe<mode>"
17578 [(set (match_operand:P 0 "register_operand" "=r")
17579 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17580 UNSPECV_PROBE_STACK_RANGE))
17581 (set (reg:P SP_REG)
17582 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17583 (clobber (reg:CC FLAGS_REG))
17584 (clobber (mem:BLK (scratch)))]
17586 "* return output_adjust_stack_and_probe (operands[0]);"
17587 [(set_attr "type" "multi")])
17589 (define_insn "probe_stack_range<mode>"
17590 [(set (match_operand:P 0 "register_operand" "=r")
17591 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17592 (match_operand:P 2 "const_int_operand" "n")]
17593 UNSPECV_PROBE_STACK_RANGE))
17594 (clobber (reg:CC FLAGS_REG))]
17596 "* return output_probe_stack_range (operands[0], operands[2]);"
17597 [(set_attr "type" "multi")])
17599 (define_expand "builtin_setjmp_receiver"
17600 [(label_ref (match_operand 0))]
17601 "!TARGET_64BIT && flag_pic"
17607 rtx_code_label *label_rtx = gen_label_rtx ();
17608 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17609 xops[0] = xops[1] = pic_offset_table_rtx;
17610 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17611 ix86_expand_binary_operator (MINUS, SImode, xops);
17615 emit_insn (gen_set_got (pic_offset_table_rtx));
17619 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17620 ;; Do not split instructions with mask registers.
17622 [(set (match_operand 0 "general_reg_operand")
17623 (match_operator 3 "promotable_binary_operator"
17624 [(match_operand 1 "general_reg_operand")
17625 (match_operand 2 "aligned_operand")]))
17626 (clobber (reg:CC FLAGS_REG))]
17627 "! TARGET_PARTIAL_REG_STALL && reload_completed
17628 && ((GET_MODE (operands[0]) == HImode
17629 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17630 /* ??? next two lines just !satisfies_constraint_K (...) */
17631 || !CONST_INT_P (operands[2])
17632 || satisfies_constraint_K (operands[2])))
17633 || (GET_MODE (operands[0]) == QImode
17634 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17635 [(parallel [(set (match_dup 0)
17636 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17637 (clobber (reg:CC FLAGS_REG))])]
17639 operands[0] = gen_lowpart (SImode, operands[0]);
17640 operands[1] = gen_lowpart (SImode, operands[1]);
17641 if (GET_CODE (operands[3]) != ASHIFT)
17642 operands[2] = gen_lowpart (SImode, operands[2]);
17643 operands[3] = shallow_copy_rtx (operands[3]);
17644 PUT_MODE (operands[3], SImode);
17647 ; Promote the QImode tests, as i386 has encoding of the AND
17648 ; instruction with 32-bit sign-extended immediate and thus the
17649 ; instruction size is unchanged, except in the %eax case for
17650 ; which it is increased by one byte, hence the ! optimize_size.
17652 [(set (match_operand 0 "flags_reg_operand")
17653 (match_operator 2 "compare_operator"
17654 [(and (match_operand 3 "aligned_operand")
17655 (match_operand 4 "const_int_operand"))
17657 (set (match_operand 1 "register_operand")
17658 (and (match_dup 3) (match_dup 4)))]
17659 "! TARGET_PARTIAL_REG_STALL && reload_completed
17660 && optimize_insn_for_speed_p ()
17661 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17662 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17663 /* Ensure that the operand will remain sign-extended immediate. */
17664 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17665 [(parallel [(set (match_dup 0)
17666 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17669 (and:SI (match_dup 3) (match_dup 4)))])]
17672 = gen_int_mode (INTVAL (operands[4])
17673 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17674 operands[1] = gen_lowpart (SImode, operands[1]);
17675 operands[3] = gen_lowpart (SImode, operands[3]);
17678 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17679 ; the TEST instruction with 32-bit sign-extended immediate and thus
17680 ; the instruction size would at least double, which is not what we
17681 ; want even with ! optimize_size.
17683 [(set (match_operand 0 "flags_reg_operand")
17684 (match_operator 1 "compare_operator"
17685 [(and (match_operand:HI 2 "aligned_operand")
17686 (match_operand:HI 3 "const_int_operand"))
17688 "! TARGET_PARTIAL_REG_STALL && reload_completed
17689 && ! TARGET_FAST_PREFIX
17690 && optimize_insn_for_speed_p ()
17691 /* Ensure that the operand will remain sign-extended immediate. */
17692 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17693 [(set (match_dup 0)
17694 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17698 = gen_int_mode (INTVAL (operands[3])
17699 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17700 operands[2] = gen_lowpart (SImode, operands[2]);
17704 [(set (match_operand 0 "register_operand")
17705 (neg (match_operand 1 "register_operand")))
17706 (clobber (reg:CC FLAGS_REG))]
17707 "! TARGET_PARTIAL_REG_STALL && reload_completed
17708 && (GET_MODE (operands[0]) == HImode
17709 || (GET_MODE (operands[0]) == QImode
17710 && (TARGET_PROMOTE_QImode
17711 || optimize_insn_for_size_p ())))"
17712 [(parallel [(set (match_dup 0)
17713 (neg:SI (match_dup 1)))
17714 (clobber (reg:CC FLAGS_REG))])]
17716 operands[0] = gen_lowpart (SImode, operands[0]);
17717 operands[1] = gen_lowpart (SImode, operands[1]);
17720 ;; Do not split instructions with mask regs.
17722 [(set (match_operand 0 "general_reg_operand")
17723 (not (match_operand 1 "general_reg_operand")))]
17724 "! TARGET_PARTIAL_REG_STALL && reload_completed
17725 && (GET_MODE (operands[0]) == HImode
17726 || (GET_MODE (operands[0]) == QImode
17727 && (TARGET_PROMOTE_QImode
17728 || optimize_insn_for_size_p ())))"
17729 [(set (match_dup 0)
17730 (not:SI (match_dup 1)))]
17732 operands[0] = gen_lowpart (SImode, operands[0]);
17733 operands[1] = gen_lowpart (SImode, operands[1]);
17736 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17737 ;; transform a complex memory operation into two memory to register operations.
17739 ;; Don't push memory operands
17741 [(set (match_operand:SWI 0 "push_operand")
17742 (match_operand:SWI 1 "memory_operand"))
17743 (match_scratch:SWI 2 "<r>")]
17744 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17745 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17746 [(set (match_dup 2) (match_dup 1))
17747 (set (match_dup 0) (match_dup 2))])
17749 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17752 [(set (match_operand:SF 0 "push_operand")
17753 (match_operand:SF 1 "memory_operand"))
17754 (match_scratch:SF 2 "r")]
17755 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17756 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17757 [(set (match_dup 2) (match_dup 1))
17758 (set (match_dup 0) (match_dup 2))])
17760 ;; Don't move an immediate directly to memory when the instruction
17761 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17763 [(match_scratch:SWI124 1 "<r>")
17764 (set (match_operand:SWI124 0 "memory_operand")
17766 "optimize_insn_for_speed_p ()
17767 && ((<MODE>mode == HImode
17768 && TARGET_LCP_STALL)
17769 || (!TARGET_USE_MOV0
17770 && TARGET_SPLIT_LONG_MOVES
17771 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17772 && peep2_regno_dead_p (0, FLAGS_REG)"
17773 [(parallel [(set (match_dup 2) (const_int 0))
17774 (clobber (reg:CC FLAGS_REG))])
17775 (set (match_dup 0) (match_dup 1))]
17776 "operands[2] = gen_lowpart (SImode, operands[1]);")
17779 [(match_scratch:SWI124 2 "<r>")
17780 (set (match_operand:SWI124 0 "memory_operand")
17781 (match_operand:SWI124 1 "immediate_operand"))]
17782 "optimize_insn_for_speed_p ()
17783 && ((<MODE>mode == HImode
17784 && TARGET_LCP_STALL)
17785 || (TARGET_SPLIT_LONG_MOVES
17786 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17787 [(set (match_dup 2) (match_dup 1))
17788 (set (match_dup 0) (match_dup 2))])
17790 ;; Don't compare memory with zero, load and use a test instead.
17792 [(set (match_operand 0 "flags_reg_operand")
17793 (match_operator 1 "compare_operator"
17794 [(match_operand:SI 2 "memory_operand")
17796 (match_scratch:SI 3 "r")]
17797 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17798 [(set (match_dup 3) (match_dup 2))
17799 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17801 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17802 ;; Don't split NOTs with a displacement operand, because resulting XOR
17803 ;; will not be pairable anyway.
17805 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17806 ;; represented using a modRM byte. The XOR replacement is long decoded,
17807 ;; so this split helps here as well.
17809 ;; Note: Can't do this as a regular split because we can't get proper
17810 ;; lifetime information then.
17813 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
17814 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
17815 "optimize_insn_for_speed_p ()
17816 && ((TARGET_NOT_UNPAIRABLE
17817 && (!MEM_P (operands[0])
17818 || !memory_displacement_operand (operands[0], <MODE>mode)))
17819 || (TARGET_NOT_VECTORMODE
17820 && long_memory_operand (operands[0], <MODE>mode)))
17821 && peep2_regno_dead_p (0, FLAGS_REG)"
17822 [(parallel [(set (match_dup 0)
17823 (xor:SWI124 (match_dup 1) (const_int -1)))
17824 (clobber (reg:CC FLAGS_REG))])])
17826 ;; Non pairable "test imm, reg" instructions can be translated to
17827 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17828 ;; byte opcode instead of two, have a short form for byte operands),
17829 ;; so do it for other CPUs as well. Given that the value was dead,
17830 ;; this should not create any new dependencies. Pass on the sub-word
17831 ;; versions if we're concerned about partial register stalls.
17834 [(set (match_operand 0 "flags_reg_operand")
17835 (match_operator 1 "compare_operator"
17836 [(and:SI (match_operand:SI 2 "register_operand")
17837 (match_operand:SI 3 "immediate_operand"))
17839 "ix86_match_ccmode (insn, CCNOmode)
17840 && (true_regnum (operands[2]) != AX_REG
17841 || satisfies_constraint_K (operands[3]))
17842 && peep2_reg_dead_p (1, operands[2])"
17844 [(set (match_dup 0)
17845 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17848 (and:SI (match_dup 2) (match_dup 3)))])])
17850 ;; We don't need to handle HImode case, because it will be promoted to SImode
17851 ;; on ! TARGET_PARTIAL_REG_STALL
17854 [(set (match_operand 0 "flags_reg_operand")
17855 (match_operator 1 "compare_operator"
17856 [(and:QI (match_operand:QI 2 "register_operand")
17857 (match_operand:QI 3 "immediate_operand"))
17859 "! TARGET_PARTIAL_REG_STALL
17860 && ix86_match_ccmode (insn, CCNOmode)
17861 && true_regnum (operands[2]) != AX_REG
17862 && peep2_reg_dead_p (1, operands[2])"
17864 [(set (match_dup 0)
17865 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17868 (and:QI (match_dup 2) (match_dup 3)))])])
17871 [(set (match_operand 0 "flags_reg_operand")
17872 (match_operator 1 "compare_operator"
17875 (match_operand 2 "QIreg_operand")
17878 (match_operand 3 "const_int_operand"))
17880 "! TARGET_PARTIAL_REG_STALL
17881 && ix86_match_ccmode (insn, CCNOmode)
17882 && true_regnum (operands[2]) != AX_REG
17883 && peep2_reg_dead_p (1, operands[2])"
17884 [(parallel [(set (match_dup 0)
17893 (set (zero_extract:SI (match_dup 2)
17901 (match_dup 3)))])])
17903 ;; Don't do logical operations with memory inputs.
17905 [(match_scratch:SI 2 "r")
17906 (parallel [(set (match_operand:SI 0 "register_operand")
17907 (match_operator:SI 3 "arith_or_logical_operator"
17909 (match_operand:SI 1 "memory_operand")]))
17910 (clobber (reg:CC FLAGS_REG))])]
17911 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17912 [(set (match_dup 2) (match_dup 1))
17913 (parallel [(set (match_dup 0)
17914 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17915 (clobber (reg:CC FLAGS_REG))])])
17918 [(match_scratch:SI 2 "r")
17919 (parallel [(set (match_operand:SI 0 "register_operand")
17920 (match_operator:SI 3 "arith_or_logical_operator"
17921 [(match_operand:SI 1 "memory_operand")
17923 (clobber (reg:CC FLAGS_REG))])]
17924 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17925 [(set (match_dup 2) (match_dup 1))
17926 (parallel [(set (match_dup 0)
17927 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17928 (clobber (reg:CC FLAGS_REG))])])
17930 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17931 ;; refers to the destination of the load!
17934 [(set (match_operand:SI 0 "register_operand")
17935 (match_operand:SI 1 "register_operand"))
17936 (parallel [(set (match_dup 0)
17937 (match_operator:SI 3 "commutative_operator"
17939 (match_operand:SI 2 "memory_operand")]))
17940 (clobber (reg:CC FLAGS_REG))])]
17941 "REGNO (operands[0]) != REGNO (operands[1])
17942 && GENERAL_REGNO_P (REGNO (operands[0]))
17943 && GENERAL_REGNO_P (REGNO (operands[1]))"
17944 [(set (match_dup 0) (match_dup 4))
17945 (parallel [(set (match_dup 0)
17946 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17947 (clobber (reg:CC FLAGS_REG))])]
17948 "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
17951 [(set (match_operand 0 "register_operand")
17952 (match_operand 1 "register_operand"))
17954 (match_operator 3 "commutative_operator"
17956 (match_operand 2 "memory_operand")]))]
17957 "REGNO (operands[0]) != REGNO (operands[1])
17958 && ((MMX_REGNO_P (REGNO (operands[0]))
17959 && MMX_REGNO_P (REGNO (operands[1])))
17960 || (SSE_REGNO_P (REGNO (operands[0]))
17961 && SSE_REGNO_P (REGNO (operands[1]))))"
17962 [(set (match_dup 0) (match_dup 2))
17964 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17966 ; Don't do logical operations with memory outputs
17968 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17969 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17970 ; the same decoder scheduling characteristics as the original.
17973 [(match_scratch:SI 2 "r")
17974 (parallel [(set (match_operand:SI 0 "memory_operand")
17975 (match_operator:SI 3 "arith_or_logical_operator"
17977 (match_operand:SI 1 "nonmemory_operand")]))
17978 (clobber (reg:CC FLAGS_REG))])]
17979 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17980 /* Do not split stack checking probes. */
17981 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17982 [(set (match_dup 2) (match_dup 0))
17983 (parallel [(set (match_dup 2)
17984 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17985 (clobber (reg:CC FLAGS_REG))])
17986 (set (match_dup 0) (match_dup 2))])
17989 [(match_scratch:SI 2 "r")
17990 (parallel [(set (match_operand:SI 0 "memory_operand")
17991 (match_operator:SI 3 "arith_or_logical_operator"
17992 [(match_operand:SI 1 "nonmemory_operand")
17994 (clobber (reg:CC FLAGS_REG))])]
17995 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17996 /* Do not split stack checking probes. */
17997 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17998 [(set (match_dup 2) (match_dup 0))
17999 (parallel [(set (match_dup 2)
18000 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18001 (clobber (reg:CC FLAGS_REG))])
18002 (set (match_dup 0) (match_dup 2))])
18004 ;; Attempt to use arith or logical operations with memory outputs with
18005 ;; setting of flags.
18007 [(set (match_operand:SWI 0 "register_operand")
18008 (match_operand:SWI 1 "memory_operand"))
18009 (parallel [(set (match_dup 0)
18010 (match_operator:SWI 3 "plusminuslogic_operator"
18012 (match_operand:SWI 2 "<nonmemory_operand>")]))
18013 (clobber (reg:CC FLAGS_REG))])
18014 (set (match_dup 1) (match_dup 0))
18015 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18016 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18017 && peep2_reg_dead_p (4, operands[0])
18018 && !reg_overlap_mentioned_p (operands[0], operands[1])
18019 && !reg_overlap_mentioned_p (operands[0], operands[2])
18020 && (<MODE>mode != QImode
18021 || immediate_operand (operands[2], QImode)
18022 || any_QIreg_operand (operands[2], QImode))
18023 && ix86_match_ccmode (peep2_next_insn (3),
18024 (GET_CODE (operands[3]) == PLUS
18025 || GET_CODE (operands[3]) == MINUS)
18026 ? CCGOCmode : CCNOmode)"
18027 [(parallel [(set (match_dup 4) (match_dup 5))
18028 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
18029 (match_dup 2)]))])]
18031 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18032 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18033 copy_rtx (operands[1]),
18034 copy_rtx (operands[2]));
18035 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
18036 operands[5], const0_rtx);
18040 [(parallel [(set (match_operand:SWI 0 "register_operand")
18041 (match_operator:SWI 2 "plusminuslogic_operator"
18043 (match_operand:SWI 1 "memory_operand")]))
18044 (clobber (reg:CC FLAGS_REG))])
18045 (set (match_dup 1) (match_dup 0))
18046 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18047 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18048 && GET_CODE (operands[2]) != MINUS
18049 && peep2_reg_dead_p (3, operands[0])
18050 && !reg_overlap_mentioned_p (operands[0], operands[1])
18051 && ix86_match_ccmode (peep2_next_insn (2),
18052 GET_CODE (operands[2]) == PLUS
18053 ? CCGOCmode : CCNOmode)"
18054 [(parallel [(set (match_dup 3) (match_dup 4))
18055 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
18056 (match_dup 0)]))])]
18058 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
18059 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
18060 copy_rtx (operands[1]),
18061 copy_rtx (operands[0]));
18062 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
18063 operands[4], const0_rtx);
18067 [(set (match_operand:SWI12 0 "register_operand")
18068 (match_operand:SWI12 1 "memory_operand"))
18069 (parallel [(set (match_operand:SI 4 "register_operand")
18070 (match_operator:SI 3 "plusminuslogic_operator"
18072 (match_operand:SI 2 "nonmemory_operand")]))
18073 (clobber (reg:CC FLAGS_REG))])
18074 (set (match_dup 1) (match_dup 0))
18075 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18076 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18077 && REG_P (operands[0]) && REG_P (operands[4])
18078 && REGNO (operands[0]) == REGNO (operands[4])
18079 && peep2_reg_dead_p (4, operands[0])
18080 && (<MODE>mode != QImode
18081 || immediate_operand (operands[2], SImode)
18082 || any_QIreg_operand (operands[2], SImode))
18083 && !reg_overlap_mentioned_p (operands[0], operands[1])
18084 && !reg_overlap_mentioned_p (operands[0], operands[2])
18085 && ix86_match_ccmode (peep2_next_insn (3),
18086 (GET_CODE (operands[3]) == PLUS
18087 || GET_CODE (operands[3]) == MINUS)
18088 ? CCGOCmode : CCNOmode)"
18089 [(parallel [(set (match_dup 4) (match_dup 5))
18090 (set (match_dup 1) (match_dup 6))])]
18092 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
18093 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18094 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18095 copy_rtx (operands[1]), operands[2]);
18096 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
18097 operands[5], const0_rtx);
18098 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18099 copy_rtx (operands[1]),
18100 copy_rtx (operands[2]));
18103 ;; Attempt to always use XOR for zeroing registers.
18105 [(set (match_operand 0 "register_operand")
18106 (match_operand 1 "const0_operand"))]
18107 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18108 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18109 && GENERAL_REGNO_P (REGNO (operands[0]))
18110 && peep2_regno_dead_p (0, FLAGS_REG)"
18111 [(parallel [(set (match_dup 0) (const_int 0))
18112 (clobber (reg:CC FLAGS_REG))])]
18113 "operands[0] = gen_lowpart (word_mode, operands[0]);")
18116 [(set (strict_low_part (match_operand 0 "register_operand"))
18118 "(GET_MODE (operands[0]) == QImode
18119 || GET_MODE (operands[0]) == HImode)
18120 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18121 && peep2_regno_dead_p (0, FLAGS_REG)"
18122 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18123 (clobber (reg:CC FLAGS_REG))])])
18125 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
18127 [(set (match_operand:SWI248 0 "register_operand")
18129 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
18130 && GENERAL_REGNO_P (REGNO (operands[0]))
18131 && peep2_regno_dead_p (0, FLAGS_REG)"
18132 [(parallel [(set (match_dup 0) (const_int -1))
18133 (clobber (reg:CC FLAGS_REG))])]
18135 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
18136 operands[0] = gen_lowpart (SImode, operands[0]);
18139 ;; Attempt to convert simple lea to add/shift.
18140 ;; These can be created by move expanders.
18141 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
18142 ;; relevant lea instructions were already split.
18145 [(set (match_operand:SWI48 0 "register_operand")
18146 (plus:SWI48 (match_dup 0)
18147 (match_operand:SWI48 1 "<nonmemory_operand>")))]
18149 && peep2_regno_dead_p (0, FLAGS_REG)"
18150 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18151 (clobber (reg:CC FLAGS_REG))])])
18154 [(set (match_operand:SWI48 0 "register_operand")
18155 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
18158 && peep2_regno_dead_p (0, FLAGS_REG)"
18159 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18160 (clobber (reg:CC FLAGS_REG))])])
18163 [(set (match_operand:DI 0 "register_operand")
18165 (plus:SI (match_operand:SI 1 "register_operand")
18166 (match_operand:SI 2 "nonmemory_operand"))))]
18167 "TARGET_64BIT && !TARGET_OPT_AGU
18168 && REGNO (operands[0]) == REGNO (operands[1])
18169 && peep2_regno_dead_p (0, FLAGS_REG)"
18170 [(parallel [(set (match_dup 0)
18171 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
18172 (clobber (reg:CC FLAGS_REG))])])
18175 [(set (match_operand:DI 0 "register_operand")
18177 (plus:SI (match_operand:SI 1 "nonmemory_operand")
18178 (match_operand:SI 2 "register_operand"))))]
18179 "TARGET_64BIT && !TARGET_OPT_AGU
18180 && REGNO (operands[0]) == REGNO (operands[2])
18181 && peep2_regno_dead_p (0, FLAGS_REG)"
18182 [(parallel [(set (match_dup 0)
18183 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
18184 (clobber (reg:CC FLAGS_REG))])])
18187 [(set (match_operand:SWI48 0 "register_operand")
18188 (mult:SWI48 (match_dup 0)
18189 (match_operand:SWI48 1 "const_int_operand")))]
18190 "exact_log2 (INTVAL (operands[1])) >= 0
18191 && peep2_regno_dead_p (0, FLAGS_REG)"
18192 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
18193 (clobber (reg:CC FLAGS_REG))])]
18194 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18197 [(set (match_operand:DI 0 "register_operand")
18199 (mult:SI (match_operand:SI 1 "register_operand")
18200 (match_operand:SI 2 "const_int_operand"))))]
18202 && exact_log2 (INTVAL (operands[2])) >= 0
18203 && REGNO (operands[0]) == REGNO (operands[1])
18204 && peep2_regno_dead_p (0, FLAGS_REG)"
18205 [(parallel [(set (match_dup 0)
18206 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
18207 (clobber (reg:CC FLAGS_REG))])]
18208 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18210 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18211 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
18212 ;; On many CPUs it is also faster, since special hardware to avoid esp
18213 ;; dependencies is present.
18215 ;; While some of these conversions may be done using splitters, we use
18216 ;; peepholes in order to allow combine_stack_adjustments pass to see
18217 ;; nonobfuscated RTL.
18219 ;; Convert prologue esp subtractions to push.
18220 ;; We need register to push. In order to keep verify_flow_info happy we have
18222 ;; - use scratch and clobber it in order to avoid dependencies
18223 ;; - use already live register
18224 ;; We can't use the second way right now, since there is no reliable way how to
18225 ;; verify that given register is live. First choice will also most likely in
18226 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18227 ;; call clobbered registers are dead. We may want to use base pointer as an
18228 ;; alternative when no register is available later.
18231 [(match_scratch:W 1 "r")
18232 (parallel [(set (reg:P SP_REG)
18233 (plus:P (reg:P SP_REG)
18234 (match_operand:P 0 "const_int_operand")))
18235 (clobber (reg:CC FLAGS_REG))
18236 (clobber (mem:BLK (scratch)))])]
18237 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18238 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
18239 && !ix86_using_red_zone ()"
18240 [(clobber (match_dup 1))
18241 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18242 (clobber (mem:BLK (scratch)))])])
18245 [(match_scratch:W 1 "r")
18246 (parallel [(set (reg:P SP_REG)
18247 (plus:P (reg:P SP_REG)
18248 (match_operand:P 0 "const_int_operand")))
18249 (clobber (reg:CC FLAGS_REG))
18250 (clobber (mem:BLK (scratch)))])]
18251 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
18252 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
18253 && !ix86_using_red_zone ()"
18254 [(clobber (match_dup 1))
18255 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18256 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18257 (clobber (mem:BLK (scratch)))])])
18259 ;; Convert esp subtractions to push.
18261 [(match_scratch:W 1 "r")
18262 (parallel [(set (reg:P SP_REG)
18263 (plus:P (reg:P SP_REG)
18264 (match_operand:P 0 "const_int_operand")))
18265 (clobber (reg:CC FLAGS_REG))])]
18266 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18267 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
18268 && !ix86_using_red_zone ()"
18269 [(clobber (match_dup 1))
18270 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
18273 [(match_scratch:W 1 "r")
18274 (parallel [(set (reg:P SP_REG)
18275 (plus:P (reg:P SP_REG)
18276 (match_operand:P 0 "const_int_operand")))
18277 (clobber (reg:CC FLAGS_REG))])]
18278 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
18279 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
18280 && !ix86_using_red_zone ()"
18281 [(clobber (match_dup 1))
18282 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18283 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
18285 ;; Convert epilogue deallocator to pop.
18287 [(match_scratch:W 1 "r")
18288 (parallel [(set (reg:P SP_REG)
18289 (plus:P (reg:P SP_REG)
18290 (match_operand:P 0 "const_int_operand")))
18291 (clobber (reg:CC FLAGS_REG))
18292 (clobber (mem:BLK (scratch)))])]
18293 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
18294 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
18295 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18296 (clobber (mem:BLK (scratch)))])])
18298 ;; Two pops case is tricky, since pop causes dependency
18299 ;; on destination register. We use two registers if available.
18301 [(match_scratch:W 1 "r")
18302 (match_scratch:W 2 "r")
18303 (parallel [(set (reg:P SP_REG)
18304 (plus:P (reg:P SP_REG)
18305 (match_operand:P 0 "const_int_operand")))
18306 (clobber (reg:CC FLAGS_REG))
18307 (clobber (mem:BLK (scratch)))])]
18308 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
18309 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18310 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18311 (clobber (mem:BLK (scratch)))])
18312 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
18315 [(match_scratch:W 1 "r")
18316 (parallel [(set (reg:P SP_REG)
18317 (plus:P (reg:P SP_REG)
18318 (match_operand:P 0 "const_int_operand")))
18319 (clobber (reg:CC FLAGS_REG))
18320 (clobber (mem:BLK (scratch)))])]
18321 "optimize_insn_for_size_p ()
18322 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18323 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18324 (clobber (mem:BLK (scratch)))])
18325 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18327 ;; Convert esp additions to pop.
18329 [(match_scratch:W 1 "r")
18330 (parallel [(set (reg:P SP_REG)
18331 (plus:P (reg:P SP_REG)
18332 (match_operand:P 0 "const_int_operand")))
18333 (clobber (reg:CC FLAGS_REG))])]
18334 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
18335 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18337 ;; Two pops case is tricky, since pop causes dependency
18338 ;; on destination register. We use two registers if available.
18340 [(match_scratch:W 1 "r")
18341 (match_scratch:W 2 "r")
18342 (parallel [(set (reg:P SP_REG)
18343 (plus:P (reg:P SP_REG)
18344 (match_operand:P 0 "const_int_operand")))
18345 (clobber (reg:CC FLAGS_REG))])]
18346 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18347 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18348 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
18351 [(match_scratch:W 1 "r")
18352 (parallel [(set (reg:P SP_REG)
18353 (plus:P (reg:P SP_REG)
18354 (match_operand:P 0 "const_int_operand")))
18355 (clobber (reg:CC FLAGS_REG))])]
18356 "optimize_insn_for_size_p ()
18357 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18358 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18359 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18361 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18362 ;; required and register dies. Similarly for 128 to -128.
18364 [(set (match_operand 0 "flags_reg_operand")
18365 (match_operator 1 "compare_operator"
18366 [(match_operand 2 "register_operand")
18367 (match_operand 3 "const_int_operand")]))]
18368 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
18369 && incdec_operand (operands[3], GET_MODE (operands[3])))
18370 || (!TARGET_FUSE_CMP_AND_BRANCH
18371 && INTVAL (operands[3]) == 128))
18372 && ix86_match_ccmode (insn, CCGCmode)
18373 && peep2_reg_dead_p (1, operands[2])"
18374 [(parallel [(set (match_dup 0)
18375 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18376 (clobber (match_dup 2))])])
18378 ;; Convert imul by three, five and nine into lea
18381 [(set (match_operand:SWI48 0 "register_operand")
18382 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
18383 (match_operand:SWI48 2 "const359_operand")))
18384 (clobber (reg:CC FLAGS_REG))])]
18385 "!TARGET_PARTIAL_REG_STALL
18386 || <MODE>mode == SImode
18387 || optimize_function_for_size_p (cfun)"
18388 [(set (match_dup 0)
18389 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
18391 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18395 [(set (match_operand:SWI48 0 "register_operand")
18396 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
18397 (match_operand:SWI48 2 "const359_operand")))
18398 (clobber (reg:CC FLAGS_REG))])]
18399 "optimize_insn_for_speed_p ()
18400 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
18401 [(set (match_dup 0) (match_dup 1))
18403 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
18405 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18407 ;; imul $32bit_imm, mem, reg is vector decoded, while
18408 ;; imul $32bit_imm, reg, reg is direct decoded.
18410 [(match_scratch:SWI48 3 "r")
18411 (parallel [(set (match_operand:SWI48 0 "register_operand")
18412 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
18413 (match_operand:SWI48 2 "immediate_operand")))
18414 (clobber (reg:CC FLAGS_REG))])]
18415 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18416 && !satisfies_constraint_K (operands[2])"
18417 [(set (match_dup 3) (match_dup 1))
18418 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
18419 (clobber (reg:CC FLAGS_REG))])])
18422 [(match_scratch:SI 3 "r")
18423 (parallel [(set (match_operand:DI 0 "register_operand")
18425 (mult:SI (match_operand:SI 1 "memory_operand")
18426 (match_operand:SI 2 "immediate_operand"))))
18427 (clobber (reg:CC FLAGS_REG))])]
18429 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18430 && !satisfies_constraint_K (operands[2])"
18431 [(set (match_dup 3) (match_dup 1))
18432 (parallel [(set (match_dup 0)
18433 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18434 (clobber (reg:CC FLAGS_REG))])])
18436 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18437 ;; Convert it into imul reg, reg
18438 ;; It would be better to force assembler to encode instruction using long
18439 ;; immediate, but there is apparently no way to do so.
18441 [(parallel [(set (match_operand:SWI248 0 "register_operand")
18443 (match_operand:SWI248 1 "nonimmediate_operand")
18444 (match_operand:SWI248 2 "const_int_operand")))
18445 (clobber (reg:CC FLAGS_REG))])
18446 (match_scratch:SWI248 3 "r")]
18447 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18448 && satisfies_constraint_K (operands[2])"
18449 [(set (match_dup 3) (match_dup 2))
18450 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
18451 (clobber (reg:CC FLAGS_REG))])]
18453 if (!rtx_equal_p (operands[0], operands[1]))
18454 emit_move_insn (operands[0], operands[1]);
18457 ;; After splitting up read-modify operations, array accesses with memory
18458 ;; operands might end up in form:
18460 ;; movl 4(%esp), %edx
18462 ;; instead of pre-splitting:
18464 ;; addl 4(%esp), %eax
18466 ;; movl 4(%esp), %edx
18467 ;; leal (%edx,%eax,4), %eax
18470 [(match_scratch:W 5 "r")
18471 (parallel [(set (match_operand 0 "register_operand")
18472 (ashift (match_operand 1 "register_operand")
18473 (match_operand 2 "const_int_operand")))
18474 (clobber (reg:CC FLAGS_REG))])
18475 (parallel [(set (match_operand 3 "register_operand")
18476 (plus (match_dup 0)
18477 (match_operand 4 "x86_64_general_operand")))
18478 (clobber (reg:CC FLAGS_REG))])]
18479 "IN_RANGE (INTVAL (operands[2]), 1, 3)
18480 /* Validate MODE for lea. */
18481 && ((!TARGET_PARTIAL_REG_STALL
18482 && (GET_MODE (operands[0]) == QImode
18483 || GET_MODE (operands[0]) == HImode))
18484 || GET_MODE (operands[0]) == SImode
18485 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18486 && (rtx_equal_p (operands[0], operands[3])
18487 || peep2_reg_dead_p (2, operands[0]))
18488 /* We reorder load and the shift. */
18489 && !reg_overlap_mentioned_p (operands[0], operands[4])"
18490 [(set (match_dup 5) (match_dup 4))
18491 (set (match_dup 0) (match_dup 1))]
18493 machine_mode op1mode = GET_MODE (operands[1]);
18494 machine_mode mode = op1mode == DImode ? DImode : SImode;
18495 int scale = 1 << INTVAL (operands[2]);
18496 rtx index = gen_lowpart (word_mode, operands[1]);
18497 rtx base = gen_lowpart (word_mode, operands[5]);
18498 rtx dest = gen_lowpart (mode, operands[3]);
18500 operands[1] = gen_rtx_PLUS (word_mode, base,
18501 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
18502 if (mode != word_mode)
18503 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18505 operands[5] = base;
18506 if (op1mode != word_mode)
18507 operands[5] = gen_lowpart (op1mode, operands[5]);
18509 operands[0] = dest;
18512 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18513 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18514 ;; caught for use by garbage collectors and the like. Using an insn that
18515 ;; maps to SIGILL makes it more likely the program will rightfully die.
18516 ;; Keeping with tradition, "6" is in honor of #UD.
18517 (define_insn "trap"
18518 [(trap_if (const_int 1) (const_int 6))]
18521 #ifdef HAVE_AS_IX86_UD2
18524 return ASM_SHORT "0x0b0f";
18527 [(set_attr "length" "2")])
18529 (define_expand "prefetch"
18530 [(prefetch (match_operand 0 "address_operand")
18531 (match_operand:SI 1 "const_int_operand")
18532 (match_operand:SI 2 "const_int_operand"))]
18533 "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18535 bool write = INTVAL (operands[1]) != 0;
18536 int locality = INTVAL (operands[2]);
18538 gcc_assert (IN_RANGE (locality, 0, 3));
18540 /* Use 3dNOW prefetch in case we are asking for write prefetch not
18541 supported by SSE counterpart or the SSE prefetch is not available
18542 (K6 machines). Otherwise use SSE prefetch as it allows specifying
18544 if (TARGET_PREFETCHWT1 && write && locality <= 2)
18545 operands[2] = const2_rtx;
18546 else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
18547 operands[2] = GEN_INT (3);
18549 operands[1] = const0_rtx;
18552 (define_insn "*prefetch_sse"
18553 [(prefetch (match_operand 0 "address_operand" "p")
18555 (match_operand:SI 1 "const_int_operand"))]
18556 "TARGET_PREFETCH_SSE"
18558 static const char * const patterns[4] = {
18559 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18562 int locality = INTVAL (operands[1]);
18563 gcc_assert (IN_RANGE (locality, 0, 3));
18565 return patterns[locality];
18567 [(set_attr "type" "sse")
18568 (set_attr "atom_sse_attr" "prefetch")
18569 (set (attr "length_address")
18570 (symbol_ref "memory_address_length (operands[0], false)"))
18571 (set_attr "memory" "none")])
18573 (define_insn "*prefetch_3dnow"
18574 [(prefetch (match_operand 0 "address_operand" "p")
18575 (match_operand:SI 1 "const_int_operand" "n")
18579 if (INTVAL (operands[1]) == 0)
18580 return "prefetch\t%a0";
18582 return "prefetchw\t%a0";
18584 [(set_attr "type" "mmx")
18585 (set (attr "length_address")
18586 (symbol_ref "memory_address_length (operands[0], false)"))
18587 (set_attr "memory" "none")])
18589 (define_insn "*prefetch_prefetchwt1"
18590 [(prefetch (match_operand 0 "address_operand" "p")
18593 "TARGET_PREFETCHWT1"
18594 "prefetchwt1\t%a0";
18595 [(set_attr "type" "sse")
18596 (set (attr "length_address")
18597 (symbol_ref "memory_address_length (operands[0], false)"))
18598 (set_attr "memory" "none")])
18600 (define_expand "stack_protect_set"
18601 [(match_operand 0 "memory_operand")
18602 (match_operand 1 "memory_operand")]
18603 "TARGET_SSP_TLS_GUARD"
18605 rtx (*insn)(rtx, rtx);
18607 #ifdef TARGET_THREAD_SSP_OFFSET
18608 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18609 insn = (TARGET_LP64
18610 ? gen_stack_tls_protect_set_di
18611 : gen_stack_tls_protect_set_si);
18613 insn = (TARGET_LP64
18614 ? gen_stack_protect_set_di
18615 : gen_stack_protect_set_si);
18618 emit_insn (insn (operands[0], operands[1]));
18622 (define_insn "stack_protect_set_<mode>"
18623 [(set (match_operand:PTR 0 "memory_operand" "=m")
18624 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18626 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18627 (clobber (reg:CC FLAGS_REG))]
18628 "TARGET_SSP_TLS_GUARD"
18629 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18630 [(set_attr "type" "multi")])
18632 (define_insn "stack_tls_protect_set_<mode>"
18633 [(set (match_operand:PTR 0 "memory_operand" "=m")
18634 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
18635 UNSPEC_SP_TLS_SET))
18636 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18637 (clobber (reg:CC FLAGS_REG))]
18639 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18640 [(set_attr "type" "multi")])
18642 (define_expand "stack_protect_test"
18643 [(match_operand 0 "memory_operand")
18644 (match_operand 1 "memory_operand")
18646 "TARGET_SSP_TLS_GUARD"
18648 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18650 rtx (*insn)(rtx, rtx, rtx);
18652 #ifdef TARGET_THREAD_SSP_OFFSET
18653 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18654 insn = (TARGET_LP64
18655 ? gen_stack_tls_protect_test_di
18656 : gen_stack_tls_protect_test_si);
18658 insn = (TARGET_LP64
18659 ? gen_stack_protect_test_di
18660 : gen_stack_protect_test_si);
18663 emit_insn (insn (flags, operands[0], operands[1]));
18665 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18666 flags, const0_rtx, operands[2]));
18670 (define_insn "stack_protect_test_<mode>"
18671 [(set (match_operand:CCZ 0 "flags_reg_operand")
18672 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18673 (match_operand:PTR 2 "memory_operand" "m")]
18675 (clobber (match_scratch:PTR 3 "=&r"))]
18676 "TARGET_SSP_TLS_GUARD"
18677 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18678 [(set_attr "type" "multi")])
18680 (define_insn "stack_tls_protect_test_<mode>"
18681 [(set (match_operand:CCZ 0 "flags_reg_operand")
18682 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18683 (match_operand:PTR 2 "const_int_operand" "i")]
18684 UNSPEC_SP_TLS_TEST))
18685 (clobber (match_scratch:PTR 3 "=r"))]
18687 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18688 [(set_attr "type" "multi")])
18690 (define_insn "sse4_2_crc32<mode>"
18691 [(set (match_operand:SI 0 "register_operand" "=r")
18693 [(match_operand:SI 1 "register_operand" "0")
18694 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18696 "TARGET_SSE4_2 || TARGET_CRC32"
18697 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18698 [(set_attr "type" "sselog1")
18699 (set_attr "prefix_rep" "1")
18700 (set_attr "prefix_extra" "1")
18701 (set (attr "prefix_data16")
18702 (if_then_else (match_operand:HI 2)
18704 (const_string "*")))
18705 (set (attr "prefix_rex")
18706 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18708 (const_string "*")))
18709 (set_attr "mode" "SI")])
18711 (define_insn "sse4_2_crc32di"
18712 [(set (match_operand:DI 0 "register_operand" "=r")
18714 [(match_operand:DI 1 "register_operand" "0")
18715 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18717 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18718 "crc32{q}\t{%2, %0|%0, %2}"
18719 [(set_attr "type" "sselog1")
18720 (set_attr "prefix_rep" "1")
18721 (set_attr "prefix_extra" "1")
18722 (set_attr "mode" "DI")])
18724 (define_insn "rdpmc"
18725 [(set (match_operand:DI 0 "register_operand" "=A")
18726 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18730 [(set_attr "type" "other")
18731 (set_attr "length" "2")])
18733 (define_insn "rdpmc_rex64"
18734 [(set (match_operand:DI 0 "register_operand" "=a")
18735 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18737 (set (match_operand:DI 1 "register_operand" "=d")
18738 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18741 [(set_attr "type" "other")
18742 (set_attr "length" "2")])
18744 (define_insn "rdtsc"
18745 [(set (match_operand:DI 0 "register_operand" "=A")
18746 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18749 [(set_attr "type" "other")
18750 (set_attr "length" "2")])
18752 (define_insn "rdtsc_rex64"
18753 [(set (match_operand:DI 0 "register_operand" "=a")
18754 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18755 (set (match_operand:DI 1 "register_operand" "=d")
18756 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18759 [(set_attr "type" "other")
18760 (set_attr "length" "2")])
18762 (define_insn "rdtscp"
18763 [(set (match_operand:DI 0 "register_operand" "=A")
18764 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18765 (set (match_operand:SI 1 "register_operand" "=c")
18766 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18769 [(set_attr "type" "other")
18770 (set_attr "length" "3")])
18772 (define_insn "rdtscp_rex64"
18773 [(set (match_operand:DI 0 "register_operand" "=a")
18774 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18775 (set (match_operand:DI 1 "register_operand" "=d")
18776 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18777 (set (match_operand:SI 2 "register_operand" "=c")
18778 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18781 [(set_attr "type" "other")
18782 (set_attr "length" "3")])
18784 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18786 ;; FXSR, XSAVE and XSAVEOPT instructions
18788 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18790 (define_insn "fxsave"
18791 [(set (match_operand:BLK 0 "memory_operand" "=m")
18792 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18795 [(set_attr "type" "other")
18796 (set_attr "memory" "store")
18797 (set (attr "length")
18798 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18800 (define_insn "fxsave64"
18801 [(set (match_operand:BLK 0 "memory_operand" "=m")
18802 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18803 "TARGET_64BIT && TARGET_FXSR"
18805 [(set_attr "type" "other")
18806 (set_attr "memory" "store")
18807 (set (attr "length")
18808 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18810 (define_insn "fxrstor"
18811 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18815 [(set_attr "type" "other")
18816 (set_attr "memory" "load")
18817 (set (attr "length")
18818 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18820 (define_insn "fxrstor64"
18821 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18822 UNSPECV_FXRSTOR64)]
18823 "TARGET_64BIT && TARGET_FXSR"
18825 [(set_attr "type" "other")
18826 (set_attr "memory" "load")
18827 (set (attr "length")
18828 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18830 (define_int_iterator ANY_XSAVE
18832 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18833 (UNSPECV_XSAVEC "TARGET_XSAVEC")
18834 (UNSPECV_XSAVES "TARGET_XSAVES")])
18836 (define_int_iterator ANY_XSAVE64
18838 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18839 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18840 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18842 (define_int_attr xsave
18843 [(UNSPECV_XSAVE "xsave")
18844 (UNSPECV_XSAVE64 "xsave64")
18845 (UNSPECV_XSAVEOPT "xsaveopt")
18846 (UNSPECV_XSAVEOPT64 "xsaveopt64")
18847 (UNSPECV_XSAVEC "xsavec")
18848 (UNSPECV_XSAVEC64 "xsavec64")
18849 (UNSPECV_XSAVES "xsaves")
18850 (UNSPECV_XSAVES64 "xsaves64")])
18852 (define_int_iterator ANY_XRSTOR
18854 (UNSPECV_XRSTORS "TARGET_XSAVES")])
18856 (define_int_iterator ANY_XRSTOR64
18858 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18860 (define_int_attr xrstor
18861 [(UNSPECV_XRSTOR "xrstor")
18862 (UNSPECV_XRSTOR64 "xrstor")
18863 (UNSPECV_XRSTORS "xrstors")
18864 (UNSPECV_XRSTORS64 "xrstors")])
18866 (define_insn "<xsave>"
18867 [(set (match_operand:BLK 0 "memory_operand" "=m")
18868 (unspec_volatile:BLK
18869 [(match_operand:DI 1 "register_operand" "A")]
18871 "!TARGET_64BIT && TARGET_XSAVE"
18873 [(set_attr "type" "other")
18874 (set_attr "memory" "store")
18875 (set (attr "length")
18876 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18878 (define_insn "<xsave>_rex64"
18879 [(set (match_operand:BLK 0 "memory_operand" "=m")
18880 (unspec_volatile:BLK
18881 [(match_operand:SI 1 "register_operand" "a")
18882 (match_operand:SI 2 "register_operand" "d")]
18884 "TARGET_64BIT && TARGET_XSAVE"
18886 [(set_attr "type" "other")
18887 (set_attr "memory" "store")
18888 (set (attr "length")
18889 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18891 (define_insn "<xsave>"
18892 [(set (match_operand:BLK 0 "memory_operand" "=m")
18893 (unspec_volatile:BLK
18894 [(match_operand:SI 1 "register_operand" "a")
18895 (match_operand:SI 2 "register_operand" "d")]
18897 "TARGET_64BIT && TARGET_XSAVE"
18899 [(set_attr "type" "other")
18900 (set_attr "memory" "store")
18901 (set (attr "length")
18902 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18904 (define_insn "<xrstor>"
18905 [(unspec_volatile:BLK
18906 [(match_operand:BLK 0 "memory_operand" "m")
18907 (match_operand:DI 1 "register_operand" "A")]
18909 "!TARGET_64BIT && TARGET_XSAVE"
18911 [(set_attr "type" "other")
18912 (set_attr "memory" "load")
18913 (set (attr "length")
18914 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18916 (define_insn "<xrstor>_rex64"
18917 [(unspec_volatile:BLK
18918 [(match_operand:BLK 0 "memory_operand" "m")
18919 (match_operand:SI 1 "register_operand" "a")
18920 (match_operand:SI 2 "register_operand" "d")]
18922 "TARGET_64BIT && TARGET_XSAVE"
18924 [(set_attr "type" "other")
18925 (set_attr "memory" "load")
18926 (set (attr "length")
18927 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18929 (define_insn "<xrstor>64"
18930 [(unspec_volatile:BLK
18931 [(match_operand:BLK 0 "memory_operand" "m")
18932 (match_operand:SI 1 "register_operand" "a")
18933 (match_operand:SI 2 "register_operand" "d")]
18935 "TARGET_64BIT && TARGET_XSAVE"
18937 [(set_attr "type" "other")
18938 (set_attr "memory" "load")
18939 (set (attr "length")
18940 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18942 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18944 ;; Floating-point instructions for atomic compound assignments
18946 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18948 ; Clobber all floating-point registers on environment save and restore
18949 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18950 (define_insn "fnstenv"
18951 [(set (match_operand:BLK 0 "memory_operand" "=m")
18952 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18953 (clobber (reg:HI FPCR_REG))
18954 (clobber (reg:XF ST0_REG))
18955 (clobber (reg:XF ST1_REG))
18956 (clobber (reg:XF ST2_REG))
18957 (clobber (reg:XF ST3_REG))
18958 (clobber (reg:XF ST4_REG))
18959 (clobber (reg:XF ST5_REG))
18960 (clobber (reg:XF ST6_REG))
18961 (clobber (reg:XF ST7_REG))]
18964 [(set_attr "type" "other")
18965 (set_attr "memory" "store")
18966 (set (attr "length")
18967 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18969 (define_insn "fldenv"
18970 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18972 (clobber (reg:CCFP FPSR_REG))
18973 (clobber (reg:HI FPCR_REG))
18974 (clobber (reg:XF ST0_REG))
18975 (clobber (reg:XF ST1_REG))
18976 (clobber (reg:XF ST2_REG))
18977 (clobber (reg:XF ST3_REG))
18978 (clobber (reg:XF ST4_REG))
18979 (clobber (reg:XF ST5_REG))
18980 (clobber (reg:XF ST6_REG))
18981 (clobber (reg:XF ST7_REG))]
18984 [(set_attr "type" "other")
18985 (set_attr "memory" "load")
18986 (set (attr "length")
18987 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18989 (define_insn "fnstsw"
18990 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18991 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18994 [(set_attr "type" "other,other")
18995 (set_attr "memory" "none,store")
18996 (set (attr "length")
18997 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18999 (define_insn "fnclex"
19000 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
19003 [(set_attr "type" "other")
19004 (set_attr "memory" "none")
19005 (set_attr "length" "2")])
19007 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19009 ;; LWP instructions
19011 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19013 (define_expand "lwp_llwpcb"
19014 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
19015 UNSPECV_LLWP_INTRINSIC)]
19018 (define_insn "*lwp_llwpcb<mode>1"
19019 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
19020 UNSPECV_LLWP_INTRINSIC)]
19023 [(set_attr "type" "lwp")
19024 (set_attr "mode" "<MODE>")
19025 (set_attr "length" "5")])
19027 (define_expand "lwp_slwpcb"
19028 [(set (match_operand 0 "register_operand" "=r")
19029 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19034 insn = (Pmode == DImode
19036 : gen_lwp_slwpcbsi);
19038 emit_insn (insn (operands[0]));
19042 (define_insn "lwp_slwpcb<mode>"
19043 [(set (match_operand:P 0 "register_operand" "=r")
19044 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19047 [(set_attr "type" "lwp")
19048 (set_attr "mode" "<MODE>")
19049 (set_attr "length" "5")])
19051 (define_expand "lwp_lwpval<mode>3"
19052 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
19053 (match_operand:SI 2 "nonimmediate_operand" "rm")
19054 (match_operand:SI 3 "const_int_operand" "i")]
19055 UNSPECV_LWPVAL_INTRINSIC)]
19057 ;; Avoid unused variable warning.
19058 "(void) operands[0];")
19060 (define_insn "*lwp_lwpval<mode>3_1"
19061 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
19062 (match_operand:SI 1 "nonimmediate_operand" "rm")
19063 (match_operand:SI 2 "const_int_operand" "i")]
19064 UNSPECV_LWPVAL_INTRINSIC)]
19066 "lwpval\t{%2, %1, %0|%0, %1, %2}"
19067 [(set_attr "type" "lwp")
19068 (set_attr "mode" "<MODE>")
19069 (set (attr "length")
19070 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19072 (define_expand "lwp_lwpins<mode>3"
19073 [(set (reg:CCC FLAGS_REG)
19074 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
19075 (match_operand:SI 2 "nonimmediate_operand" "rm")
19076 (match_operand:SI 3 "const_int_operand" "i")]
19077 UNSPECV_LWPINS_INTRINSIC))
19078 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
19079 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
19082 (define_insn "*lwp_lwpins<mode>3_1"
19083 [(set (reg:CCC FLAGS_REG)
19084 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
19085 (match_operand:SI 1 "nonimmediate_operand" "rm")
19086 (match_operand:SI 2 "const_int_operand" "i")]
19087 UNSPECV_LWPINS_INTRINSIC))]
19089 "lwpins\t{%2, %1, %0|%0, %1, %2}"
19090 [(set_attr "type" "lwp")
19091 (set_attr "mode" "<MODE>")
19092 (set (attr "length")
19093 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19095 (define_int_iterator RDFSGSBASE
19099 (define_int_iterator WRFSGSBASE
19103 (define_int_attr fsgs
19104 [(UNSPECV_RDFSBASE "fs")
19105 (UNSPECV_RDGSBASE "gs")
19106 (UNSPECV_WRFSBASE "fs")
19107 (UNSPECV_WRGSBASE "gs")])
19109 (define_insn "rd<fsgs>base<mode>"
19110 [(set (match_operand:SWI48 0 "register_operand" "=r")
19111 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
19112 "TARGET_64BIT && TARGET_FSGSBASE"
19114 [(set_attr "type" "other")
19115 (set_attr "prefix_extra" "2")])
19117 (define_insn "wr<fsgs>base<mode>"
19118 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
19120 "TARGET_64BIT && TARGET_FSGSBASE"
19122 [(set_attr "type" "other")
19123 (set_attr "prefix_extra" "2")])
19125 (define_insn "rdrand<mode>_1"
19126 [(set (match_operand:SWI248 0 "register_operand" "=r")
19127 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
19128 (set (reg:CCC FLAGS_REG)
19129 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
19132 [(set_attr "type" "other")
19133 (set_attr "prefix_extra" "1")])
19135 (define_insn "rdseed<mode>_1"
19136 [(set (match_operand:SWI248 0 "register_operand" "=r")
19137 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
19138 (set (reg:CCC FLAGS_REG)
19139 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
19142 [(set_attr "type" "other")
19143 (set_attr "prefix_extra" "1")])
19145 (define_expand "pause"
19146 [(set (match_dup 0)
19147 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19150 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
19151 MEM_VOLATILE_P (operands[0]) = 1;
19154 ;; Use "rep; nop", instead of "pause", to support older assemblers.
19155 ;; They have the same encoding.
19156 (define_insn "*pause"
19157 [(set (match_operand:BLK 0)
19158 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19161 [(set_attr "length" "2")
19162 (set_attr "memory" "unknown")])
19164 (define_expand "xbegin"
19165 [(set (match_operand:SI 0 "register_operand")
19166 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
19169 rtx_code_label *label = gen_label_rtx ();
19171 /* xbegin is emitted as jump_insn, so reload won't be able
19172 to reload its operand. Force the value into AX hard register. */
19173 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
19174 emit_move_insn (ax_reg, constm1_rtx);
19176 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
19178 emit_label (label);
19179 LABEL_NUSES (label) = 1;
19181 emit_move_insn (operands[0], ax_reg);
19186 (define_insn "xbegin_1"
19188 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
19190 (label_ref (match_operand 1))
19192 (set (match_operand:SI 0 "register_operand" "+a")
19193 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
19196 [(set_attr "type" "other")
19197 (set_attr "length" "6")])
19199 (define_insn "xend"
19200 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
19203 [(set_attr "type" "other")
19204 (set_attr "length" "3")])
19206 (define_insn "xabort"
19207 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
19211 [(set_attr "type" "other")
19212 (set_attr "length" "3")])
19214 (define_expand "xtest"
19215 [(set (match_operand:QI 0 "register_operand")
19216 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
19219 emit_insn (gen_xtest_1 ());
19221 ix86_expand_setcc (operands[0], NE,
19222 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
19226 (define_insn "xtest_1"
19227 [(set (reg:CCZ FLAGS_REG)
19228 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
19231 [(set_attr "type" "other")
19232 (set_attr "length" "3")])
19234 (define_insn "pcommit"
19235 [(unspec_volatile [(const_int 0)] UNSPECV_PCOMMIT)]
19238 [(set_attr "type" "other")
19239 (set_attr "length" "4")])
19241 (define_insn "clwb"
19242 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
19246 [(set_attr "type" "sse")
19247 (set_attr "atom_sse_attr" "fence")
19248 (set_attr "memory" "unknown")])
19250 (define_insn "clflushopt"
19251 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
19252 UNSPECV_CLFLUSHOPT)]
19253 "TARGET_CLFLUSHOPT"
19255 [(set_attr "type" "sse")
19256 (set_attr "atom_sse_attr" "fence")
19257 (set_attr "memory" "unknown")])
19259 ;; MONITORX and MWAITX
19260 (define_insn "mwaitx"
19261 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
19262 (match_operand:SI 1 "register_operand" "a")
19263 (match_operand:SI 2 "register_operand" "b")]
19266 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
19267 ;; Since 32bit register operands are implicitly zero extended to 64bit,
19268 ;; we only need to set up 32bit registers.
19270 [(set_attr "length" "3")])
19272 (define_insn "monitorx_<mode>"
19273 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
19274 (match_operand:SI 1 "register_operand" "c")
19275 (match_operand:SI 2 "register_operand" "d")]
19278 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
19279 ;; RCX and RDX are used. Since 32bit register operands are implicitly
19280 ;; zero extended to 64bit, we only need to set up 32bit registers.
19282 [(set (attr "length")
19283 (symbol_ref ("(Pmode != word_mode) + 3")))])
19286 (define_insn "clzero_<mode>"
19287 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
19291 [(set_attr "length" "3")
19292 (set_attr "memory" "unknown")])
19294 ;; MPX instructions
19296 (define_expand "<mode>_mk"
19297 [(set (match_operand:BND 0 "register_operand")
19301 [(match_operand:<bnd_ptr> 1 "register_operand")
19302 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
19306 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
19308 UNSPEC_BNDMK_ADDR);
19311 (define_insn "*<mode>_mk"
19312 [(set (match_operand:BND 0 "register_operand" "=w")
19314 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19316 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
19317 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
19318 UNSPEC_BNDMK_ADDR)])]
19321 "bndmk\t{%3, %0|%0, %3}"
19322 [(set_attr "type" "mpxmk")])
19324 (define_expand "mov<mode>"
19325 [(set (match_operand:BND 0 "general_operand")
19326 (match_operand:BND 1 "general_operand"))]
19328 "ix86_expand_move (<MODE>mode, operands); DONE;")
19330 (define_insn "*mov<mode>_internal_mpx"
19331 [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
19332 (match_operand:BND 1 "general_operand" "wm,w"))]
19334 "bndmov\t{%1, %0|%0, %1}"
19335 [(set_attr "type" "mpxmov")])
19337 (define_expand "<mode>_<bndcheck>"
19340 [(match_operand:BND 0 "register_operand")
19341 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
19343 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
19346 operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
19347 MEM_VOLATILE_P (operands[2]) = 1;
19350 (define_insn "*<mode>_<bndcheck>"
19352 [(match_operand:BND 0 "register_operand" "w")
19353 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
19354 (set (match_operand:BLK 2 "bnd_mem_operator")
19355 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))]
19357 "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
19358 [(set_attr "type" "mpxchk")])
19360 (define_expand "<mode>_ldx"
19362 [(set (match_operand:BND 0 "register_operand")
19366 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
19367 (match_operand:<bnd_ptr> 2 "register_operand")]))]
19369 (use (mem:BLK (match_dup 1)))])]
19372 /* Avoid registers which cannot be used as index. */
19373 if (!index_register_operand (operands[2], Pmode))
19374 operands[2] = copy_addr_to_reg (operands[2]);
19376 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
19378 UNSPEC_BNDLDX_ADDR);
19381 (define_insn "*<mode>_ldx"
19382 [(set (match_operand:BND 0 "register_operand" "=w")
19384 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19386 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
19387 (match_operand:<bnd_ptr> 2 "register_operand" "l")]
19388 UNSPEC_BNDLDX_ADDR)])]
19390 (use (mem:BLK (match_dup 1)))]
19392 "bndldx\t{%3, %0|%0, %3}"
19393 [(set_attr "type" "mpxld")])
19395 (define_expand "<mode>_stx"
19400 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
19401 (match_operand:<bnd_ptr> 1 "register_operand")]))
19402 (match_operand:BND 2 "register_operand")]
19405 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
19408 /* Avoid registers which cannot be used as index. */
19409 if (!index_register_operand (operands[1], Pmode))
19410 operands[1] = copy_addr_to_reg (operands[1]);
19412 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
19414 UNSPEC_BNDLDX_ADDR);
19415 operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
19416 MEM_VOLATILE_P (operands[4]) = 1;
19419 (define_insn "*<mode>_stx"
19421 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19423 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
19424 (match_operand:<bnd_ptr> 1 "register_operand" "l")]
19425 UNSPEC_BNDLDX_ADDR)])
19426 (match_operand:BND 2 "register_operand" "w")]
19428 (set (match_operand:BLK 4 "bnd_mem_operator")
19429 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))]
19431 "bndstx\t{%2, %3|%3, %2}"
19432 [(set_attr "type" "mpxst")])
19434 (define_insn "move_size_reloc_<mode>"
19435 [(set (match_operand:SWI48 0 "register_operand" "=r")
19437 [(match_operand:SWI48 1 "symbol_operand")]
19441 if (x86_64_immediate_size_operand (operands[1], VOIDmode))
19442 return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
19444 return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
19446 [(set_attr "type" "imov")
19447 (set_attr "mode" "<MODE>")])
19449 ;; RDPKRU and WRPKRU
19451 (define_expand "rdpkru"
19453 [(set (match_operand:SI 0 "register_operand")
19454 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
19455 (set (match_dup 2) (const_int 0))])]
19458 operands[1] = force_reg (SImode, const0_rtx);
19459 operands[2] = gen_reg_rtx (SImode);
19462 (define_insn "*rdpkru"
19463 [(set (match_operand:SI 0 "register_operand" "=a")
19464 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
19466 (set (match_operand:SI 1 "register_operand" "=d")
19470 [(set_attr "type" "other")])
19472 (define_expand "wrpkru"
19473 [(unspec_volatile:SI
19474 [(match_operand:SI 0 "register_operand")
19475 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
19478 operands[1] = force_reg (SImode, const0_rtx);
19479 operands[2] = force_reg (SImode, const0_rtx);
19482 (define_insn "*wrpkru"
19483 [(unspec_volatile:SI
19484 [(match_operand:SI 0 "register_operand" "a")
19485 (match_operand:SI 1 "register_operand" "d")
19486 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
19489 [(set_attr "type" "other")])
19493 (include "sync.md")