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
177 ;; For LZCNT suppoprt
188 ;; For AVX512F support
202 (define_c_enum "unspecv" [
205 UNSPECV_PROBE_STACK_RANGE
208 UNSPECV_SPLIT_STACK_RETURN
214 UNSPECV_LLWP_INTRINSIC
215 UNSPECV_SLWP_INTRINSIC
216 UNSPECV_LWPVAL_INTRINSIC
217 UNSPECV_LWPINS_INTRINSIC
239 ;; For atomic compound assignments.
245 ;; For RDRAND support
248 ;; For RDSEED support
262 ;; For CLFLUSHOPT support
265 ;; For MONITORX and MWAITX support
269 ;; For CLZERO support
272 ;; For RDPKRU and WRPKRU support
275 ;; For Speculation Barrier support
276 UNSPECV_SPECULATION_BARRIER
279 ;; Constants to represent rounding modes in the ROUND instruction
288 ;; Constants to represent AVX512F embeded rounding
290 [(ROUND_NEAREST_INT 0)
298 ;; Constants to represent pcomtrue/pcomfalse variants
308 ;; Constants used in the XOP pperm instruction
310 [(PPERM_SRC 0x00) /* copy source */
311 (PPERM_INVERT 0x20) /* invert source */
312 (PPERM_REVERSE 0x40) /* bit reverse source */
313 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
314 (PPERM_ZERO 0x80) /* all 0's */
315 (PPERM_ONES 0xa0) /* all 1's */
316 (PPERM_SIGN 0xc0) /* propagate sign bit */
317 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
318 (PPERM_SRC1 0x00) /* use first source byte */
319 (PPERM_SRC2 0x10) /* use second source byte */
322 ;; Registers by name.
405 (FIRST_PSEUDO_REG 81)
408 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
411 ;; In C guard expressions, put expressions which may be compile-time
412 ;; constants first. This allows for better optimization. For
413 ;; example, write "TARGET_64BIT && reload_completed", not
414 ;; "reload_completed && TARGET_64BIT".
418 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
419 atom,slm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
420 bdver4,btver2,znver1"
421 (const (symbol_ref "ix86_schedule")))
423 ;; A basic instruction type. Refinements due to arguments to be
424 ;; provided in other attributes.
427 alu,alu1,negnot,imov,imovx,lea,
428 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
429 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
430 push,pop,call,callv,leave,
432 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
433 fxch,fistp,fisttp,frndint,
434 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
435 ssemul,sseimul,ssediv,sselog,sselog1,
436 sseishft,sseishft1,ssecmp,ssecomi,
437 ssecvt,ssecvt1,sseicvt,sseins,
438 sseshuf,sseshuf1,ssemuladd,sse4arg,
440 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
441 mpxmov,mpxmk,mpxchk,mpxld,mpxst"
442 (const_string "other"))
444 ;; Main data type used by the insn
446 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
448 (const_string "unknown"))
450 ;; The CPU unit operations uses.
451 (define_attr "unit" "integer,i387,sse,mmx,unknown"
452 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
453 fxch,fistp,fisttp,frndint")
454 (const_string "i387")
455 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
456 ssemul,sseimul,ssediv,sselog,sselog1,
457 sseishft,sseishft1,ssecmp,ssecomi,
458 ssecvt,ssecvt1,sseicvt,sseins,
459 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
461 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
463 (eq_attr "type" "other")
464 (const_string "unknown")]
465 (const_string "integer")))
467 ;; The minimum required alignment of vector mode memory operands of the SSE
468 ;; (non-VEX/EVEX) instruction in bits, if it is different from
469 ;; GET_MODE_ALIGNMENT of the operand, otherwise 0. If an instruction has
470 ;; multiple alternatives, this should be conservative maximum of those minimum
471 ;; required alignments.
472 (define_attr "ssememalign" "" (const_int 0))
474 ;; The (bounding maximum) length of an instruction immediate.
475 (define_attr "length_immediate" ""
476 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
477 bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
480 (eq_attr "unit" "i387,sse,mmx")
482 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
483 rotate,rotatex,rotate1,imul,icmp,push,pop")
484 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
485 (eq_attr "type" "imov,test")
486 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
487 (eq_attr "type" "call")
488 (if_then_else (match_operand 0 "constant_call_address_operand")
491 (eq_attr "type" "callv")
492 (if_then_else (match_operand 1 "constant_call_address_operand")
495 ;; We don't know the size before shorten_branches. Expect
496 ;; the instruction to fit for better scheduling.
497 (eq_attr "type" "ibr")
500 (symbol_ref "/* Update immediate_length and other attributes! */
501 gcc_unreachable (),1")))
503 ;; The (bounding maximum) length of an instruction address.
504 (define_attr "length_address" ""
505 (cond [(eq_attr "type" "str,other,multi,fxch")
507 (and (eq_attr "type" "call")
508 (match_operand 0 "constant_call_address_operand"))
510 (and (eq_attr "type" "callv")
511 (match_operand 1 "constant_call_address_operand"))
514 (symbol_ref "ix86_attr_length_address_default (insn)")))
516 ;; Set when length prefix is used.
517 (define_attr "prefix_data16" ""
518 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
520 (eq_attr "mode" "HI")
522 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
527 ;; Set when string REP prefix is used.
528 (define_attr "prefix_rep" ""
529 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
531 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
533 (and (eq_attr "type" "ibr,call,callv")
534 (match_test "ix86_bnd_prefixed_insn_p (insn)"))
539 ;; Set when 0f opcode prefix is used.
540 (define_attr "prefix_0f" ""
542 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
543 mpxmk,mpxmov,mpxchk,mpxld,mpxst")
544 (eq_attr "unit" "sse,mmx"))
548 ;; Set when REX opcode prefix is used.
549 (define_attr "prefix_rex" ""
550 (cond [(not (match_test "TARGET_64BIT"))
552 (and (eq_attr "mode" "DI")
553 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
554 (eq_attr "unit" "!mmx")))
556 (and (eq_attr "mode" "QI")
557 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
559 (match_test "x86_extended_reg_mentioned_p (insn)")
561 (and (eq_attr "type" "imovx")
562 (match_operand:QI 1 "ext_QIreg_operand"))
567 ;; There are also additional prefixes in 3DNOW, SSSE3.
568 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
569 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
570 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
571 (define_attr "prefix_extra" ""
572 (cond [(eq_attr "type" "ssemuladd,sse4arg")
574 (eq_attr "type" "sseiadd1,ssecvt1")
579 ;; Set when BND opcode prefix may be used.
580 (define_attr "maybe_prefix_bnd" "" (const_int 0))
582 ;; Prefix used: original, VEX or maybe VEX.
583 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
584 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
586 (eq_attr "mode" "XI,V16SF,V8DF")
587 (const_string "evex")
589 (const_string "orig")))
591 ;; VEX W bit is used.
592 (define_attr "prefix_vex_w" "" (const_int 0))
594 ;; The length of VEX prefix
595 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
596 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
597 ;; still prefix_0f 1, with prefix_extra 1.
598 (define_attr "length_vex" ""
599 (if_then_else (and (eq_attr "prefix_0f" "1")
600 (eq_attr "prefix_extra" "0"))
601 (if_then_else (eq_attr "prefix_vex_w" "1")
602 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
603 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
604 (if_then_else (eq_attr "prefix_vex_w" "1")
605 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
606 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
608 ;; 4-bytes evex prefix and 1 byte opcode.
609 (define_attr "length_evex" "" (const_int 5))
611 ;; Set when modrm byte is used.
612 (define_attr "modrm" ""
613 (cond [(eq_attr "type" "str,leave")
615 (eq_attr "unit" "i387")
617 (and (eq_attr "type" "incdec")
618 (and (not (match_test "TARGET_64BIT"))
619 (ior (match_operand:SI 1 "register_operand")
620 (match_operand:HI 1 "register_operand"))))
622 (and (eq_attr "type" "push")
623 (not (match_operand 1 "memory_operand")))
625 (and (eq_attr "type" "pop")
626 (not (match_operand 0 "memory_operand")))
628 (and (eq_attr "type" "imov")
629 (and (not (eq_attr "mode" "DI"))
630 (ior (and (match_operand 0 "register_operand")
631 (match_operand 1 "immediate_operand"))
632 (ior (and (match_operand 0 "ax_reg_operand")
633 (match_operand 1 "memory_displacement_only_operand"))
634 (and (match_operand 0 "memory_displacement_only_operand")
635 (match_operand 1 "ax_reg_operand"))))))
637 (and (eq_attr "type" "call")
638 (match_operand 0 "constant_call_address_operand"))
640 (and (eq_attr "type" "callv")
641 (match_operand 1 "constant_call_address_operand"))
643 (and (eq_attr "type" "alu,alu1,icmp,test")
644 (match_operand 0 "ax_reg_operand"))
645 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
649 (define_attr "modrm_class" "none,incdec,op0,op01,op02,pushpop,unknown"
650 (cond [(eq_attr "modrm" "0")
651 (const_string "none")
652 (eq_attr "type" "alu,imul,ishift")
653 (const_string "op02")
654 (eq_attr "type" "imov,imovx,lea,alu1,icmp")
655 (const_string "op01")
656 (eq_attr "type" "incdec")
657 (const_string "incdec")
658 (eq_attr "type" "push,pop")
659 (const_string "pushpop")]
660 (const_string "unknown")))
662 ;; The (bounding maximum) length of an instruction in bytes.
663 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
664 ;; Later we may want to split them and compute proper length as for
666 (define_attr "length" ""
667 (cond [(eq_attr "type" "other,multi,fistp,frndint")
669 (eq_attr "type" "fcmp")
671 (eq_attr "unit" "i387")
673 (plus (attr "prefix_data16")
674 (attr "length_address")))
675 (ior (eq_attr "prefix" "evex")
676 (and (ior (eq_attr "prefix" "maybe_evex")
677 (eq_attr "prefix" "maybe_vex"))
678 (match_test "TARGET_AVX512F")))
679 (plus (attr "length_evex")
680 (plus (attr "length_immediate")
682 (attr "length_address"))))
683 (ior (eq_attr "prefix" "vex")
684 (and (ior (eq_attr "prefix" "maybe_vex")
685 (eq_attr "prefix" "maybe_evex"))
686 (match_test "TARGET_AVX")))
687 (plus (attr "length_vex")
688 (plus (attr "length_immediate")
690 (attr "length_address"))))]
691 (plus (plus (attr "modrm")
692 (plus (attr "prefix_0f")
693 (plus (attr "prefix_rex")
694 (plus (attr "prefix_extra")
696 (plus (attr "prefix_rep")
697 (plus (attr "prefix_data16")
698 (plus (attr "length_immediate")
699 (attr "length_address")))))))
701 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
702 ;; `store' if there is a simple memory reference therein, or `unknown'
703 ;; if the instruction is complex.
705 (define_attr "memory" "none,load,store,both,unknown"
706 (cond [(eq_attr "type" "other,multi,str,lwp")
707 (const_string "unknown")
708 (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
709 (const_string "none")
710 (eq_attr "type" "fistp,leave")
711 (const_string "both")
712 (eq_attr "type" "frndint")
713 (const_string "load")
714 (eq_attr "type" "mpxld")
715 (const_string "load")
716 (eq_attr "type" "mpxst")
717 (const_string "store")
718 (eq_attr "type" "push")
719 (if_then_else (match_operand 1 "memory_operand")
720 (const_string "both")
721 (const_string "store"))
722 (eq_attr "type" "pop")
723 (if_then_else (match_operand 0 "memory_operand")
724 (const_string "both")
725 (const_string "load"))
726 (eq_attr "type" "setcc")
727 (if_then_else (match_operand 0 "memory_operand")
728 (const_string "store")
729 (const_string "none"))
730 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
731 (if_then_else (ior (match_operand 0 "memory_operand")
732 (match_operand 1 "memory_operand"))
733 (const_string "load")
734 (const_string "none"))
735 (eq_attr "type" "ibr")
736 (if_then_else (match_operand 0 "memory_operand")
737 (const_string "load")
738 (const_string "none"))
739 (eq_attr "type" "call")
740 (if_then_else (match_operand 0 "constant_call_address_operand")
741 (const_string "none")
742 (const_string "load"))
743 (eq_attr "type" "callv")
744 (if_then_else (match_operand 1 "constant_call_address_operand")
745 (const_string "none")
746 (const_string "load"))
747 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
748 (match_operand 1 "memory_operand"))
749 (const_string "both")
750 (and (match_operand 0 "memory_operand")
751 (match_operand 1 "memory_operand"))
752 (const_string "both")
753 (match_operand 0 "memory_operand")
754 (const_string "store")
755 (match_operand 1 "memory_operand")
756 (const_string "load")
758 "!alu1,negnot,ishift1,
759 imov,imovx,icmp,test,bitmanip,
761 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
762 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
763 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
764 (match_operand 2 "memory_operand"))
765 (const_string "load")
766 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
767 (match_operand 3 "memory_operand"))
768 (const_string "load")
770 (const_string "none")))
772 ;; Indicates if an instruction has both an immediate and a displacement.
774 (define_attr "imm_disp" "false,true,unknown"
775 (cond [(eq_attr "type" "other,multi")
776 (const_string "unknown")
777 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
778 (and (match_operand 0 "memory_displacement_operand")
779 (match_operand 1 "immediate_operand")))
780 (const_string "true")
781 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
782 (and (match_operand 0 "memory_displacement_operand")
783 (match_operand 2 "immediate_operand")))
784 (const_string "true")
786 (const_string "false")))
788 ;; Indicates if an FP operation has an integer source.
790 (define_attr "fp_int_src" "false,true"
791 (const_string "false"))
793 ;; Defines rounding mode of an FP operation.
795 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
796 (const_string "any"))
798 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
799 (define_attr "use_carry" "0,1" (const_string "0"))
801 ;; Define attribute to indicate unaligned ssemov insns
802 (define_attr "movu" "0,1" (const_string "0"))
804 ;; Used to control the "enabled" attribute on a per-instruction basis.
805 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
806 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
807 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
808 fma_avx512f,avx512bw,noavx512bw,avx512dq,noavx512dq,
810 (const_string "base"))
812 (define_attr "enabled" ""
813 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
814 (eq_attr "isa" "x64_sse4")
815 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
816 (eq_attr "isa" "x64_sse4_noavx")
817 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
818 (eq_attr "isa" "x64_avx")
819 (symbol_ref "TARGET_64BIT && TARGET_AVX")
820 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
821 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
822 (eq_attr "isa" "sse2_noavx")
823 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
824 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
825 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
826 (eq_attr "isa" "sse4_noavx")
827 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
828 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
829 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
830 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
831 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
832 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
833 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
834 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
835 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
836 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
837 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
838 (eq_attr "isa" "fma_avx512f")
839 (symbol_ref "TARGET_FMA || TARGET_AVX512F")
840 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
841 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
842 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
843 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
844 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
845 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
849 (define_attr "preferred_for_size" "" (const_int 1))
850 (define_attr "preferred_for_speed" "" (const_int 1))
852 ;; Describe a user's asm statement.
853 (define_asm_attributes
854 [(set_attr "length" "128")
855 (set_attr "type" "multi")])
857 (define_code_iterator plusminus [plus minus])
859 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
861 (define_code_iterator multdiv [mult div])
863 ;; Base name for define_insn
864 (define_code_attr plusminus_insn
865 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
866 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
868 ;; Base name for insn mnemonic.
869 (define_code_attr plusminus_mnemonic
870 [(plus "add") (ss_plus "adds") (us_plus "addus")
871 (minus "sub") (ss_minus "subs") (us_minus "subus")])
872 (define_code_attr multdiv_mnemonic
873 [(mult "mul") (div "div")])
875 ;; Mark commutative operators as such in constraints.
876 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
877 (minus "") (ss_minus "") (us_minus "")])
879 ;; Mapping of max and min
880 (define_code_iterator maxmin [smax smin umax umin])
882 ;; Mapping of signed max and min
883 (define_code_iterator smaxmin [smax smin])
885 ;; Mapping of unsigned max and min
886 (define_code_iterator umaxmin [umax umin])
888 ;; Base name for integer and FP insn mnemonic
889 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
890 (umax "maxu") (umin "minu")])
891 (define_code_attr maxmin_float [(smax "max") (smin "min")])
893 (define_int_iterator IEEE_MAXMIN
897 (define_int_attr ieee_maxmin
898 [(UNSPEC_IEEE_MAX "max")
899 (UNSPEC_IEEE_MIN "min")])
901 ;; Mapping of logic operators
902 (define_code_iterator any_logic [and ior xor])
903 (define_code_iterator any_or [ior xor])
904 (define_code_iterator fpint_logic [and xor])
906 ;; Base name for insn mnemonic.
907 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
909 ;; Mapping of logic-shift operators
910 (define_code_iterator any_lshift [ashift lshiftrt])
912 ;; Mapping of shift-right operators
913 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
915 ;; Mapping of all shift operators
916 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
918 ;; Base name for define_insn
919 (define_code_attr shift_insn
920 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
922 ;; Base name for insn mnemonic.
923 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
924 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
926 ;; Mask variant left right mnemonics
927 (define_code_attr mshift [(ashift "shiftl") (lshiftrt "shiftr")])
929 ;; Mapping of rotate operators
930 (define_code_iterator any_rotate [rotate rotatert])
932 ;; Base name for define_insn
933 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
935 ;; Base name for insn mnemonic.
936 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
938 ;; Mapping of abs neg operators
939 (define_code_iterator absneg [abs neg])
941 ;; Base name for x87 insn mnemonic.
942 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
944 ;; Used in signed and unsigned widening multiplications.
945 (define_code_iterator any_extend [sign_extend zero_extend])
947 ;; Prefix for insn menmonic.
948 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
950 ;; Prefix for define_insn
951 (define_code_attr u [(sign_extend "") (zero_extend "u")])
952 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
953 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
955 ;; Used in signed and unsigned truncations.
956 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
957 ;; Instruction suffix for truncations.
958 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
960 ;; Used in signed and unsigned fix.
961 (define_code_iterator any_fix [fix unsigned_fix])
962 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
964 ;; Used in signed and unsigned float.
965 (define_code_iterator any_float [float unsigned_float])
966 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
968 ;; All integer modes.
969 (define_mode_iterator SWI1248x [QI HI SI DI])
971 ;; All integer modes with AVX512BW/DQ.
972 (define_mode_iterator SWI1248_AVX512BWDQ
973 [(QI "TARGET_AVX512DQ") HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
975 ;; All integer modes without QImode.
976 (define_mode_iterator SWI248x [HI SI DI])
978 ;; All integer modes without QImode and HImode.
979 (define_mode_iterator SWI48x [SI DI])
981 ;; All integer modes without SImode and DImode.
982 (define_mode_iterator SWI12 [QI HI])
984 ;; All integer modes without DImode.
985 (define_mode_iterator SWI124 [QI HI SI])
987 ;; All integer modes without QImode and DImode.
988 (define_mode_iterator SWI24 [HI SI])
990 ;; Single word integer modes.
991 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
993 ;; Single word integer modes without QImode.
994 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
996 ;; Single word integer modes without QImode and HImode.
997 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
999 ;; All math-dependant single and double word integer modes.
1000 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1001 (HI "TARGET_HIMODE_MATH")
1002 SI DI (TI "TARGET_64BIT")])
1004 ;; Math-dependant single word integer modes.
1005 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1006 (HI "TARGET_HIMODE_MATH")
1007 SI (DI "TARGET_64BIT")])
1009 ;; Math-dependant integer modes without DImode.
1010 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1011 (HI "TARGET_HIMODE_MATH")
1014 ;; Math-dependant integer modes with DImode.
1015 (define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH")
1016 (HI "TARGET_HIMODE_MATH")
1017 SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")])
1019 ;; Math-dependant single word integer modes without QImode.
1020 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1021 SI (DI "TARGET_64BIT")])
1023 ;; Double word integer modes.
1024 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1025 (TI "TARGET_64BIT")])
1027 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1028 ;; compile time constant, it is faster to use <MODE_SIZE> than
1029 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1030 ;; command line options just use GET_MODE_SIZE macro.
1031 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1032 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1033 (V16QI "16") (V32QI "32") (V64QI "64")
1034 (V8HI "16") (V16HI "32") (V32HI "64")
1035 (V4SI "16") (V8SI "32") (V16SI "64")
1036 (V2DI "16") (V4DI "32") (V8DI "64")
1037 (V1TI "16") (V2TI "32") (V4TI "64")
1038 (V2DF "16") (V4DF "32") (V8DF "64")
1039 (V4SF "16") (V8SF "32") (V16SF "64")])
1041 ;; Double word integer modes as mode attribute.
1042 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1043 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1045 ;; Half mode for double word integer modes.
1046 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1047 (DI "TARGET_64BIT")])
1050 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1051 (BND64 "TARGET_LP64")])
1053 ;; Pointer mode corresponding to bound mode.
1054 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1057 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1060 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1062 (UNSPEC_BNDCN "cn")])
1064 ;; Instruction suffix for integer modes.
1065 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1067 ;; Instruction suffix for masks.
1068 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1070 ;; Pointer size prefix for integer modes (Intel asm dialect)
1071 (define_mode_attr iptrsize [(QI "BYTE")
1076 ;; Register class for integer modes.
1077 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1079 ;; Immediate operand constraint for integer modes.
1080 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1082 ;; General operand constraint for word modes.
1083 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1085 ;; Immediate operand constraint for double integer modes.
1086 (define_mode_attr di [(SI "nF") (DI "e")])
1088 ;; Immediate operand constraint for shifts.
1089 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1091 ;; General operand predicate for integer modes.
1092 (define_mode_attr general_operand
1093 [(QI "general_operand")
1094 (HI "general_operand")
1095 (SI "x86_64_general_operand")
1096 (DI "x86_64_general_operand")
1097 (TI "x86_64_general_operand")])
1099 ;; General sign extend operand predicate for integer modes,
1100 ;; which disallows VOIDmode operands and thus it is suitable
1101 ;; for use inside sign_extend.
1102 (define_mode_attr general_sext_operand
1103 [(QI "sext_operand")
1105 (SI "x86_64_sext_operand")
1106 (DI "x86_64_sext_operand")])
1108 ;; General sign/zero extend operand predicate for integer modes.
1109 (define_mode_attr general_szext_operand
1110 [(QI "general_operand")
1111 (HI "general_operand")
1112 (SI "x86_64_szext_general_operand")
1113 (DI "x86_64_szext_general_operand")])
1115 ;; Immediate operand predicate for integer modes.
1116 (define_mode_attr immediate_operand
1117 [(QI "immediate_operand")
1118 (HI "immediate_operand")
1119 (SI "x86_64_immediate_operand")
1120 (DI "x86_64_immediate_operand")])
1122 ;; Nonmemory operand predicate for integer modes.
1123 (define_mode_attr nonmemory_operand
1124 [(QI "nonmemory_operand")
1125 (HI "nonmemory_operand")
1126 (SI "x86_64_nonmemory_operand")
1127 (DI "x86_64_nonmemory_operand")])
1129 ;; Operand predicate for shifts.
1130 (define_mode_attr shift_operand
1131 [(QI "nonimmediate_operand")
1132 (HI "nonimmediate_operand")
1133 (SI "nonimmediate_operand")
1134 (DI "shiftdi_operand")
1135 (TI "register_operand")])
1137 ;; Operand predicate for shift argument.
1138 (define_mode_attr shift_immediate_operand
1139 [(QI "const_1_to_31_operand")
1140 (HI "const_1_to_31_operand")
1141 (SI "const_1_to_31_operand")
1142 (DI "const_1_to_63_operand")])
1144 ;; Input operand predicate for arithmetic left shifts.
1145 (define_mode_attr ashl_input_operand
1146 [(QI "nonimmediate_operand")
1147 (HI "nonimmediate_operand")
1148 (SI "nonimmediate_operand")
1149 (DI "ashldi_input_operand")
1150 (TI "reg_or_pm1_operand")])
1152 ;; SSE and x87 SFmode and DFmode floating point modes
1153 (define_mode_iterator MODEF [SF DF])
1155 ;; All x87 floating point modes
1156 (define_mode_iterator X87MODEF [SF DF XF])
1158 ;; SSE instruction suffix for various modes
1159 (define_mode_attr ssemodesuffix
1160 [(SF "ss") (DF "sd")
1161 (V16SF "ps") (V8DF "pd")
1162 (V8SF "ps") (V4DF "pd")
1163 (V4SF "ps") (V2DF "pd")
1164 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1165 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1166 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1168 ;; SSE vector suffix for floating point modes
1169 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1171 ;; SSE vector mode corresponding to a scalar mode
1172 (define_mode_attr ssevecmode
1173 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1174 (define_mode_attr ssevecmodelower
1175 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1177 ;; Instruction suffix for REX 64bit operators.
1178 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1180 ;; This mode iterator allows :P to be used for patterns that operate on
1181 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1182 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1184 ;; This mode iterator allows :W to be used for patterns that operate on
1185 ;; word_mode sized quantities.
1186 (define_mode_iterator W
1187 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1189 ;; This mode iterator allows :PTR to be used for patterns that operate on
1190 ;; ptr_mode sized quantities.
1191 (define_mode_iterator PTR
1192 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1194 ;; Scheduling descriptions
1196 (include "pentium.md")
1199 (include "athlon.md")
1200 (include "bdver1.md")
1201 (include "bdver3.md")
1202 (include "btver2.md")
1203 (include "znver1.md")
1204 (include "geode.md")
1207 (include "core2.md")
1208 (include "haswell.md")
1211 ;; Operand and operator predicates and constraints
1213 (include "predicates.md")
1214 (include "constraints.md")
1217 ;; Compare and branch/compare and store instructions.
1219 (define_expand "cbranch<mode>4"
1220 [(set (reg:CC FLAGS_REG)
1221 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1222 (match_operand:SDWIM 2 "<general_operand>")))
1223 (set (pc) (if_then_else
1224 (match_operator 0 "ordered_comparison_operator"
1225 [(reg:CC FLAGS_REG) (const_int 0)])
1226 (label_ref (match_operand 3))
1230 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1231 operands[1] = force_reg (<MODE>mode, operands[1]);
1232 ix86_expand_branch (GET_CODE (operands[0]),
1233 operands[1], operands[2], operands[3]);
1237 (define_expand "cstore<mode>4"
1238 [(set (reg:CC FLAGS_REG)
1239 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1240 (match_operand:SWIM 3 "<general_operand>")))
1241 (set (match_operand:QI 0 "register_operand")
1242 (match_operator 1 "ordered_comparison_operator"
1243 [(reg:CC FLAGS_REG) (const_int 0)]))]
1246 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1247 operands[2] = force_reg (<MODE>mode, operands[2]);
1248 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1249 operands[2], operands[3]);
1253 (define_expand "cmp<mode>_1"
1254 [(set (reg:CC FLAGS_REG)
1255 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1256 (match_operand:SWI48 1 "<general_operand>")))])
1258 (define_insn "*cmp<mode>_ccno_1"
1259 [(set (reg FLAGS_REG)
1260 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1261 (match_operand:SWI 1 "const0_operand")))]
1262 "ix86_match_ccmode (insn, CCNOmode)"
1264 test{<imodesuffix>}\t%0, %0
1265 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1266 [(set_attr "type" "test,icmp")
1267 (set_attr "length_immediate" "0,1")
1268 (set_attr "modrm_class" "op0,unknown")
1269 (set_attr "mode" "<MODE>")])
1271 (define_insn "*cmp<mode>_1"
1272 [(set (reg FLAGS_REG)
1273 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1274 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1275 "ix86_match_ccmode (insn, CCmode)"
1276 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1277 [(set_attr "type" "icmp")
1278 (set_attr "mode" "<MODE>")])
1280 (define_insn "*cmp<mode>_minus_1"
1281 [(set (reg FLAGS_REG)
1283 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1284 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1286 "ix86_match_ccmode (insn, CCGOCmode)"
1287 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1288 [(set_attr "type" "icmp")
1289 (set_attr "mode" "<MODE>")])
1291 (define_insn "*cmpqi_ext_1"
1292 [(set (reg FLAGS_REG)
1294 (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1297 (match_operand 1 "ext_register_operand" "Q,Q")
1299 (const_int 8)) 0)))]
1300 "ix86_match_ccmode (insn, CCmode)"
1301 "cmp{b}\t{%h1, %0|%0, %h1}"
1302 [(set_attr "isa" "*,nox64")
1303 (set_attr "type" "icmp")
1304 (set_attr "mode" "QI")])
1306 (define_insn "*cmpqi_ext_2"
1307 [(set (reg FLAGS_REG)
1311 (match_operand 0 "ext_register_operand" "Q")
1314 (match_operand:QI 1 "const0_operand")))]
1315 "ix86_match_ccmode (insn, CCNOmode)"
1317 [(set_attr "type" "test")
1318 (set_attr "length_immediate" "0")
1319 (set_attr "mode" "QI")])
1321 (define_expand "cmpqi_ext_3"
1322 [(set (reg:CC FLAGS_REG)
1326 (match_operand 0 "ext_register_operand")
1329 (match_operand:QI 1 "const_int_operand")))])
1331 (define_insn "*cmpqi_ext_3"
1332 [(set (reg FLAGS_REG)
1336 (match_operand 0 "ext_register_operand" "Q,Q")
1339 (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1340 "ix86_match_ccmode (insn, CCmode)"
1341 "cmp{b}\t{%1, %h0|%h0, %1}"
1342 [(set_attr "isa" "*,nox64")
1343 (set_attr "type" "icmp")
1344 (set_attr "modrm" "1")
1345 (set_attr "mode" "QI")])
1347 (define_insn "*cmpqi_ext_4"
1348 [(set (reg FLAGS_REG)
1352 (match_operand 0 "ext_register_operand" "Q")
1357 (match_operand 1 "ext_register_operand" "Q")
1359 (const_int 8)) 0)))]
1360 "ix86_match_ccmode (insn, CCmode)"
1361 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1362 [(set_attr "type" "icmp")
1363 (set_attr "mode" "QI")])
1365 ;; These implement float point compares.
1366 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1367 ;; which would allow mix and match FP modes on the compares. Which is what
1368 ;; the old patterns did, but with many more of them.
1370 (define_expand "cbranchxf4"
1371 [(set (reg:CC FLAGS_REG)
1372 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1373 (match_operand:XF 2 "nonmemory_operand")))
1374 (set (pc) (if_then_else
1375 (match_operator 0 "ix86_fp_comparison_operator"
1378 (label_ref (match_operand 3))
1382 ix86_expand_branch (GET_CODE (operands[0]),
1383 operands[1], operands[2], operands[3]);
1387 (define_expand "cstorexf4"
1388 [(set (reg:CC FLAGS_REG)
1389 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1390 (match_operand:XF 3 "nonmemory_operand")))
1391 (set (match_operand:QI 0 "register_operand")
1392 (match_operator 1 "ix86_fp_comparison_operator"
1397 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1398 operands[2], operands[3]);
1402 (define_expand "cbranch<mode>4"
1403 [(set (reg:CC FLAGS_REG)
1404 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1405 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1406 (set (pc) (if_then_else
1407 (match_operator 0 "ix86_fp_comparison_operator"
1410 (label_ref (match_operand 3))
1412 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1414 ix86_expand_branch (GET_CODE (operands[0]),
1415 operands[1], operands[2], operands[3]);
1419 (define_expand "cstore<mode>4"
1420 [(set (reg:CC FLAGS_REG)
1421 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1422 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1423 (set (match_operand:QI 0 "register_operand")
1424 (match_operator 1 "ix86_fp_comparison_operator"
1427 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1429 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1430 operands[2], operands[3]);
1434 (define_expand "cbranchcc4"
1435 [(set (pc) (if_then_else
1436 (match_operator 0 "comparison_operator"
1437 [(match_operand 1 "flags_reg_operand")
1438 (match_operand 2 "const0_operand")])
1439 (label_ref (match_operand 3))
1443 ix86_expand_branch (GET_CODE (operands[0]),
1444 operands[1], operands[2], operands[3]);
1448 (define_expand "cstorecc4"
1449 [(set (match_operand:QI 0 "register_operand")
1450 (match_operator 1 "comparison_operator"
1451 [(match_operand 2 "flags_reg_operand")
1452 (match_operand 3 "const0_operand")]))]
1455 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1456 operands[2], operands[3]);
1461 ;; FP compares, step 1:
1462 ;; Set the FP condition codes.
1464 ;; CCFPmode compare with exceptions
1465 ;; CCFPUmode compare with no exceptions
1467 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1468 ;; used to manage the reg stack popping would not be preserved.
1470 (define_insn "*cmp<mode>_0_i387"
1471 [(set (match_operand:HI 0 "register_operand" "=a")
1474 (match_operand:X87MODEF 1 "register_operand" "f")
1475 (match_operand:X87MODEF 2 "const0_operand"))]
1478 "* return output_fp_compare (insn, operands, false, false);"
1479 [(set_attr "type" "multi")
1480 (set_attr "unit" "i387")
1481 (set_attr "mode" "<MODE>")])
1483 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1484 [(set (reg:CCFP FLAGS_REG)
1486 (match_operand:X87MODEF 1 "register_operand" "f")
1487 (match_operand:X87MODEF 2 "const0_operand")))
1488 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1489 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1491 "&& reload_completed"
1494 [(compare:CCFP (match_dup 1)(match_dup 2))]
1496 (set (reg:CC FLAGS_REG)
1497 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1499 [(set_attr "type" "multi")
1500 (set_attr "unit" "i387")
1501 (set_attr "mode" "<MODE>")])
1503 (define_insn "*cmpxf_i387"
1504 [(set (match_operand:HI 0 "register_operand" "=a")
1507 (match_operand:XF 1 "register_operand" "f")
1508 (match_operand:XF 2 "register_operand" "f"))]
1511 "* return output_fp_compare (insn, operands, false, false);"
1512 [(set_attr "type" "multi")
1513 (set_attr "unit" "i387")
1514 (set_attr "mode" "XF")])
1516 (define_insn_and_split "*cmpxf_cc_i387"
1517 [(set (reg:CCFP FLAGS_REG)
1519 (match_operand:XF 1 "register_operand" "f")
1520 (match_operand:XF 2 "register_operand" "f")))
1521 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1522 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1524 "&& reload_completed"
1527 [(compare:CCFP (match_dup 1)(match_dup 2))]
1529 (set (reg:CC FLAGS_REG)
1530 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1532 [(set_attr "type" "multi")
1533 (set_attr "unit" "i387")
1534 (set_attr "mode" "XF")])
1536 (define_insn "*cmp<mode>_i387"
1537 [(set (match_operand:HI 0 "register_operand" "=a")
1540 (match_operand:MODEF 1 "register_operand" "f")
1541 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1544 "* return output_fp_compare (insn, operands, false, false);"
1545 [(set_attr "type" "multi")
1546 (set_attr "unit" "i387")
1547 (set_attr "mode" "<MODE>")])
1549 (define_insn_and_split "*cmp<mode>_cc_i387"
1550 [(set (reg:CCFP FLAGS_REG)
1552 (match_operand:MODEF 1 "register_operand" "f")
1553 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1554 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1555 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1557 "&& reload_completed"
1560 [(compare:CCFP (match_dup 1)(match_dup 2))]
1562 (set (reg:CC FLAGS_REG)
1563 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1565 [(set_attr "type" "multi")
1566 (set_attr "unit" "i387")
1567 (set_attr "mode" "<MODE>")])
1569 (define_insn "*cmpu<mode>_i387"
1570 [(set (match_operand:HI 0 "register_operand" "=a")
1573 (match_operand:X87MODEF 1 "register_operand" "f")
1574 (match_operand:X87MODEF 2 "register_operand" "f"))]
1577 "* return output_fp_compare (insn, operands, false, true);"
1578 [(set_attr "type" "multi")
1579 (set_attr "unit" "i387")
1580 (set_attr "mode" "<MODE>")])
1582 (define_insn_and_split "*cmpu<mode>_cc_i387"
1583 [(set (reg:CCFPU FLAGS_REG)
1585 (match_operand:X87MODEF 1 "register_operand" "f")
1586 (match_operand:X87MODEF 2 "register_operand" "f")))
1587 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1588 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1590 "&& reload_completed"
1593 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1595 (set (reg:CC FLAGS_REG)
1596 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1598 [(set_attr "type" "multi")
1599 (set_attr "unit" "i387")
1600 (set_attr "mode" "<MODE>")])
1602 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1603 [(set (match_operand:HI 0 "register_operand" "=a")
1606 (match_operand:X87MODEF 1 "register_operand" "f")
1607 (match_operator:X87MODEF 3 "float_operator"
1608 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1611 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1612 || optimize_function_for_size_p (cfun))"
1613 "* return output_fp_compare (insn, operands, false, false);"
1614 [(set_attr "type" "multi")
1615 (set_attr "unit" "i387")
1616 (set_attr "fp_int_src" "true")
1617 (set_attr "mode" "<SWI24:MODE>")])
1619 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1620 [(set (reg:CCFP FLAGS_REG)
1622 (match_operand:X87MODEF 1 "register_operand" "f")
1623 (match_operator:X87MODEF 3 "float_operator"
1624 [(match_operand:SWI24 2 "memory_operand" "m")])))
1625 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1626 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1627 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1628 || optimize_function_for_size_p (cfun))"
1630 "&& reload_completed"
1635 (match_op_dup 3 [(match_dup 2)]))]
1637 (set (reg:CC FLAGS_REG)
1638 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1640 [(set_attr "type" "multi")
1641 (set_attr "unit" "i387")
1642 (set_attr "fp_int_src" "true")
1643 (set_attr "mode" "<SWI24:MODE>")])
1645 ;; FP compares, step 2
1646 ;; Move the fpsw to ax.
1648 (define_insn "x86_fnstsw_1"
1649 [(set (match_operand:HI 0 "register_operand" "=a")
1650 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1653 [(set_attr "length" "2")
1654 (set_attr "mode" "SI")
1655 (set_attr "unit" "i387")])
1657 ;; FP compares, step 3
1658 ;; Get ax into flags, general case.
1660 (define_insn "x86_sahf_1"
1661 [(set (reg:CC FLAGS_REG)
1662 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1666 #ifndef HAVE_AS_IX86_SAHF
1668 return ASM_BYTE "0x9e";
1673 [(set_attr "length" "1")
1674 (set_attr "athlon_decode" "vector")
1675 (set_attr "amdfam10_decode" "direct")
1676 (set_attr "bdver1_decode" "direct")
1677 (set_attr "mode" "SI")])
1679 ;; Pentium Pro can do steps 1 through 3 in one go.
1680 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1681 ;; (these i387 instructions set flags directly)
1683 (define_mode_iterator FPCMP [CCFP CCFPU])
1684 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1686 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1687 [(set (reg:FPCMP FLAGS_REG)
1689 (match_operand:MODEF 0 "register_operand" "f,v")
1690 (match_operand:MODEF 1 "nonimmediate_operand" "f,vm")))]
1691 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
1692 "* return output_fp_compare (insn, operands, true,
1693 <FPCMP:MODE>mode == CCFPUmode);"
1694 [(set_attr "type" "fcmp,ssecomi")
1695 (set_attr "prefix" "orig,maybe_vex")
1696 (set_attr "mode" "<MODEF:MODE>")
1697 (set_attr "prefix_rep" "*,0")
1698 (set (attr "prefix_data16")
1699 (cond [(eq_attr "alternative" "0")
1701 (eq_attr "mode" "DF")
1704 (const_string "0")))
1705 (set_attr "athlon_decode" "vector")
1706 (set_attr "amdfam10_decode" "direct")
1707 (set_attr "bdver1_decode" "double")
1708 (set_attr "znver1_decode" "double")
1709 (set (attr "enabled")
1710 (cond [(eq_attr "alternative" "0")
1711 (symbol_ref "TARGET_MIX_SSE_I387")
1713 (symbol_ref "true")))])
1715 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1716 [(set (reg:FPCMP FLAGS_REG)
1718 (match_operand:X87MODEF 0 "register_operand" "f")
1719 (match_operand:X87MODEF 1 "register_operand" "f")))]
1720 "TARGET_80387 && TARGET_CMOVE
1721 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1722 "* return output_fp_compare (insn, operands, true,
1723 <FPCMP:MODE>mode == CCFPUmode);"
1724 [(set_attr "type" "fcmp")
1725 (set_attr "mode" "<X87MODEF:MODE>")
1726 (set_attr "athlon_decode" "vector")
1727 (set_attr "amdfam10_decode" "direct")
1728 (set_attr "bdver1_decode" "double")
1729 (set_attr "znver1_decode" "double")])
1731 ;; Push/pop instructions.
1733 (define_insn "*push<mode>2"
1734 [(set (match_operand:DWI 0 "push_operand" "=<")
1735 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1738 [(set_attr "type" "multi")
1739 (set_attr "mode" "<MODE>")])
1742 [(set (match_operand:TI 0 "push_operand")
1743 (match_operand:TI 1 "general_operand"))]
1744 "TARGET_64BIT && reload_completed
1745 && !SSE_REG_P (operands[1])"
1747 "ix86_split_long_move (operands); DONE;")
1749 (define_insn "*pushdi2_rex64"
1750 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1751 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1756 [(set_attr "type" "push,multi")
1757 (set_attr "mode" "DI")])
1759 ;; Convert impossible pushes of immediate to existing instructions.
1760 ;; First try to get scratch register and go through it. In case this
1761 ;; fails, push sign extended lower part first and then overwrite
1762 ;; upper part by 32bit move.
1764 [(match_scratch:DI 2 "r")
1765 (set (match_operand:DI 0 "push_operand")
1766 (match_operand:DI 1 "immediate_operand"))]
1767 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1768 && !x86_64_immediate_operand (operands[1], DImode)"
1769 [(set (match_dup 2) (match_dup 1))
1770 (set (match_dup 0) (match_dup 2))])
1772 ;; We need to define this as both peepholer and splitter for case
1773 ;; peephole2 pass is not run.
1774 ;; "&& 1" is needed to keep it from matching the previous pattern.
1776 [(set (match_operand:DI 0 "push_operand")
1777 (match_operand:DI 1 "immediate_operand"))]
1778 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1779 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1780 [(set (match_dup 0) (match_dup 1))
1781 (set (match_dup 2) (match_dup 3))]
1783 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1785 operands[1] = gen_lowpart (DImode, operands[2]);
1786 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1791 [(set (match_operand:DI 0 "push_operand")
1792 (match_operand:DI 1 "immediate_operand"))]
1793 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1794 ? epilogue_completed : reload_completed)
1795 && !symbolic_operand (operands[1], DImode)
1796 && !x86_64_immediate_operand (operands[1], DImode)"
1797 [(set (match_dup 0) (match_dup 1))
1798 (set (match_dup 2) (match_dup 3))]
1800 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1802 operands[1] = gen_lowpart (DImode, operands[2]);
1803 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1808 [(set (match_operand:DI 0 "push_operand")
1809 (match_operand:DI 1 "general_operand"))]
1810 "!TARGET_64BIT && reload_completed
1811 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1813 "ix86_split_long_move (operands); DONE;")
1815 (define_insn "*pushsi2"
1816 [(set (match_operand:SI 0 "push_operand" "=<")
1817 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1820 [(set_attr "type" "push")
1821 (set_attr "mode" "SI")])
1823 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1824 ;; "push a byte/word". But actually we use pushl, which has the effect
1825 ;; of rounding the amount pushed up to a word.
1827 ;; For TARGET_64BIT we always round up to 8 bytes.
1828 (define_insn "*push<mode>2_rex64"
1829 [(set (match_operand:SWI124 0 "push_operand" "=X")
1830 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1833 [(set_attr "type" "push")
1834 (set_attr "mode" "DI")])
1836 (define_insn "*push<mode>2"
1837 [(set (match_operand:SWI12 0 "push_operand" "=X")
1838 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1841 [(set_attr "type" "push")
1842 (set_attr "mode" "SI")])
1844 (define_insn "*push<mode>2_prologue"
1845 [(set (match_operand:W 0 "push_operand" "=<")
1846 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1847 (clobber (mem:BLK (scratch)))]
1849 "push{<imodesuffix>}\t%1"
1850 [(set_attr "type" "push")
1851 (set_attr "mode" "<MODE>")])
1853 (define_insn "*pop<mode>1"
1854 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1855 (match_operand:W 1 "pop_operand" ">"))]
1857 "pop{<imodesuffix>}\t%0"
1858 [(set_attr "type" "pop")
1859 (set_attr "mode" "<MODE>")])
1861 (define_insn "*pop<mode>1_epilogue"
1862 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1863 (match_operand:W 1 "pop_operand" ">"))
1864 (clobber (mem:BLK (scratch)))]
1866 "pop{<imodesuffix>}\t%0"
1867 [(set_attr "type" "pop")
1868 (set_attr "mode" "<MODE>")])
1870 (define_insn "*pushfl<mode>2"
1871 [(set (match_operand:W 0 "push_operand" "=<")
1872 (match_operand:W 1 "flags_reg_operand"))]
1874 "pushf{<imodesuffix>}"
1875 [(set_attr "type" "push")
1876 (set_attr "mode" "<MODE>")])
1878 (define_insn "*popfl<mode>1"
1879 [(set (match_operand:W 0 "flags_reg_operand")
1880 (match_operand:W 1 "pop_operand" ">"))]
1882 "popf{<imodesuffix>}"
1883 [(set_attr "type" "pop")
1884 (set_attr "mode" "<MODE>")])
1887 ;; Reload patterns to support multi-word load/store
1888 ;; with non-offsetable address.
1889 (define_expand "reload_noff_store"
1890 [(parallel [(match_operand 0 "memory_operand" "=m")
1891 (match_operand 1 "register_operand" "r")
1892 (match_operand:DI 2 "register_operand" "=&r")])]
1895 rtx mem = operands[0];
1896 rtx addr = XEXP (mem, 0);
1898 emit_move_insn (operands[2], addr);
1899 mem = replace_equiv_address_nv (mem, operands[2]);
1901 emit_insn (gen_rtx_SET (mem, operands[1]));
1905 (define_expand "reload_noff_load"
1906 [(parallel [(match_operand 0 "register_operand" "=r")
1907 (match_operand 1 "memory_operand" "m")
1908 (match_operand:DI 2 "register_operand" "=r")])]
1911 rtx mem = operands[1];
1912 rtx addr = XEXP (mem, 0);
1914 emit_move_insn (operands[2], addr);
1915 mem = replace_equiv_address_nv (mem, operands[2]);
1917 emit_insn (gen_rtx_SET (operands[0], mem));
1921 ;; Move instructions.
1923 (define_expand "movxi"
1924 [(set (match_operand:XI 0 "nonimmediate_operand")
1925 (match_operand:XI 1 "general_operand"))]
1927 "ix86_expand_vector_move (XImode, operands); DONE;")
1929 (define_expand "movoi"
1930 [(set (match_operand:OI 0 "nonimmediate_operand")
1931 (match_operand:OI 1 "general_operand"))]
1933 "ix86_expand_vector_move (OImode, operands); DONE;")
1935 (define_expand "movti"
1936 [(set (match_operand:TI 0 "nonimmediate_operand")
1937 (match_operand:TI 1 "general_operand"))]
1938 "TARGET_64BIT || TARGET_SSE"
1941 ix86_expand_move (TImode, operands);
1943 ix86_expand_vector_move (TImode, operands);
1947 ;; This expands to what emit_move_complex would generate if we didn't
1948 ;; have a movti pattern. Having this avoids problems with reload on
1949 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1950 ;; to have around all the time.
1951 (define_expand "movcdi"
1952 [(set (match_operand:CDI 0 "nonimmediate_operand")
1953 (match_operand:CDI 1 "general_operand"))]
1956 if (push_operand (operands[0], CDImode))
1957 emit_move_complex_push (CDImode, operands[0], operands[1]);
1959 emit_move_complex_parts (operands[0], operands[1]);
1963 (define_expand "mov<mode>"
1964 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1965 (match_operand:SWI1248x 1 "general_operand"))]
1967 "ix86_expand_move (<MODE>mode, operands); DONE;")
1969 (define_insn "*mov<mode>_xor"
1970 [(set (match_operand:SWI48 0 "register_operand" "=r")
1971 (match_operand:SWI48 1 "const0_operand"))
1972 (clobber (reg:CC FLAGS_REG))]
1975 [(set_attr "type" "alu1")
1976 (set_attr "modrm_class" "op0")
1977 (set_attr "mode" "SI")
1978 (set_attr "length_immediate" "0")])
1980 (define_insn "*mov<mode>_or"
1981 [(set (match_operand:SWI48 0 "register_operand" "=r")
1982 (match_operand:SWI48 1 "const_int_operand"))
1983 (clobber (reg:CC FLAGS_REG))]
1985 && operands[1] == constm1_rtx"
1986 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1987 [(set_attr "type" "alu1")
1988 (set_attr "mode" "<MODE>")
1989 (set_attr "length_immediate" "1")])
1991 (define_insn "*movxi_internal_avx512f"
1992 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,m")
1993 (match_operand:XI 1 "vector_move_operand" "C ,vm,v"))]
1994 "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1996 switch (which_alternative)
1999 return standard_sse_constant_opcode (insn, operands[1]);
2002 if (misaligned_operand (operands[0], XImode)
2003 || misaligned_operand (operands[1], XImode))
2004 return "vmovdqu32\t{%1, %0|%0, %1}";
2006 return "vmovdqa32\t{%1, %0|%0, %1}";
2011 [(set_attr "type" "sselog1,ssemov,ssemov")
2012 (set_attr "prefix" "evex")
2013 (set_attr "mode" "XI")])
2015 (define_insn "*movoi_internal_avx"
2016 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,m")
2017 (match_operand:OI 1 "vector_move_operand" "C ,vm,v"))]
2018 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2020 switch (get_attr_type (insn))
2023 return standard_sse_constant_opcode (insn, operands[1]);
2026 if (misaligned_operand (operands[0], OImode)
2027 || misaligned_operand (operands[1], OImode))
2029 if (get_attr_mode (insn) == MODE_V8SF)
2030 return "vmovups\t{%1, %0|%0, %1}";
2031 else if (get_attr_mode (insn) == MODE_XI)
2032 return "vmovdqu32\t{%1, %0|%0, %1}";
2034 return "vmovdqu\t{%1, %0|%0, %1}";
2038 if (get_attr_mode (insn) == MODE_V8SF)
2039 return "vmovaps\t{%1, %0|%0, %1}";
2040 else if (get_attr_mode (insn) == MODE_XI)
2041 return "vmovdqa32\t{%1, %0|%0, %1}";
2043 return "vmovdqa\t{%1, %0|%0, %1}";
2050 [(set_attr "type" "sselog1,ssemov,ssemov")
2051 (set_attr "prefix" "vex")
2053 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2054 (match_operand 1 "ext_sse_reg_operand"))
2056 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2057 (const_string "V8SF")
2058 (and (eq_attr "alternative" "2")
2059 (match_test "TARGET_SSE_TYPELESS_STORES"))
2060 (const_string "V8SF")
2062 (const_string "OI")))])
2064 (define_insn "*movti_internal"
2065 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,m")
2066 (match_operand:TI 1 "general_operand" "riFo,re,C,vm,v"))]
2067 "(TARGET_64BIT || TARGET_SSE)
2068 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2070 switch (get_attr_type (insn))
2076 return standard_sse_constant_opcode (insn, operands[1]);
2079 /* TDmode values are passed as TImode on the stack. Moving them
2080 to stack may result in unaligned memory access. */
2081 if (misaligned_operand (operands[0], TImode)
2082 || misaligned_operand (operands[1], TImode))
2084 if (get_attr_mode (insn) == MODE_V4SF)
2085 return "%vmovups\t{%1, %0|%0, %1}";
2086 else if (get_attr_mode (insn) == MODE_XI)
2087 return "vmovdqu32\t{%1, %0|%0, %1}";
2089 return "%vmovdqu\t{%1, %0|%0, %1}";
2093 if (get_attr_mode (insn) == MODE_V4SF)
2094 return "%vmovaps\t{%1, %0|%0, %1}";
2095 else if (get_attr_mode (insn) == MODE_XI)
2096 return "vmovdqa32\t{%1, %0|%0, %1}";
2098 return "%vmovdqa\t{%1, %0|%0, %1}";
2105 [(set_attr "isa" "x64,x64,*,*,*")
2106 (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
2107 (set (attr "prefix")
2108 (if_then_else (eq_attr "type" "sselog1,ssemov")
2109 (const_string "maybe_vex")
2110 (const_string "orig")))
2112 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2113 (match_operand 1 "ext_sse_reg_operand"))
2115 (eq_attr "alternative" "0,1")
2117 (ior (not (match_test "TARGET_SSE2"))
2118 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2119 (const_string "V4SF")
2120 (and (eq_attr "alternative" "4")
2121 (match_test "TARGET_SSE_TYPELESS_STORES"))
2122 (const_string "V4SF")
2123 (match_test "TARGET_AVX")
2125 (match_test "optimize_function_for_size_p (cfun)")
2126 (const_string "V4SF")
2128 (const_string "TI")))])
2131 [(set (match_operand:TI 0 "nonimmediate_operand")
2132 (match_operand:TI 1 "general_operand"))]
2134 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2136 "ix86_split_long_move (operands); DONE;")
2138 (define_insn "*movdi_internal"
2139 [(set (match_operand:DI 0 "nonimmediate_operand"
2140 "=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")
2141 (match_operand:DI 1 "general_operand"
2142 "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"))]
2143 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2145 switch (get_attr_type (insn))
2148 return "kmovq\t{%1, %0|%0, %1}";
2154 return "pxor\t%0, %0";
2157 /* Handle broken assemblers that require movd instead of movq. */
2158 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2159 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2160 return "movd\t{%1, %0|%0, %1}";
2161 return "movq\t{%1, %0|%0, %1}";
2164 if (GENERAL_REG_P (operands[0]))
2165 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2167 return standard_sse_constant_opcode (insn, operands[1]);
2170 switch (get_attr_mode (insn))
2173 /* Handle broken assemblers that require movd instead of movq. */
2174 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2175 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2176 return "%vmovd\t{%1, %0|%0, %1}";
2177 return "%vmovq\t{%1, %0|%0, %1}";
2179 return "%vmovdqa\t{%1, %0|%0, %1}";
2181 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2184 gcc_assert (!TARGET_AVX);
2185 return "movlps\t{%1, %0|%0, %1}";
2187 return "%vmovaps\t{%1, %0|%0, %1}";
2194 if (SSE_REG_P (operands[0]))
2195 return "movq2dq\t{%1, %0|%0, %1}";
2197 return "movdq2q\t{%1, %0|%0, %1}";
2200 return "lea{q}\t{%E1, %0|%0, %E1}";
2203 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2204 if (get_attr_mode (insn) == MODE_SI)
2205 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2206 else if (which_alternative == 4)
2207 return "movabs{q}\t{%1, %0|%0, %1}";
2208 else if (ix86_use_lea_for_mov (insn, operands))
2209 return "lea{q}\t{%E1, %0|%0, %E1}";
2211 return "mov{q}\t{%1, %0|%0, %1}";
2218 (cond [(eq_attr "alternative" "0,1")
2219 (const_string "nox64")
2220 (eq_attr "alternative" "2,3,4,5,10,11,17,19,22,24")
2221 (const_string "x64")
2222 (eq_attr "alternative" "18")
2223 (const_string "x64_sse4")
2225 (const_string "*")))
2227 (cond [(eq_attr "alternative" "0,1")
2228 (const_string "multi")
2229 (eq_attr "alternative" "6")
2230 (const_string "mmx")
2231 (eq_attr "alternative" "7,8,9,10,11")
2232 (const_string "mmxmov")
2233 (eq_attr "alternative" "12,18")
2234 (const_string "sselog1")
2235 (eq_attr "alternative" "13,14,15,16,17,19")
2236 (const_string "ssemov")
2237 (eq_attr "alternative" "20,21")
2238 (const_string "ssecvt")
2239 (eq_attr "alternative" "22,23,24,25")
2240 (const_string "mskmov")
2241 (and (match_operand 0 "register_operand")
2242 (match_operand 1 "pic_32bit_operand"))
2243 (const_string "lea")
2245 (const_string "imov")))
2248 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2250 (const_string "*")))
2251 (set (attr "length_immediate")
2252 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2254 (eq_attr "alternative" "18")
2257 (const_string "*")))
2258 (set (attr "prefix_rex")
2259 (if_then_else (eq_attr "alternative" "10,11,17,18,19")
2261 (const_string "*")))
2262 (set (attr "prefix_extra")
2263 (if_then_else (eq_attr "alternative" "18")
2265 (const_string "*")))
2266 (set (attr "prefix")
2267 (if_then_else (eq_attr "type" "sselog1,ssemov")
2268 (const_string "maybe_vex")
2269 (const_string "orig")))
2270 (set (attr "prefix_data16")
2271 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2273 (const_string "*")))
2275 (cond [(eq_attr "alternative" "2")
2277 (eq_attr "alternative" "12,13")
2278 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2279 (match_operand 1 "ext_sse_reg_operand"))
2281 (ior (not (match_test "TARGET_SSE2"))
2282 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2283 (const_string "V4SF")
2284 (match_test "TARGET_AVX")
2286 (match_test "optimize_function_for_size_p (cfun)")
2287 (const_string "V4SF")
2289 (const_string "TI"))
2291 (and (eq_attr "alternative" "14,15,16")
2292 (not (match_test "TARGET_SSE2")))
2293 (const_string "V2SF")
2294 (eq_attr "alternative" "18")
2297 (const_string "DI")))
2298 (set (attr "enabled")
2299 (cond [(eq_attr "alternative" "15")
2301 (match_test "TARGET_STV && TARGET_SSE2")
2302 (symbol_ref "false")
2304 (eq_attr "alternative" "16")
2306 (match_test "TARGET_STV && TARGET_SSE2")
2308 (symbol_ref "false"))
2310 (const_string "*")))])
2313 [(set (match_operand:DI 0 "nonimmediate_operand")
2314 (match_operand:DI 1 "general_operand"))]
2315 "!TARGET_64BIT && reload_completed
2316 && !(MMX_REG_P (operands[0])
2317 || SSE_REG_P (operands[0])
2318 || MASK_REG_P (operands[0]))
2319 && !(MMX_REG_P (operands[1])
2320 || SSE_REG_P (operands[1])
2321 || MASK_REG_P (operands[1]))"
2323 "ix86_split_long_move (operands); DONE;")
2325 (define_insn "*movsi_internal"
2326 [(set (match_operand:SI 0 "nonimmediate_operand"
2327 "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k ,*rm")
2328 (match_operand:SI 1 "general_operand"
2329 "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r ,*krm,*k"))]
2330 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2332 switch (get_attr_type (insn))
2335 if (GENERAL_REG_P (operands[0]))
2336 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2338 return standard_sse_constant_opcode (insn, operands[1]);
2341 return "kmovd\t{%1, %0|%0, %1}";
2344 switch (get_attr_mode (insn))
2347 return "%vmovd\t{%1, %0|%0, %1}";
2349 return "%vmovdqa\t{%1, %0|%0, %1}";
2351 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2354 return "%vmovaps\t{%1, %0|%0, %1}";
2357 gcc_assert (!TARGET_AVX);
2358 return "movss\t{%1, %0|%0, %1}";
2365 return "pxor\t%0, %0";
2368 switch (get_attr_mode (insn))
2371 return "movq\t{%1, %0|%0, %1}";
2373 return "movd\t{%1, %0|%0, %1}";
2380 return "lea{l}\t{%E1, %0|%0, %E1}";
2383 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2384 if (ix86_use_lea_for_mov (insn, operands))
2385 return "lea{l}\t{%E1, %0|%0, %E1}";
2387 return "mov{l}\t{%1, %0|%0, %1}";
2394 (if_then_else (eq_attr "alternative" "11")
2395 (const_string "sse4")
2396 (const_string "*")))
2398 (cond [(eq_attr "alternative" "2")
2399 (const_string "mmx")
2400 (eq_attr "alternative" "3,4,5")
2401 (const_string "mmxmov")
2402 (eq_attr "alternative" "6,11")
2403 (const_string "sselog1")
2404 (eq_attr "alternative" "7,8,9,10,12")
2405 (const_string "ssemov")
2406 (eq_attr "alternative" "13,14")
2407 (const_string "mskmov")
2408 (and (match_operand 0 "register_operand")
2409 (match_operand 1 "pic_32bit_operand"))
2410 (const_string "lea")
2412 (const_string "imov")))
2413 (set (attr "length_immediate")
2414 (if_then_else (eq_attr "alternative" "11")
2416 (const_string "*")))
2417 (set (attr "prefix_extra")
2418 (if_then_else (eq_attr "alternative" "11")
2420 (const_string "*")))
2421 (set (attr "prefix")
2422 (if_then_else (eq_attr "type" "sselog1,ssemov")
2423 (const_string "maybe_vex")
2424 (const_string "orig")))
2425 (set (attr "prefix_data16")
2426 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2428 (const_string "*")))
2430 (cond [(eq_attr "alternative" "2,3")
2432 (eq_attr "alternative" "6,7")
2433 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2434 (match_operand 1 "ext_sse_reg_operand"))
2436 (ior (not (match_test "TARGET_SSE2"))
2437 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2438 (const_string "V4SF")
2439 (match_test "TARGET_AVX")
2441 (match_test "optimize_function_for_size_p (cfun)")
2442 (const_string "V4SF")
2444 (const_string "TI"))
2446 (and (eq_attr "alternative" "8,9")
2447 (not (match_test "TARGET_SSE2")))
2449 (eq_attr "alternative" "11")
2452 (const_string "SI")))])
2454 (define_insn "kmovw"
2455 [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2457 [(match_operand:HI 1 "nonimmediate_operand" "r,km")]
2459 "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2461 kmovw\t{%k1, %0|%0, %k1}
2462 kmovw\t{%1, %0|%0, %1}";
2463 [(set_attr "mode" "HI")
2464 (set_attr "type" "mskmov")
2465 (set_attr "prefix" "vex")])
2468 (define_insn "*movhi_internal"
2469 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k, r,m")
2470 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,r,km,k,k"))]
2471 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2473 switch (get_attr_type (insn))
2476 /* movzwl is faster than movw on p2 due to partial word stalls,
2477 though not as fast as an aligned movl. */
2478 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2481 switch (which_alternative)
2483 case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2484 case 5: /* FALLTHRU */
2485 case 7: return "kmovw\t{%1, %0|%0, %1}";
2486 case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2487 default: gcc_unreachable ();
2491 if (get_attr_mode (insn) == MODE_SI)
2492 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2494 return "mov{w}\t{%1, %0|%0, %1}";
2498 (cond [(eq_attr "alternative" "4,5,6,7")
2499 (const_string "mskmov")
2500 (match_test "optimize_function_for_size_p (cfun)")
2501 (const_string "imov")
2502 (and (eq_attr "alternative" "0")
2503 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2504 (not (match_test "TARGET_HIMODE_MATH"))))
2505 (const_string "imov")
2506 (and (eq_attr "alternative" "1,2")
2507 (match_operand:HI 1 "aligned_operand"))
2508 (const_string "imov")
2509 (and (match_test "TARGET_MOVX")
2510 (eq_attr "alternative" "0,2"))
2511 (const_string "imovx")
2513 (const_string "imov")))
2514 (set (attr "prefix")
2515 (if_then_else (eq_attr "alternative" "4,5,6,7")
2516 (const_string "vex")
2517 (const_string "orig")))
2519 (cond [(eq_attr "type" "imovx")
2521 (and (eq_attr "alternative" "1,2")
2522 (match_operand:HI 1 "aligned_operand"))
2524 (and (eq_attr "alternative" "0")
2525 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2526 (not (match_test "TARGET_HIMODE_MATH"))))
2529 (const_string "HI")))])
2531 ;; Situation is quite tricky about when to choose full sized (SImode) move
2532 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2533 ;; partial register dependency machines (such as AMD Athlon), where QImode
2534 ;; moves issue extra dependency and for partial register stalls machines
2535 ;; that don't use QImode patterns (and QImode move cause stall on the next
2538 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2539 ;; register stall machines with, where we use QImode instructions, since
2540 ;; partial register stall can be caused there. Then we use movzx.
2542 (define_insn "*movqi_internal"
2543 [(set (match_operand:QI 0 "nonimmediate_operand"
2544 "=q,q ,q ,r,r ,?r,m ,k,k,r ,m,k")
2545 (match_operand:QI 1 "general_operand"
2546 "q ,qn,qm,q,rn,qm,qn,r ,k,k,k,m"))]
2547 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2549 switch (get_attr_type (insn))
2552 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2553 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2556 switch (which_alternative)
2558 case 7: return TARGET_AVX512DQ ? "kmovb\t{%k1, %0|%0, %k1}"
2559 : "kmovw\t{%k1, %0|%0, %k1}";
2560 case 8: return TARGET_AVX512DQ ? "kmovb\t{%1, %0|%0, %1}"
2561 : "kmovw\t{%1, %0|%0, %1}";
2562 case 9: return TARGET_AVX512DQ ? "kmovb\t{%1, %k0|%k0, %1}"
2563 : "kmovw\t{%1, %k0|%k0, %1}";
2566 gcc_assert (TARGET_AVX512DQ);
2567 return "kmovb\t{%1, %0|%0, %1}";
2568 default: gcc_unreachable ();
2572 if (get_attr_mode (insn) == MODE_SI)
2573 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2575 return "mov{b}\t{%1, %0|%0, %1}";
2578 [(set_attr "isa" "*,*,*,*,*,*,*,*,*,*,avx512dq,avx512dq")
2580 (cond [(eq_attr "alternative" "7,8,9,10,11")
2581 (const_string "mskmov")
2582 (and (eq_attr "alternative" "5")
2583 (not (match_operand:QI 1 "aligned_operand")))
2584 (const_string "imovx")
2585 (match_test "optimize_function_for_size_p (cfun)")
2586 (const_string "imov")
2587 (and (eq_attr "alternative" "3")
2588 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2589 (not (match_test "TARGET_QIMODE_MATH"))))
2590 (const_string "imov")
2591 (eq_attr "alternative" "3,5")
2592 (const_string "imovx")
2593 (and (match_test "TARGET_MOVX")
2594 (eq_attr "alternative" "2"))
2595 (const_string "imovx")
2597 (const_string "imov")))
2598 (set (attr "prefix")
2599 (if_then_else (eq_attr "alternative" "7,8,9")
2600 (const_string "vex")
2601 (const_string "orig")))
2603 (cond [(eq_attr "alternative" "3,4,5")
2605 (eq_attr "alternative" "6")
2607 (eq_attr "type" "imovx")
2609 (and (eq_attr "type" "imov")
2610 (and (eq_attr "alternative" "0,1")
2611 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2612 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2613 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2615 ;; Avoid partial register stalls when not using QImode arithmetic
2616 (and (eq_attr "type" "imov")
2617 (and (eq_attr "alternative" "0,1")
2618 (and (match_test "TARGET_PARTIAL_REG_STALL")
2619 (not (match_test "TARGET_QIMODE_MATH")))))
2622 (const_string "QI")))])
2624 ;; Stores and loads of ax to arbitrary constant address.
2625 ;; We fake an second form of instruction to force reload to load address
2626 ;; into register when rax is not available
2627 (define_insn "*movabs<mode>_1"
2628 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2629 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2630 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2632 /* Recover the full memory rtx. */
2633 operands[0] = SET_DEST (PATTERN (insn));
2634 switch (which_alternative)
2637 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2639 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2644 [(set_attr "type" "imov")
2645 (set_attr "modrm" "0,*")
2646 (set_attr "length_address" "8,0")
2647 (set_attr "length_immediate" "0,*")
2648 (set_attr "memory" "store")
2649 (set_attr "mode" "<MODE>")])
2651 (define_insn "*movabs<mode>_2"
2652 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2653 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2654 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2656 /* Recover the full memory rtx. */
2657 operands[1] = SET_SRC (PATTERN (insn));
2658 switch (which_alternative)
2661 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2663 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2668 [(set_attr "type" "imov")
2669 (set_attr "modrm" "0,*")
2670 (set_attr "length_address" "8,0")
2671 (set_attr "length_immediate" "0")
2672 (set_attr "memory" "load")
2673 (set_attr "mode" "<MODE>")])
2675 (define_insn "*swap<mode>"
2676 [(set (match_operand:SWI48 0 "register_operand" "+r")
2677 (match_operand:SWI48 1 "register_operand" "+r"))
2681 "xchg{<imodesuffix>}\t%1, %0"
2682 [(set_attr "type" "imov")
2683 (set_attr "mode" "<MODE>")
2684 (set_attr "pent_pair" "np")
2685 (set_attr "athlon_decode" "vector")
2686 (set_attr "amdfam10_decode" "double")
2687 (set_attr "bdver1_decode" "double")])
2689 (define_insn "*swap<mode>_1"
2690 [(set (match_operand:SWI12 0 "register_operand" "+r")
2691 (match_operand:SWI12 1 "register_operand" "+r"))
2694 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2696 [(set_attr "type" "imov")
2697 (set_attr "mode" "SI")
2698 (set_attr "pent_pair" "np")
2699 (set_attr "athlon_decode" "vector")
2700 (set_attr "amdfam10_decode" "double")
2701 (set_attr "bdver1_decode" "double")])
2703 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2704 ;; is disabled for AMDFAM10
2705 (define_insn "*swap<mode>_2"
2706 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2707 (match_operand:SWI12 1 "register_operand" "+<r>"))
2710 "TARGET_PARTIAL_REG_STALL"
2711 "xchg{<imodesuffix>}\t%1, %0"
2712 [(set_attr "type" "imov")
2713 (set_attr "mode" "<MODE>")
2714 (set_attr "pent_pair" "np")
2715 (set_attr "athlon_decode" "vector")])
2717 (define_expand "movstrict<mode>"
2718 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2719 (match_operand:SWI12 1 "general_operand"))]
2722 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2724 if (SUBREG_P (operands[0])
2725 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2727 /* Don't generate memory->memory moves, go through a register */
2728 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2729 operands[1] = force_reg (<MODE>mode, operands[1]);
2732 (define_insn "*movstrict<mode>_1"
2733 [(set (strict_low_part
2734 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2735 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2736 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2737 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2738 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2739 [(set_attr "type" "imov")
2740 (set_attr "mode" "<MODE>")])
2742 (define_insn "*movstrict<mode>_xor"
2743 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2744 (match_operand:SWI12 1 "const0_operand"))
2745 (clobber (reg:CC FLAGS_REG))]
2747 "xor{<imodesuffix>}\t%0, %0"
2748 [(set_attr "type" "alu1")
2749 (set_attr "modrm_class" "op0")
2750 (set_attr "mode" "<MODE>")
2751 (set_attr "length_immediate" "0")])
2753 (define_expand "extv<mode>"
2754 [(set (match_operand:SWI24 0 "register_operand")
2755 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2756 (match_operand:SI 2 "const_int_operand")
2757 (match_operand:SI 3 "const_int_operand")))]
2760 /* Handle extractions from %ah et al. */
2761 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2764 if (! ext_register_operand (operands[1], VOIDmode))
2765 operands[1] = copy_to_reg (operands[1]);
2768 (define_insn "*extv<mode>"
2769 [(set (match_operand:SWI24 0 "register_operand" "=R")
2770 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2774 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2775 [(set_attr "type" "imovx")
2776 (set_attr "mode" "SI")])
2778 (define_insn "*extvqi"
2779 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2780 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2785 switch (get_attr_type (insn))
2788 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2790 return "mov{b}\t{%h1, %0|%0, %h1}";
2793 [(set_attr "isa" "*,*,nox64")
2795 (if_then_else (and (match_operand:QI 0 "register_operand")
2796 (ior (not (match_operand:QI 0 "QIreg_operand"))
2797 (match_test "TARGET_MOVX")))
2798 (const_string "imovx")
2799 (const_string "imov")))
2801 (if_then_else (eq_attr "type" "imovx")
2803 (const_string "QI")))])
2805 (define_expand "extzv<mode>"
2806 [(set (match_operand:SWI248 0 "register_operand")
2807 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2808 (match_operand:SI 2 "const_int_operand")
2809 (match_operand:SI 3 "const_int_operand")))]
2812 if (ix86_expand_pextr (operands))
2815 /* Handle extractions from %ah et al. */
2816 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2819 if (! ext_register_operand (operands[1], VOIDmode))
2820 operands[1] = copy_to_reg (operands[1]);
2823 (define_insn "*extzv<mode>"
2824 [(set (match_operand:SWI248 0 "register_operand" "=R")
2825 (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2829 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2830 [(set_attr "type" "imovx")
2831 (set_attr "mode" "SI")])
2833 (define_insn "*extzvqi"
2834 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2836 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2841 switch (get_attr_type (insn))
2844 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2846 return "mov{b}\t{%h1, %0|%0, %h1}";
2849 [(set_attr "isa" "*,*,nox64")
2851 (if_then_else (and (match_operand:QI 0 "register_operand")
2852 (ior (not (match_operand:QI 0 "QIreg_operand"))
2853 (match_test "TARGET_MOVX")))
2854 (const_string "imovx")
2855 (const_string "imov")))
2857 (if_then_else (eq_attr "type" "imovx")
2859 (const_string "QI")))])
2861 (define_expand "insv<mode>"
2862 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
2863 (match_operand:SI 1 "const_int_operand")
2864 (match_operand:SI 2 "const_int_operand"))
2865 (match_operand:SWI248 3 "register_operand"))]
2870 if (ix86_expand_pinsr (operands))
2873 /* Handle insertions to %ah et al. */
2874 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
2879 if (!ext_register_operand (dst, VOIDmode))
2880 dst = copy_to_reg (dst);
2882 emit_insn (gen_insv<mode>_1 (dst, operands[3]));
2884 /* Fix up the destination if needed. */
2885 if (dst != operands[0])
2886 emit_move_insn (operands[0], dst);
2891 (define_insn "insv<mode>_1"
2892 [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
2895 (match_operand:SWI248 1 "general_x64nomem_operand" "Qn,m"))]
2898 if (CONST_INT_P (operands[1]))
2899 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
2900 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2902 [(set_attr "isa" "*,nox64")
2903 (set_attr "type" "imov")
2904 (set_attr "mode" "QI")])
2906 (define_insn "*insvqi"
2907 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2910 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2913 "mov{b}\t{%h1, %h0|%h0, %h1}"
2914 [(set_attr "type" "imov")
2915 (set_attr "mode" "QI")])
2917 ;; Floating point push instructions.
2919 (define_insn "*pushtf"
2920 [(set (match_operand:TF 0 "push_operand" "=<,<")
2921 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2922 "TARGET_64BIT || TARGET_SSE"
2924 /* This insn should be already split before reg-stack. */
2927 [(set_attr "isa" "*,x64")
2928 (set_attr "type" "multi")
2929 (set_attr "unit" "sse,*")
2930 (set_attr "mode" "TF,DI")])
2932 ;; %%% Kill this when call knows how to work this out.
2934 [(set (match_operand:TF 0 "push_operand")
2935 (match_operand:TF 1 "sse_reg_operand"))]
2936 "TARGET_SSE && reload_completed"
2937 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2938 (set (match_dup 0) (match_dup 1))]
2940 /* Preserve memory attributes. */
2941 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2944 (define_insn "*pushxf"
2945 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<")
2946 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF"))]
2949 /* This insn should be already split before reg-stack. */
2952 [(set_attr "type" "multi")
2953 (set_attr "unit" "i387,*,*,*")
2955 (cond [(eq_attr "alternative" "1,2,3")
2956 (if_then_else (match_test "TARGET_64BIT")
2958 (const_string "SI"))
2960 (const_string "XF")))
2961 (set (attr "preferred_for_size")
2962 (cond [(eq_attr "alternative" "1")
2963 (symbol_ref "false")]
2964 (symbol_ref "true")))])
2966 ;; %%% Kill this when call knows how to work this out.
2968 [(set (match_operand:XF 0 "push_operand")
2969 (match_operand:XF 1 "fp_register_operand"))]
2971 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2972 (set (match_dup 0) (match_dup 1))]
2974 operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2975 /* Preserve memory attributes. */
2976 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2979 (define_insn "*pushdf"
2980 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
2981 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmF,x"))]
2984 /* This insn should be already split before reg-stack. */
2987 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
2988 (set_attr "type" "multi")
2989 (set_attr "unit" "i387,*,*,*,*,sse")
2990 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
2991 (set (attr "preferred_for_size")
2992 (cond [(eq_attr "alternative" "1")
2993 (symbol_ref "false")]
2994 (symbol_ref "true")))
2995 (set (attr "preferred_for_speed")
2996 (cond [(eq_attr "alternative" "1")
2997 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
2998 (symbol_ref "true")))])
3000 ;; %%% Kill this when call knows how to work this out.
3002 [(set (match_operand:DF 0 "push_operand")
3003 (match_operand:DF 1 "any_fp_register_operand"))]
3005 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3006 (set (match_dup 0) (match_dup 1))]
3008 /* Preserve memory attributes. */
3009 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3012 (define_insn "*pushsf_rex64"
3013 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3014 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3017 /* Anything else should be already split before reg-stack. */
3018 gcc_assert (which_alternative == 1);
3019 return "push{q}\t%q1";
3021 [(set_attr "type" "multi,push,multi")
3022 (set_attr "unit" "i387,*,*")
3023 (set_attr "mode" "SF,DI,SF")])
3025 (define_insn "*pushsf"
3026 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3027 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3030 /* Anything else should be already split before reg-stack. */
3031 gcc_assert (which_alternative == 1);
3032 return "push{l}\t%1";
3034 [(set_attr "type" "multi,push,multi")
3035 (set_attr "unit" "i387,*,*")
3036 (set_attr "mode" "SF,SI,SF")])
3038 ;; %%% Kill this when call knows how to work this out.
3040 [(set (match_operand:SF 0 "push_operand")
3041 (match_operand:SF 1 "any_fp_register_operand"))]
3043 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3044 (set (match_dup 0) (match_dup 1))]
3046 rtx op = XEXP (operands[0], 0);
3047 if (GET_CODE (op) == PRE_DEC)
3049 gcc_assert (!TARGET_64BIT);
3054 op = XEXP (XEXP (op, 1), 1);
3055 gcc_assert (CONST_INT_P (op));
3058 /* Preserve memory attributes. */
3059 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3063 [(set (match_operand:SF 0 "push_operand")
3064 (match_operand:SF 1 "memory_operand"))]
3066 [(set (match_dup 0) (match_dup 2))]
3068 operands[2] = find_constant_src (curr_insn);
3070 if (operands[2] == NULL_RTX)
3075 [(set (match_operand 0 "push_operand")
3076 (match_operand 1 "general_operand"))]
3078 && (GET_MODE (operands[0]) == TFmode
3079 || GET_MODE (operands[0]) == XFmode
3080 || GET_MODE (operands[0]) == DFmode)
3081 && !ANY_FP_REG_P (operands[1])"
3083 "ix86_split_long_move (operands); DONE;")
3085 ;; Floating point move instructions.
3087 (define_expand "movtf"
3088 [(set (match_operand:TF 0 "nonimmediate_operand")
3089 (match_operand:TF 1 "nonimmediate_operand"))]
3090 "TARGET_64BIT || TARGET_SSE"
3091 "ix86_expand_move (TFmode, operands); DONE;")
3093 (define_expand "mov<mode>"
3094 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3095 (match_operand:X87MODEF 1 "general_operand"))]
3097 "ix86_expand_move (<MODE>mode, operands); DONE;")
3099 (define_insn "*movtf_internal"
3100 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
3101 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
3102 "(TARGET_64BIT || TARGET_SSE)
3103 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3104 && (lra_in_progress || reload_completed
3105 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3106 || !CONST_DOUBLE_P (operands[1])
3107 || (optimize_function_for_size_p (cfun)
3108 && standard_sse_constant_p (operands[1])
3109 && !memory_operand (operands[0], TFmode))
3110 || (!TARGET_MEMORY_MISMATCH_STALL
3111 && memory_operand (operands[0], TFmode)))"
3113 switch (get_attr_type (insn))
3116 return standard_sse_constant_opcode (insn, operands[1]);
3119 /* Handle misaligned load/store since we
3120 don't have movmisaligntf pattern. */
3121 if (misaligned_operand (operands[0], TFmode)
3122 || misaligned_operand (operands[1], TFmode))
3124 if (get_attr_mode (insn) == MODE_V4SF)
3125 return "%vmovups\t{%1, %0|%0, %1}";
3127 return "%vmovdqu\t{%1, %0|%0, %1}";
3131 if (get_attr_mode (insn) == MODE_V4SF)
3132 return "%vmovaps\t{%1, %0|%0, %1}";
3134 return "%vmovdqa\t{%1, %0|%0, %1}";
3144 [(set_attr "isa" "*,*,*,x64,x64")
3145 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3146 (set (attr "prefix")
3147 (if_then_else (eq_attr "type" "sselog1,ssemov")
3148 (const_string "maybe_vex")
3149 (const_string "orig")))
3151 (cond [(eq_attr "alternative" "3,4")
3153 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3154 (const_string "V4SF")
3155 (and (eq_attr "alternative" "2")
3156 (match_test "TARGET_SSE_TYPELESS_STORES"))
3157 (const_string "V4SF")
3158 (match_test "TARGET_AVX")
3160 (ior (not (match_test "TARGET_SSE2"))
3161 (match_test "optimize_function_for_size_p (cfun)"))
3162 (const_string "V4SF")
3164 (const_string "TI")))])
3167 [(set (match_operand:TF 0 "nonimmediate_operand")
3168 (match_operand:TF 1 "general_operand"))]
3170 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3172 "ix86_split_long_move (operands); DONE;")
3174 ;; Possible store forwarding (partial memory) stall
3175 ;; in alternatives 4, 6, 7 and 8.
3176 (define_insn "*movxf_internal"
3177 [(set (match_operand:XF 0 "nonimmediate_operand"
3178 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o")
3179 (match_operand:XF 1 "general_operand"
3180 "fm,f,G,roF,r , *roF,*r,F ,C,roF,rF"))]
3181 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3182 && (lra_in_progress || reload_completed
3183 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3184 || !CONST_DOUBLE_P (operands[1])
3185 || (optimize_function_for_size_p (cfun)
3186 && standard_80387_constant_p (operands[1]) > 0
3187 && !memory_operand (operands[0], XFmode))
3188 || (!TARGET_MEMORY_MISMATCH_STALL
3189 && memory_operand (operands[0], XFmode))
3190 || !TARGET_HARD_XF_REGS)"
3192 switch (get_attr_type (insn))
3195 if (which_alternative == 2)
3196 return standard_80387_constant_opcode (operands[1]);
3197 return output_387_reg_move (insn, operands);
3207 (cond [(eq_attr "alternative" "7")
3208 (const_string "nox64")
3209 (eq_attr "alternative" "8")
3210 (const_string "x64")
3212 (const_string "*")))
3214 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10")
3215 (const_string "multi")
3217 (const_string "fmov")))
3219 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10")
3220 (if_then_else (match_test "TARGET_64BIT")
3222 (const_string "SI"))
3224 (const_string "XF")))
3225 (set (attr "preferred_for_size")
3226 (cond [(eq_attr "alternative" "3,4")
3227 (symbol_ref "false")]
3228 (symbol_ref "true")))
3229 (set (attr "enabled")
3230 (cond [(eq_attr "alternative" "9,10")
3232 (match_test "TARGET_HARD_XF_REGS")
3233 (symbol_ref "false")
3235 (not (match_test "TARGET_HARD_XF_REGS"))
3236 (symbol_ref "false")
3238 (const_string "*")))])
3241 [(set (match_operand:XF 0 "nonimmediate_operand")
3242 (match_operand:XF 1 "general_operand"))]
3244 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3246 "ix86_split_long_move (operands); DONE;")
3248 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3249 (define_insn "*movdf_internal"
3250 [(set (match_operand:DF 0 "nonimmediate_operand"
3251 "=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")
3252 (match_operand:DF 1 "general_operand"
3253 "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"))]
3254 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3255 && (lra_in_progress || reload_completed
3256 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3257 || !CONST_DOUBLE_P (operands[1])
3258 || (optimize_function_for_size_p (cfun)
3259 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3260 && standard_80387_constant_p (operands[1]) > 0)
3261 || (TARGET_SSE2 && TARGET_SSE_MATH
3262 && standard_sse_constant_p (operands[1])))
3263 && !memory_operand (operands[0], DFmode))
3264 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3265 && memory_operand (operands[0], DFmode))
3266 || !TARGET_HARD_DF_REGS)"
3268 switch (get_attr_type (insn))
3271 if (which_alternative == 2)
3272 return standard_80387_constant_opcode (operands[1]);
3273 return output_387_reg_move (insn, operands);
3279 if (get_attr_mode (insn) == MODE_SI)
3280 return "mov{l}\t{%1, %k0|%k0, %1}";
3281 else if (which_alternative == 11)
3282 return "movabs{q}\t{%1, %0|%0, %1}";
3284 return "mov{q}\t{%1, %0|%0, %1}";
3287 return standard_sse_constant_opcode (insn, operands[1]);
3290 switch (get_attr_mode (insn))
3293 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3294 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3295 return "%vmovsd\t{%1, %0|%0, %1}";
3298 return "%vmovaps\t{%1, %0|%0, %1}";
3300 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3302 return "%vmovapd\t{%1, %0|%0, %1}";
3305 gcc_assert (!TARGET_AVX);
3306 return "movlps\t{%1, %0|%0, %1}";
3308 gcc_assert (!TARGET_AVX);
3309 return "movlpd\t{%1, %0|%0, %1}";
3312 /* Handle broken assemblers that require movd instead of movq. */
3313 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3314 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3315 return "%vmovd\t{%1, %0|%0, %1}";
3316 return "%vmovq\t{%1, %0|%0, %1}";
3327 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3328 (const_string "nox64")
3329 (eq_attr "alternative" "8,9,10,11,20,21,24,25")
3330 (const_string "x64")
3331 (eq_attr "alternative" "12,13,14,15")
3332 (const_string "sse2")
3334 (const_string "*")))
3336 (cond [(eq_attr "alternative" "0,1,2")
3337 (const_string "fmov")
3338 (eq_attr "alternative" "3,4,5,6,7,22,23")
3339 (const_string "multi")
3340 (eq_attr "alternative" "8,9,10,11,24,25")
3341 (const_string "imov")
3342 (eq_attr "alternative" "12,16")
3343 (const_string "sselog1")
3345 (const_string "ssemov")))
3347 (if_then_else (eq_attr "alternative" "11")
3349 (const_string "*")))
3350 (set (attr "length_immediate")
3351 (if_then_else (eq_attr "alternative" "11")
3353 (const_string "*")))
3354 (set (attr "prefix")
3355 (if_then_else (eq_attr "type" "sselog1,ssemov")
3356 (const_string "maybe_vex")
3357 (const_string "orig")))
3358 (set (attr "prefix_data16")
3360 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3361 (eq_attr "mode" "V1DF"))
3363 (const_string "*")))
3365 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3367 (eq_attr "alternative" "8,9,11,20,21,24,25")
3370 /* xorps is one byte shorter for non-AVX targets. */
3371 (eq_attr "alternative" "12,16")
3372 (cond [(not (match_test "TARGET_SSE2"))
3373 (const_string "V4SF")
3374 (match_test "TARGET_AVX512F")
3376 (match_test "TARGET_AVX")
3377 (const_string "V2DF")
3378 (match_test "optimize_function_for_size_p (cfun)")
3379 (const_string "V4SF")
3380 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3383 (const_string "V2DF"))
3385 /* For architectures resolving dependencies on
3386 whole SSE registers use movapd to break dependency
3387 chains, otherwise use short move to avoid extra work. */
3389 /* movaps is one byte shorter for non-AVX targets. */
3390 (eq_attr "alternative" "13,17")
3391 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3392 (match_operand 1 "ext_sse_reg_operand"))
3393 (const_string "V8DF")
3394 (ior (not (match_test "TARGET_SSE2"))
3395 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3396 (const_string "V4SF")
3397 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3398 (const_string "V2DF")
3399 (match_test "TARGET_AVX")
3401 (match_test "optimize_function_for_size_p (cfun)")
3402 (const_string "V4SF")
3404 (const_string "DF"))
3406 /* For architectures resolving dependencies on register
3407 parts we may avoid extra work to zero out upper part
3409 (eq_attr "alternative" "14,18")
3410 (cond [(not (match_test "TARGET_SSE2"))
3411 (const_string "V2SF")
3412 (match_test "TARGET_AVX")
3414 (match_test "TARGET_SSE_SPLIT_REGS")
3415 (const_string "V1DF")
3417 (const_string "DF"))
3419 (and (eq_attr "alternative" "15,19")
3420 (not (match_test "TARGET_SSE2")))
3421 (const_string "V2SF")
3423 (const_string "DF")))
3424 (set (attr "preferred_for_size")
3425 (cond [(eq_attr "alternative" "3,4")
3426 (symbol_ref "false")]
3427 (symbol_ref "true")))
3428 (set (attr "preferred_for_speed")
3429 (cond [(eq_attr "alternative" "3,4")
3430 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3431 (symbol_ref "true")))
3432 (set (attr "enabled")
3433 (cond [(eq_attr "alternative" "22,23,24,25")
3435 (match_test "TARGET_HARD_DF_REGS")
3436 (symbol_ref "false")
3438 (not (match_test "TARGET_HARD_DF_REGS"))
3439 (symbol_ref "false")
3441 (const_string "*")))])
3444 [(set (match_operand:DF 0 "nonimmediate_operand")
3445 (match_operand:DF 1 "general_operand"))]
3446 "!TARGET_64BIT && reload_completed
3447 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3449 "ix86_split_long_move (operands); DONE;")
3451 (define_insn "*movsf_internal"
3452 [(set (match_operand:SF 0 "nonimmediate_operand"
3453 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym,r ,m")
3454 (match_operand:SF 1 "general_operand"
3455 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r ,rmF,rF"))]
3456 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3457 && (lra_in_progress || reload_completed
3458 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3459 || !CONST_DOUBLE_P (operands[1])
3460 || (optimize_function_for_size_p (cfun)
3461 && ((!TARGET_SSE_MATH
3462 && standard_80387_constant_p (operands[1]) > 0)
3464 && standard_sse_constant_p (operands[1]))))
3465 || memory_operand (operands[0], SFmode)
3466 || !TARGET_HARD_SF_REGS)"
3468 switch (get_attr_type (insn))
3471 if (which_alternative == 2)
3472 return standard_80387_constant_opcode (operands[1]);
3473 return output_387_reg_move (insn, operands);
3476 return "mov{l}\t{%1, %0|%0, %1}";
3479 return standard_sse_constant_opcode (insn, operands[1]);
3482 switch (get_attr_mode (insn))
3485 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3486 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3487 return "%vmovss\t{%1, %0|%0, %1}";
3490 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3492 return "%vmovaps\t{%1, %0|%0, %1}";
3495 return "%vmovd\t{%1, %0|%0, %1}";
3502 switch (get_attr_mode (insn))
3505 return "movq\t{%1, %0|%0, %1}";
3507 return "movd\t{%1, %0|%0, %1}";
3518 (cond [(eq_attr "alternative" "0,1,2")
3519 (const_string "fmov")
3520 (eq_attr "alternative" "3,4,16,17")
3521 (const_string "imov")
3522 (eq_attr "alternative" "5")
3523 (const_string "sselog1")
3524 (eq_attr "alternative" "11,12,13,14,15")
3525 (const_string "mmxmov")
3527 (const_string "ssemov")))
3528 (set (attr "prefix")
3529 (if_then_else (eq_attr "type" "sselog1,ssemov")
3530 (const_string "maybe_vex")
3531 (const_string "orig")))
3532 (set (attr "prefix_data16")
3533 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3535 (const_string "*")))
3537 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3539 (eq_attr "alternative" "11")
3541 (eq_attr "alternative" "5")
3542 (cond [(not (match_test "TARGET_SSE2"))
3543 (const_string "V4SF")
3544 (match_test "TARGET_AVX512F")
3545 (const_string "V16SF")
3546 (match_test "TARGET_AVX")
3547 (const_string "V4SF")
3548 (match_test "optimize_function_for_size_p (cfun)")
3549 (const_string "V4SF")
3550 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3553 (const_string "V4SF"))
3555 /* For architectures resolving dependencies on
3556 whole SSE registers use APS move to break dependency
3557 chains, otherwise use short move to avoid extra work.
3559 Do the same for architectures resolving dependencies on
3560 the parts. While in DF mode it is better to always handle
3561 just register parts, the SF mode is different due to lack
3562 of instructions to load just part of the register. It is
3563 better to maintain the whole registers in single format
3564 to avoid problems on using packed logical operations. */
3565 (eq_attr "alternative" "6")
3566 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3567 (match_operand 1 "ext_sse_reg_operand"))
3568 (const_string "V16SF")
3569 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3570 (match_test "TARGET_SSE_SPLIT_REGS"))
3571 (const_string "V4SF")
3573 (const_string "SF"))
3575 (const_string "SF")))
3576 (set (attr "enabled")
3577 (cond [(eq_attr "alternative" "16,17")
3579 (match_test "TARGET_HARD_SF_REGS")
3580 (symbol_ref "false")
3582 (not (match_test "TARGET_HARD_SF_REGS"))
3583 (symbol_ref "false")
3585 (const_string "*")))])
3588 [(set (match_operand 0 "any_fp_register_operand")
3589 (match_operand 1 "memory_operand"))]
3591 && (GET_MODE (operands[0]) == TFmode
3592 || GET_MODE (operands[0]) == XFmode
3593 || GET_MODE (operands[0]) == DFmode
3594 || GET_MODE (operands[0]) == SFmode)"
3595 [(set (match_dup 0) (match_dup 2))]
3597 operands[2] = find_constant_src (curr_insn);
3599 if (operands[2] == NULL_RTX
3600 || (SSE_REGNO_P (REGNO (operands[0]))
3601 && !standard_sse_constant_p (operands[2]))
3602 || (STACK_REGNO_P (REGNO (operands[0]))
3603 && standard_80387_constant_p (operands[2]) < 1))
3608 [(set (match_operand 0 "any_fp_register_operand")
3609 (float_extend (match_operand 1 "memory_operand")))]
3611 && (GET_MODE (operands[0]) == TFmode
3612 || GET_MODE (operands[0]) == XFmode
3613 || GET_MODE (operands[0]) == DFmode)"
3614 [(set (match_dup 0) (match_dup 2))]
3616 operands[2] = find_constant_src (curr_insn);
3618 if (operands[2] == NULL_RTX
3619 || (SSE_REGNO_P (REGNO (operands[0]))
3620 && !standard_sse_constant_p (operands[2]))
3621 || (STACK_REGNO_P (REGNO (operands[0]))
3622 && standard_80387_constant_p (operands[2]) < 1))
3626 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3628 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3629 (match_operand:X87MODEF 1 "immediate_operand"))]
3631 && (standard_80387_constant_p (operands[1]) == 8
3632 || standard_80387_constant_p (operands[1]) == 9)"
3633 [(set (match_dup 0)(match_dup 1))
3635 (neg:X87MODEF (match_dup 0)))]
3637 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3638 operands[1] = CONST0_RTX (<MODE>mode);
3640 operands[1] = CONST1_RTX (<MODE>mode);
3643 (define_insn "swapxf"
3644 [(set (match_operand:XF 0 "register_operand" "+f")
3645 (match_operand:XF 1 "register_operand" "+f"))
3650 if (STACK_TOP_P (operands[0]))
3655 [(set_attr "type" "fxch")
3656 (set_attr "mode" "XF")])
3658 (define_insn "*swap<mode>"
3659 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3660 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3663 "TARGET_80387 || reload_completed"
3665 if (STACK_TOP_P (operands[0]))
3670 [(set_attr "type" "fxch")
3671 (set_attr "mode" "<MODE>")])
3673 ;; Zero extension instructions
3675 (define_expand "zero_extendsidi2"
3676 [(set (match_operand:DI 0 "nonimmediate_operand")
3677 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3679 (define_insn "*zero_extendsidi2"
3680 [(set (match_operand:DI 0 "nonimmediate_operand"
3681 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3683 (match_operand:SI 1 "x86_64_zext_operand"
3684 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))]
3687 switch (get_attr_type (insn))
3690 if (ix86_use_lea_for_mov (insn, operands))
3691 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3693 return "mov{l}\t{%1, %k0|%k0, %1}";
3699 return "movd\t{%1, %0|%0, %1}";
3702 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3705 if (GENERAL_REG_P (operands[0]))
3706 return "%vmovd\t{%1, %k0|%k0, %1}";
3708 return "%vmovd\t{%1, %0|%0, %1}";
3715 (cond [(eq_attr "alternative" "0,1,2")
3716 (const_string "nox64")
3717 (eq_attr "alternative" "3,7")
3718 (const_string "x64")
3719 (eq_attr "alternative" "8")
3720 (const_string "x64_sse4")
3721 (eq_attr "alternative" "10")
3722 (const_string "sse2")
3724 (const_string "*")))
3726 (cond [(eq_attr "alternative" "0,1,2,4")
3727 (const_string "multi")
3728 (eq_attr "alternative" "5,6")
3729 (const_string "mmxmov")
3730 (eq_attr "alternative" "7,9,10")
3731 (const_string "ssemov")
3732 (eq_attr "alternative" "8")
3733 (const_string "sselog1")
3735 (const_string "imovx")))
3736 (set (attr "prefix_extra")
3737 (if_then_else (eq_attr "alternative" "8")
3739 (const_string "*")))
3740 (set (attr "length_immediate")
3741 (if_then_else (eq_attr "alternative" "8")
3743 (const_string "*")))
3744 (set (attr "prefix")
3745 (if_then_else (eq_attr "type" "ssemov,sselog1")
3746 (const_string "maybe_vex")
3747 (const_string "orig")))
3748 (set (attr "prefix_0f")
3749 (if_then_else (eq_attr "type" "imovx")
3751 (const_string "*")))
3753 (cond [(eq_attr "alternative" "5,6")
3755 (eq_attr "alternative" "7,8,9")
3758 (const_string "SI")))])
3761 [(set (match_operand:DI 0 "memory_operand")
3762 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3764 [(set (match_dup 4) (const_int 0))]
3765 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3768 [(set (match_operand:DI 0 "register_operand")
3769 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3770 "!TARGET_64BIT && reload_completed
3771 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3772 && true_regnum (operands[0]) == true_regnum (operands[1])"
3773 [(set (match_dup 4) (const_int 0))]
3774 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3777 [(set (match_operand:DI 0 "nonimmediate_operand")
3778 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3779 "!TARGET_64BIT && reload_completed
3780 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3781 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3782 [(set (match_dup 3) (match_dup 1))
3783 (set (match_dup 4) (const_int 0))]
3784 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3786 (define_insn "zero_extend<mode>di2"
3787 [(set (match_operand:DI 0 "register_operand" "=r")
3789 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3791 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3792 [(set_attr "type" "imovx")
3793 (set_attr "mode" "SI")])
3795 (define_expand "zero_extend<mode>si2"
3796 [(set (match_operand:SI 0 "register_operand")
3797 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3800 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3802 operands[1] = force_reg (<MODE>mode, operands[1]);
3803 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3808 (define_insn_and_split "zero_extend<mode>si2_and"
3809 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3811 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3812 (clobber (reg:CC FLAGS_REG))]
3813 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3815 "&& reload_completed"
3816 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3817 (clobber (reg:CC FLAGS_REG))])]
3819 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3821 ix86_expand_clear (operands[0]);
3823 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3824 emit_insn (gen_movstrict<mode>
3825 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3829 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3831 [(set_attr "type" "alu1")
3832 (set_attr "mode" "SI")])
3834 (define_insn "*zero_extend<mode>si2"
3835 [(set (match_operand:SI 0 "register_operand" "=r")
3837 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3838 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3839 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3840 [(set_attr "type" "imovx")
3841 (set_attr "mode" "SI")])
3843 (define_expand "zero_extendqihi2"
3844 [(set (match_operand:HI 0 "register_operand")
3845 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3848 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3850 operands[1] = force_reg (QImode, operands[1]);
3851 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3856 (define_insn_and_split "zero_extendqihi2_and"
3857 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3858 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3859 (clobber (reg:CC FLAGS_REG))]
3860 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3862 "&& reload_completed"
3863 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3864 (clobber (reg:CC FLAGS_REG))])]
3866 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3868 ix86_expand_clear (operands[0]);
3870 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3871 emit_insn (gen_movstrictqi
3872 (gen_lowpart (QImode, operands[0]), operands[1]));
3876 operands[0] = gen_lowpart (SImode, operands[0]);
3878 [(set_attr "type" "alu1")
3879 (set_attr "mode" "SI")])
3881 ; zero extend to SImode to avoid partial register stalls
3882 (define_insn "*zero_extendqihi2"
3883 [(set (match_operand:HI 0 "register_operand" "=r")
3884 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3885 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3886 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3887 [(set_attr "type" "imovx")
3888 (set_attr "mode" "SI")])
3890 (define_insn_and_split "*zext<mode>_doubleword_and"
3891 [(set (match_operand:DI 0 "register_operand" "=&<r>")
3892 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3893 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
3894 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3896 "&& reload_completed && GENERAL_REG_P (operands[0])"
3897 [(set (match_dup 2) (const_int 0))]
3899 split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);
3901 emit_move_insn (operands[0], const0_rtx);
3903 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3904 emit_insn (gen_movstrict<mode>
3905 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3908 (define_insn_and_split "*zext<mode>_doubleword"
3909 [(set (match_operand:DI 0 "register_operand" "=r")
3910 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3911 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
3912 && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3914 "&& reload_completed && GENERAL_REG_P (operands[0])"
3915 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
3916 (set (match_dup 2) (const_int 0))]
3917 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
3919 (define_insn_and_split "*zextsi_doubleword"
3920 [(set (match_operand:DI 0 "register_operand" "=r")
3921 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3922 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
3924 "&& reload_completed && GENERAL_REG_P (operands[0])"
3925 [(set (match_dup 0) (match_dup 1))
3926 (set (match_dup 2) (const_int 0))]
3927 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
3929 ;; Sign extension instructions
3931 (define_expand "extendsidi2"
3932 [(set (match_operand:DI 0 "register_operand")
3933 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3938 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3943 (define_insn "*extendsidi2_rex64"
3944 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3945 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3949 movs{lq|x}\t{%1, %0|%0, %1}"
3950 [(set_attr "type" "imovx")
3951 (set_attr "mode" "DI")
3952 (set_attr "prefix_0f" "0")
3953 (set_attr "modrm" "0,1")])
3955 (define_insn "extendsidi2_1"
3956 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3957 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3958 (clobber (reg:CC FLAGS_REG))
3959 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3963 ;; Split the memory case. If the source register doesn't die, it will stay
3964 ;; this way, if it does die, following peephole2s take care of it.
3966 [(set (match_operand:DI 0 "memory_operand")
3967 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3968 (clobber (reg:CC FLAGS_REG))
3969 (clobber (match_operand:SI 2 "register_operand"))]
3973 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3975 emit_move_insn (operands[3], operands[1]);
3977 /* Generate a cltd if possible and doing so it profitable. */
3978 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3979 && true_regnum (operands[1]) == AX_REG
3980 && true_regnum (operands[2]) == DX_REG)
3982 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3986 emit_move_insn (operands[2], operands[1]);
3987 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3989 emit_move_insn (operands[4], operands[2]);
3993 ;; Peepholes for the case where the source register does die, after
3994 ;; being split with the above splitter.
3996 [(set (match_operand:SI 0 "memory_operand")
3997 (match_operand:SI 1 "register_operand"))
3998 (set (match_operand:SI 2 "register_operand") (match_dup 1))
3999 (parallel [(set (match_dup 2)
4000 (ashiftrt:SI (match_dup 2) (const_int 31)))
4001 (clobber (reg:CC FLAGS_REG))])
4002 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4003 "REGNO (operands[1]) != REGNO (operands[2])
4004 && peep2_reg_dead_p (2, operands[1])
4005 && peep2_reg_dead_p (4, operands[2])
4006 && !reg_mentioned_p (operands[2], operands[3])"
4007 [(set (match_dup 0) (match_dup 1))
4008 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4009 (clobber (reg:CC FLAGS_REG))])
4010 (set (match_dup 3) (match_dup 1))])
4013 [(set (match_operand:SI 0 "memory_operand")
4014 (match_operand:SI 1 "register_operand"))
4015 (parallel [(set (match_operand:SI 2 "register_operand")
4016 (ashiftrt:SI (match_dup 1) (const_int 31)))
4017 (clobber (reg:CC FLAGS_REG))])
4018 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4019 "/* cltd is shorter than sarl $31, %eax */
4020 !optimize_function_for_size_p (cfun)
4021 && true_regnum (operands[1]) == AX_REG
4022 && true_regnum (operands[2]) == DX_REG
4023 && peep2_reg_dead_p (2, operands[1])
4024 && peep2_reg_dead_p (3, operands[2])
4025 && !reg_mentioned_p (operands[2], operands[3])"
4026 [(set (match_dup 0) (match_dup 1))
4027 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4028 (clobber (reg:CC FLAGS_REG))])
4029 (set (match_dup 3) (match_dup 1))])
4031 ;; Extend to register case. Optimize case where source and destination
4032 ;; registers match and cases where we can use cltd.
4034 [(set (match_operand:DI 0 "register_operand")
4035 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4036 (clobber (reg:CC FLAGS_REG))
4037 (clobber (match_scratch:SI 2))]
4041 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4043 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4044 emit_move_insn (operands[3], operands[1]);
4046 /* Generate a cltd if possible and doing so it profitable. */
4047 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4048 && true_regnum (operands[3]) == AX_REG
4049 && true_regnum (operands[4]) == DX_REG)
4051 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4055 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4056 emit_move_insn (operands[4], operands[1]);
4058 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4062 (define_insn "extend<mode>di2"
4063 [(set (match_operand:DI 0 "register_operand" "=r")
4065 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4067 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4068 [(set_attr "type" "imovx")
4069 (set_attr "mode" "DI")])
4071 (define_insn "extendhisi2"
4072 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4073 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4076 switch (get_attr_prefix_0f (insn))
4079 return "{cwtl|cwde}";
4081 return "movs{wl|x}\t{%1, %0|%0, %1}";
4084 [(set_attr "type" "imovx")
4085 (set_attr "mode" "SI")
4086 (set (attr "prefix_0f")
4087 ;; movsx is short decodable while cwtl is vector decoded.
4088 (if_then_else (and (eq_attr "cpu" "!k6")
4089 (eq_attr "alternative" "0"))
4091 (const_string "1")))
4092 (set (attr "znver1_decode")
4093 (if_then_else (eq_attr "prefix_0f" "0")
4094 (const_string "double")
4095 (const_string "direct")))
4097 (if_then_else (eq_attr "prefix_0f" "0")
4099 (const_string "1")))])
4101 (define_insn "*extendhisi2_zext"
4102 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4105 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4108 switch (get_attr_prefix_0f (insn))
4111 return "{cwtl|cwde}";
4113 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4116 [(set_attr "type" "imovx")
4117 (set_attr "mode" "SI")
4118 (set (attr "prefix_0f")
4119 ;; movsx is short decodable while cwtl is vector decoded.
4120 (if_then_else (and (eq_attr "cpu" "!k6")
4121 (eq_attr "alternative" "0"))
4123 (const_string "1")))
4125 (if_then_else (eq_attr "prefix_0f" "0")
4127 (const_string "1")))])
4129 (define_insn "extendqisi2"
4130 [(set (match_operand:SI 0 "register_operand" "=r")
4131 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4133 "movs{bl|x}\t{%1, %0|%0, %1}"
4134 [(set_attr "type" "imovx")
4135 (set_attr "mode" "SI")])
4137 (define_insn "*extendqisi2_zext"
4138 [(set (match_operand:DI 0 "register_operand" "=r")
4140 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4142 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4143 [(set_attr "type" "imovx")
4144 (set_attr "mode" "SI")])
4146 (define_insn "extendqihi2"
4147 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4148 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4151 switch (get_attr_prefix_0f (insn))
4154 return "{cbtw|cbw}";
4156 return "movs{bw|x}\t{%1, %0|%0, %1}";
4159 [(set_attr "type" "imovx")
4160 (set_attr "mode" "HI")
4161 (set (attr "prefix_0f")
4162 ;; movsx is short decodable while cwtl is vector decoded.
4163 (if_then_else (and (eq_attr "cpu" "!k6")
4164 (eq_attr "alternative" "0"))
4166 (const_string "1")))
4168 (if_then_else (eq_attr "prefix_0f" "0")
4170 (const_string "1")))])
4172 ;; Conversions between float and double.
4174 ;; These are all no-ops in the model used for the 80387.
4175 ;; So just emit moves.
4177 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4179 [(set (match_operand:DF 0 "push_operand")
4180 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4182 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4183 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4186 [(set (match_operand:XF 0 "push_operand")
4187 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4189 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4190 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4191 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4193 (define_expand "extendsfdf2"
4194 [(set (match_operand:DF 0 "nonimmediate_operand")
4195 (float_extend:DF (match_operand:SF 1 "general_operand")))]
4196 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4198 /* ??? Needed for compress_float_constant since all fp constants
4199 are TARGET_LEGITIMATE_CONSTANT_P. */
4200 if (CONST_DOUBLE_P (operands[1]))
4202 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4203 && standard_80387_constant_p (operands[1]) > 0)
4205 operands[1] = simplify_const_unary_operation
4206 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4207 emit_move_insn_1 (operands[0], operands[1]);
4210 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4214 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4216 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4218 We do the conversion post reload to avoid producing of 128bit spills
4219 that might lead to ICE on 32bit target. The sequence unlikely combine
4222 [(set (match_operand:DF 0 "register_operand")
4224 (match_operand:SF 1 "nonimmediate_operand")))]
4225 "TARGET_USE_VECTOR_FP_CONVERTS
4226 && optimize_insn_for_speed_p ()
4227 && reload_completed && SSE_REG_P (operands[0])
4228 && (!EXT_REX_SSE_REG_P (operands[0])
4229 || TARGET_AVX512VL)"
4234 (parallel [(const_int 0) (const_int 1)]))))]
4236 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4237 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4238 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4239 Try to avoid move when unpacking can be done in source. */
4240 if (REG_P (operands[1]))
4242 /* If it is unsafe to overwrite upper half of source, we need
4243 to move to destination and unpack there. */
4244 if (((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4245 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4246 && true_regnum (operands[0]) != true_regnum (operands[1]))
4247 || (EXT_REX_SSE_REG_P (operands[1])
4248 && !TARGET_AVX512VL))
4250 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4251 emit_move_insn (tmp, operands[1]);
4254 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4255 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4256 =v, v, then vbroadcastss will be only needed for AVX512F without
4258 if (!EXT_REX_SSE_REGNO_P (true_regnum (operands[3])))
4259 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4263 rtx tmp = simplify_gen_subreg (V16SFmode, operands[3], V4SFmode, 0);
4264 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4268 emit_insn (gen_vec_setv4sf_0 (operands[3],
4269 CONST0_RTX (V4SFmode), operands[1]));
4272 ;; It's more profitable to split and then extend in the same register.
4274 [(set (match_operand:DF 0 "register_operand")
4276 (match_operand:SF 1 "memory_operand")))]
4277 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4278 && optimize_insn_for_speed_p ()
4279 && SSE_REG_P (operands[0])"
4280 [(set (match_dup 2) (match_dup 1))
4281 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4282 "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
4284 (define_insn "*extendsfdf2_mixed"
4285 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,v")
4287 (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4288 "TARGET_SSE2 && TARGET_SSE_MATH"
4290 switch (which_alternative)
4294 return output_387_reg_move (insn, operands);
4297 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4303 [(set_attr "type" "fmov,fmov,ssecvt")
4304 (set_attr "prefix" "orig,orig,maybe_vex")
4305 (set_attr "mode" "SF,XF,DF")
4306 (set (attr "enabled")
4307 (cond [(eq_attr "alternative" "0,1")
4308 (symbol_ref "TARGET_MIX_SSE_I387")
4310 (symbol_ref "true")))])
4312 (define_insn "*extendsfdf2_i387"
4313 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4314 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4316 "* return output_387_reg_move (insn, operands);"
4317 [(set_attr "type" "fmov")
4318 (set_attr "mode" "SF,XF")])
4320 (define_expand "extend<mode>xf2"
4321 [(set (match_operand:XF 0 "nonimmediate_operand")
4322 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4325 /* ??? Needed for compress_float_constant since all fp constants
4326 are TARGET_LEGITIMATE_CONSTANT_P. */
4327 if (CONST_DOUBLE_P (operands[1]))
4329 if (standard_80387_constant_p (operands[1]) > 0)
4331 operands[1] = simplify_const_unary_operation
4332 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4333 emit_move_insn_1 (operands[0], operands[1]);
4336 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4340 (define_insn "*extend<mode>xf2_i387"
4341 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4343 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4345 "* return output_387_reg_move (insn, operands);"
4346 [(set_attr "type" "fmov")
4347 (set_attr "mode" "<MODE>,XF")])
4349 ;; %%% This seems like bad news.
4350 ;; This cannot output into an f-reg because there is no way to be sure
4351 ;; of truncating in that case. Otherwise this is just like a simple move
4352 ;; insn. So we pretend we can output to a reg in order to get better
4353 ;; register preferencing, but we really use a stack slot.
4355 ;; Conversion from DFmode to SFmode.
4357 (define_expand "truncdfsf2"
4358 [(set (match_operand:SF 0 "nonimmediate_operand")
4360 (match_operand:DF 1 "nonimmediate_operand")))]
4361 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4363 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4365 else if (flag_unsafe_math_optimizations)
4369 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4370 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4375 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4377 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4379 We do the conversion post reload to avoid producing of 128bit spills
4380 that might lead to ICE on 32bit target. The sequence unlikely combine
4383 [(set (match_operand:SF 0 "register_operand")
4385 (match_operand:DF 1 "nonimmediate_operand")))]
4386 "TARGET_USE_VECTOR_FP_CONVERTS
4387 && optimize_insn_for_speed_p ()
4388 && reload_completed && SSE_REG_P (operands[0])
4389 && (!EXT_REX_SSE_REG_P (operands[0])
4390 || TARGET_AVX512VL)"
4393 (float_truncate:V2SF
4397 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4398 operands[3] = CONST0_RTX (V2SFmode);
4399 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4400 /* Use movsd for loading from memory, unpcklpd for registers.
4401 Try to avoid move when unpacking can be done in source, or SSE3
4402 movddup is available. */
4403 if (REG_P (operands[1]))
4406 && true_regnum (operands[0]) != true_regnum (operands[1])
4407 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4408 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4410 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4411 emit_move_insn (tmp, operands[1]);
4414 else if (!TARGET_SSE3)
4415 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4416 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4419 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4420 CONST0_RTX (DFmode)));
4423 ;; It's more profitable to split and then extend in the same register.
4425 [(set (match_operand:SF 0 "register_operand")
4427 (match_operand:DF 1 "memory_operand")))]
4428 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4429 && optimize_insn_for_speed_p ()
4430 && SSE_REG_P (operands[0])"
4431 [(set (match_dup 2) (match_dup 1))
4432 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4433 "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4435 (define_expand "truncdfsf2_with_temp"
4436 [(parallel [(set (match_operand:SF 0)
4437 (float_truncate:SF (match_operand:DF 1)))
4438 (clobber (match_operand:SF 2))])])
4440 ;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
4441 ;; because nothing we do there is unsafe.
4442 (define_insn "*truncdfsf_fast_mixed"
4443 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,v")
4445 (match_operand:DF 1 "nonimmediate_operand" "f ,vm")))]
4446 "TARGET_SSE2 && TARGET_SSE_MATH"
4448 switch (which_alternative)
4451 return output_387_reg_move (insn, operands);
4453 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4458 [(set_attr "type" "fmov,ssecvt")
4459 (set_attr "prefix" "orig,maybe_vex")
4460 (set_attr "mode" "SF")
4461 (set (attr "enabled")
4462 (cond [(eq_attr "alternative" "0")
4463 (symbol_ref "TARGET_MIX_SSE_I387
4464 && flag_unsafe_math_optimizations")
4466 (symbol_ref "true")))])
4468 (define_insn "*truncdfsf_fast_i387"
4469 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4471 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4472 "TARGET_80387 && flag_unsafe_math_optimizations"
4473 "* return output_387_reg_move (insn, operands);"
4474 [(set_attr "type" "fmov")
4475 (set_attr "mode" "SF")])
4477 (define_insn "*truncdfsf_mixed"
4478 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4480 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4481 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4482 "TARGET_MIX_SSE_I387"
4484 switch (which_alternative)
4487 return output_387_reg_move (insn, operands);
4489 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4495 [(set_attr "isa" "*,sse2,*,*,*")
4496 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4497 (set_attr "unit" "*,*,i387,i387,i387")
4498 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4499 (set_attr "mode" "SF")])
4501 (define_insn "*truncdfsf_i387"
4502 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4504 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4505 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4508 switch (which_alternative)
4511 return output_387_reg_move (insn, operands);
4517 [(set_attr "type" "fmov,multi,multi,multi")
4518 (set_attr "unit" "*,i387,i387,i387")
4519 (set_attr "mode" "SF")])
4521 (define_insn "*truncdfsf2_i387_1"
4522 [(set (match_operand:SF 0 "memory_operand" "=m")
4524 (match_operand:DF 1 "register_operand" "f")))]
4526 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4527 && !TARGET_MIX_SSE_I387"
4528 "* return output_387_reg_move (insn, operands);"
4529 [(set_attr "type" "fmov")
4530 (set_attr "mode" "SF")])
4533 [(set (match_operand:SF 0 "register_operand")
4535 (match_operand:DF 1 "fp_register_operand")))
4536 (clobber (match_operand 2))]
4538 [(set (match_dup 2) (match_dup 1))
4539 (set (match_dup 0) (match_dup 2))]
4540 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4542 ;; Conversion from XFmode to {SF,DF}mode
4544 (define_expand "truncxf<mode>2"
4545 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4546 (float_truncate:MODEF
4547 (match_operand:XF 1 "register_operand")))
4548 (clobber (match_dup 2))])]
4551 if (flag_unsafe_math_optimizations)
4553 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4554 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4555 if (reg != operands[0])
4556 emit_move_insn (operands[0], reg);
4560 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4563 (define_insn "*truncxfsf2_mixed"
4564 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4566 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4567 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4570 gcc_assert (!which_alternative);
4571 return output_387_reg_move (insn, operands);
4573 [(set_attr "type" "fmov,multi,multi,multi")
4574 (set_attr "unit" "*,i387,i387,i387")
4575 (set_attr "mode" "SF")])
4577 (define_insn "*truncxfdf2_mixed"
4578 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4580 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4581 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4584 gcc_assert (!which_alternative);
4585 return output_387_reg_move (insn, operands);
4587 [(set_attr "isa" "*,*,sse2,*")
4588 (set_attr "type" "fmov,multi,multi,multi")
4589 (set_attr "unit" "*,i387,i387,i387")
4590 (set_attr "mode" "DF")])
4592 (define_insn "truncxf<mode>2_i387_noop"
4593 [(set (match_operand:MODEF 0 "register_operand" "=f")
4594 (float_truncate:MODEF
4595 (match_operand:XF 1 "register_operand" "f")))]
4596 "TARGET_80387 && flag_unsafe_math_optimizations"
4597 "* return output_387_reg_move (insn, operands);"
4598 [(set_attr "type" "fmov")
4599 (set_attr "mode" "<MODE>")])
4601 (define_insn "*truncxf<mode>2_i387"
4602 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4603 (float_truncate:MODEF
4604 (match_operand:XF 1 "register_operand" "f")))]
4606 "* return output_387_reg_move (insn, operands);"
4607 [(set_attr "type" "fmov")
4608 (set_attr "mode" "<MODE>")])
4611 [(set (match_operand:MODEF 0 "register_operand")
4612 (float_truncate:MODEF
4613 (match_operand:XF 1 "register_operand")))
4614 (clobber (match_operand:MODEF 2 "memory_operand"))]
4615 "TARGET_80387 && reload_completed"
4616 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4617 (set (match_dup 0) (match_dup 2))])
4620 [(set (match_operand:MODEF 0 "memory_operand")
4621 (float_truncate:MODEF
4622 (match_operand:XF 1 "register_operand")))
4623 (clobber (match_operand:MODEF 2 "memory_operand"))]
4625 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4627 ;; Signed conversion to DImode.
4629 (define_expand "fix_truncxfdi2"
4630 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4631 (fix:DI (match_operand:XF 1 "register_operand")))
4632 (clobber (reg:CC FLAGS_REG))])]
4637 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4642 (define_expand "fix_trunc<mode>di2"
4643 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4644 (fix:DI (match_operand:MODEF 1 "register_operand")))
4645 (clobber (reg:CC FLAGS_REG))])]
4646 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4649 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4651 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4654 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4656 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4657 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4658 if (out != operands[0])
4659 emit_move_insn (operands[0], out);
4664 ;; Signed conversion to SImode.
4666 (define_expand "fix_truncxfsi2"
4667 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4668 (fix:SI (match_operand:XF 1 "register_operand")))
4669 (clobber (reg:CC FLAGS_REG))])]
4674 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4679 (define_expand "fix_trunc<mode>si2"
4680 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4681 (fix:SI (match_operand:MODEF 1 "register_operand")))
4682 (clobber (reg:CC FLAGS_REG))])]
4683 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4686 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4688 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4691 if (SSE_FLOAT_MODE_P (<MODE>mode))
4693 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4694 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4695 if (out != operands[0])
4696 emit_move_insn (operands[0], out);
4701 ;; Signed conversion to HImode.
4703 (define_expand "fix_trunc<mode>hi2"
4704 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4705 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4706 (clobber (reg:CC FLAGS_REG))])]
4708 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4712 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4717 ;; Unsigned conversion to SImode.
4719 (define_expand "fixuns_trunc<mode>si2"
4721 [(set (match_operand:SI 0 "register_operand")
4723 (match_operand:MODEF 1 "nonimmediate_operand")))
4725 (clobber (match_scratch:<ssevecmode> 3))
4726 (clobber (match_scratch:<ssevecmode> 4))])]
4727 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4729 machine_mode mode = <MODE>mode;
4730 machine_mode vecmode = <ssevecmode>mode;
4731 REAL_VALUE_TYPE TWO31r;
4734 if (optimize_insn_for_size_p ())
4737 real_ldexp (&TWO31r, &dconst1, 31);
4738 two31 = const_double_from_real_value (TWO31r, mode);
4739 two31 = ix86_build_const_vector (vecmode, true, two31);
4740 operands[2] = force_reg (vecmode, two31);
4743 (define_insn_and_split "*fixuns_trunc<mode>_1"
4744 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4746 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4747 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4748 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4749 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4750 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4751 && optimize_function_for_speed_p (cfun)"
4753 "&& reload_completed"
4756 ix86_split_convert_uns_si_sse (operands);
4760 ;; Unsigned conversion to HImode.
4761 ;; Without these patterns, we'll try the unsigned SI conversion which
4762 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4764 (define_expand "fixuns_trunc<mode>hi2"
4766 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4767 (set (match_operand:HI 0 "nonimmediate_operand")
4768 (subreg:HI (match_dup 2) 0))]
4769 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4770 "operands[2] = gen_reg_rtx (SImode);")
4772 ;; When SSE is available, it is always faster to use it!
4773 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4774 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4775 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
4776 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4777 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4778 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4779 [(set_attr "type" "sseicvt")
4780 (set_attr "prefix" "maybe_vex")
4781 (set (attr "prefix_rex")
4783 (match_test "<SWI48:MODE>mode == DImode")
4785 (const_string "*")))
4786 (set_attr "mode" "<MODEF:MODE>")
4787 (set_attr "athlon_decode" "double,vector")
4788 (set_attr "amdfam10_decode" "double,double")
4789 (set_attr "bdver1_decode" "double,double")])
4791 ;; Avoid vector decoded forms of the instruction.
4793 [(match_scratch:MODEF 2 "x")
4794 (set (match_operand:SWI48 0 "register_operand")
4795 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4796 "TARGET_AVOID_VECTOR_DECODE
4797 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4798 && optimize_insn_for_speed_p ()"
4799 [(set (match_dup 2) (match_dup 1))
4800 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4802 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4803 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4804 (fix:SWI248x (match_operand 1 "register_operand")))]
4805 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4807 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4808 && (TARGET_64BIT || <MODE>mode != DImode))
4810 && can_create_pseudo_p ()"
4815 if (memory_operand (operands[0], VOIDmode))
4816 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4819 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4820 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4826 [(set_attr "type" "fisttp")
4827 (set_attr "mode" "<MODE>")])
4829 (define_insn "fix_trunc<mode>_i387_fisttp"
4830 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4831 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4832 (clobber (match_scratch:XF 2 "=&1f"))]
4833 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4835 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4836 && (TARGET_64BIT || <MODE>mode != DImode))
4837 && TARGET_SSE_MATH)"
4838 "* return output_fix_trunc (insn, operands, true);"
4839 [(set_attr "type" "fisttp")
4840 (set_attr "mode" "<MODE>")])
4842 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4843 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4844 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4845 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4846 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4847 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4849 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4850 && (TARGET_64BIT || <MODE>mode != DImode))
4851 && TARGET_SSE_MATH)"
4853 [(set_attr "type" "fisttp")
4854 (set_attr "mode" "<MODE>")])
4857 [(set (match_operand:SWI248x 0 "register_operand")
4858 (fix:SWI248x (match_operand 1 "register_operand")))
4859 (clobber (match_operand:SWI248x 2 "memory_operand"))
4860 (clobber (match_scratch 3))]
4862 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4863 (clobber (match_dup 3))])
4864 (set (match_dup 0) (match_dup 2))])
4867 [(set (match_operand:SWI248x 0 "memory_operand")
4868 (fix:SWI248x (match_operand 1 "register_operand")))
4869 (clobber (match_operand:SWI248x 2 "memory_operand"))
4870 (clobber (match_scratch 3))]
4872 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4873 (clobber (match_dup 3))])])
4875 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4876 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4877 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4878 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4879 ;; function in i386.c.
4880 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4881 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4882 (fix:SWI248x (match_operand 1 "register_operand")))
4883 (clobber (reg:CC FLAGS_REG))]
4884 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4886 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4887 && (TARGET_64BIT || <MODE>mode != DImode))
4888 && can_create_pseudo_p ()"
4893 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4895 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4896 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4897 if (memory_operand (operands[0], VOIDmode))
4898 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4899 operands[2], operands[3]));
4902 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4903 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4904 operands[2], operands[3],
4909 [(set_attr "type" "fistp")
4910 (set_attr "i387_cw" "trunc")
4911 (set_attr "mode" "<MODE>")])
4913 (define_insn "fix_truncdi_i387"
4914 [(set (match_operand:DI 0 "memory_operand" "=m")
4915 (fix:DI (match_operand 1 "register_operand" "f")))
4916 (use (match_operand:HI 2 "memory_operand" "m"))
4917 (use (match_operand:HI 3 "memory_operand" "m"))
4918 (clobber (match_scratch:XF 4 "=&1f"))]
4919 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4921 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4922 "* return output_fix_trunc (insn, operands, false);"
4923 [(set_attr "type" "fistp")
4924 (set_attr "i387_cw" "trunc")
4925 (set_attr "mode" "DI")])
4927 (define_insn "fix_truncdi_i387_with_temp"
4928 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4929 (fix:DI (match_operand 1 "register_operand" "f,f")))
4930 (use (match_operand:HI 2 "memory_operand" "m,m"))
4931 (use (match_operand:HI 3 "memory_operand" "m,m"))
4932 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4933 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4934 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4936 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4938 [(set_attr "type" "fistp")
4939 (set_attr "i387_cw" "trunc")
4940 (set_attr "mode" "DI")])
4943 [(set (match_operand:DI 0 "register_operand")
4944 (fix:DI (match_operand 1 "register_operand")))
4945 (use (match_operand:HI 2 "memory_operand"))
4946 (use (match_operand:HI 3 "memory_operand"))
4947 (clobber (match_operand:DI 4 "memory_operand"))
4948 (clobber (match_scratch 5))]
4950 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4953 (clobber (match_dup 5))])
4954 (set (match_dup 0) (match_dup 4))])
4957 [(set (match_operand:DI 0 "memory_operand")
4958 (fix:DI (match_operand 1 "register_operand")))
4959 (use (match_operand:HI 2 "memory_operand"))
4960 (use (match_operand:HI 3 "memory_operand"))
4961 (clobber (match_operand:DI 4 "memory_operand"))
4962 (clobber (match_scratch 5))]
4964 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4967 (clobber (match_dup 5))])])
4969 (define_insn "fix_trunc<mode>_i387"
4970 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4971 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4972 (use (match_operand:HI 2 "memory_operand" "m"))
4973 (use (match_operand:HI 3 "memory_operand" "m"))]
4974 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4976 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4977 "* return output_fix_trunc (insn, operands, false);"
4978 [(set_attr "type" "fistp")
4979 (set_attr "i387_cw" "trunc")
4980 (set_attr "mode" "<MODE>")])
4982 (define_insn "fix_trunc<mode>_i387_with_temp"
4983 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4984 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4985 (use (match_operand:HI 2 "memory_operand" "m,m"))
4986 (use (match_operand:HI 3 "memory_operand" "m,m"))
4987 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4988 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4990 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4992 [(set_attr "type" "fistp")
4993 (set_attr "i387_cw" "trunc")
4994 (set_attr "mode" "<MODE>")])
4997 [(set (match_operand:SWI24 0 "register_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 4) (fix:SWI24 (match_dup 1)))
5005 (use (match_dup 3))])
5006 (set (match_dup 0) (match_dup 4))])
5009 [(set (match_operand:SWI24 0 "memory_operand")
5010 (fix:SWI24 (match_operand 1 "register_operand")))
5011 (use (match_operand:HI 2 "memory_operand"))
5012 (use (match_operand:HI 3 "memory_operand"))
5013 (clobber (match_operand:SWI24 4 "memory_operand"))]
5015 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
5017 (use (match_dup 3))])])
5019 (define_insn "x86_fnstcw_1"
5020 [(set (match_operand:HI 0 "memory_operand" "=m")
5021 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5024 [(set (attr "length")
5025 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5026 (set_attr "mode" "HI")
5027 (set_attr "unit" "i387")
5028 (set_attr "bdver1_decode" "vector")])
5030 (define_insn "x86_fldcw_1"
5031 [(set (reg:HI FPCR_REG)
5032 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5035 [(set (attr "length")
5036 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5037 (set_attr "mode" "HI")
5038 (set_attr "unit" "i387")
5039 (set_attr "athlon_decode" "vector")
5040 (set_attr "amdfam10_decode" "vector")
5041 (set_attr "bdver1_decode" "vector")])
5043 ;; Conversion between fixed point and floating point.
5045 ;; Even though we only accept memory inputs, the backend _really_
5046 ;; wants to be able to do this between registers. Thankfully, LRA
5047 ;; will fix this up for us during register allocation.
5049 (define_insn "floathi<mode>2"
5050 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5051 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5053 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5054 || TARGET_MIX_SSE_I387)"
5056 [(set_attr "type" "fmov")
5057 (set_attr "mode" "<MODE>")
5058 (set_attr "znver1_decode" "double")
5059 (set_attr "fp_int_src" "true")])
5061 (define_insn "float<SWI48x:mode>xf2"
5062 [(set (match_operand:XF 0 "register_operand" "=f")
5063 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5066 [(set_attr "type" "fmov")
5067 (set_attr "mode" "XF")
5068 (set_attr "znver1_decode" "double")
5069 (set_attr "fp_int_src" "true")])
5071 (define_expand "float<SWI48:mode><MODEF:mode>2"
5072 [(set (match_operand:MODEF 0 "register_operand")
5073 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5074 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5076 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
5077 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5079 rtx reg = gen_reg_rtx (XFmode);
5080 rtx (*insn)(rtx, rtx);
5082 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
5084 if (<MODEF:MODE>mode == SFmode)
5085 insn = gen_truncxfsf2;
5086 else if (<MODEF:MODE>mode == DFmode)
5087 insn = gen_truncxfdf2;
5091 emit_insn (insn (operands[0], reg));
5096 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed"
5097 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5099 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5100 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5103 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5104 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5105 [(set_attr "type" "fmov,sseicvt,sseicvt")
5106 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5107 (set_attr "mode" "<MODEF:MODE>")
5108 (set (attr "prefix_rex")
5110 (and (eq_attr "prefix" "maybe_vex")
5111 (match_test "<SWI48:MODE>mode == DImode"))
5113 (const_string "*")))
5114 (set_attr "unit" "i387,*,*")
5115 (set_attr "athlon_decode" "*,double,direct")
5116 (set_attr "amdfam10_decode" "*,vector,double")
5117 (set_attr "bdver1_decode" "*,double,direct")
5118 (set_attr "znver1_decode" "double,*,*")
5119 (set_attr "fp_int_src" "true")
5120 (set (attr "enabled")
5121 (cond [(eq_attr "alternative" "0")
5122 (symbol_ref "TARGET_MIX_SSE_I387
5123 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5126 (symbol_ref "true")))
5127 (set (attr "preferred_for_speed")
5128 (cond [(eq_attr "alternative" "1")
5129 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5130 (symbol_ref "true")))])
5132 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
5133 [(set (match_operand:MODEF 0 "register_operand" "=f")
5134 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5135 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
5137 [(set_attr "type" "fmov")
5138 (set_attr "mode" "<MODEF:MODE>")
5139 (set_attr "znver1_decode" "double")
5140 (set_attr "fp_int_src" "true")])
5142 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5143 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5144 ;; alternative in sse2_loadld.
5146 [(set (match_operand:MODEF 0 "register_operand")
5147 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5148 "TARGET_SSE2 && TARGET_SSE_MATH
5149 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5150 && reload_completed && SSE_REG_P (operands[0])
5151 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5152 && (!EXT_REX_SSE_REG_P (operands[0])
5153 || TARGET_AVX512VL)"
5156 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5158 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5160 emit_insn (gen_sse2_loadld (operands[4],
5161 CONST0_RTX (V4SImode), operands[1]));
5163 if (<ssevecmode>mode == V4SFmode)
5164 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5166 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5170 ;; Avoid partial SSE register dependency stalls
5172 [(set (match_operand:MODEF 0 "register_operand")
5173 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5174 "TARGET_SSE2 && TARGET_SSE_MATH
5175 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5176 && optimize_function_for_speed_p (cfun)
5177 && reload_completed && SSE_REG_P (operands[0])
5178 && (!EXT_REX_SSE_REG_P (operands[0])
5179 || TARGET_AVX512VL)"
5182 const machine_mode vmode = <MODEF:ssevecmode>mode;
5183 const machine_mode mode = <MODEF:MODE>mode;
5184 rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
5186 emit_move_insn (op0, CONST0_RTX (vmode));
5188 t = gen_rtx_FLOAT (mode, operands[1]);
5189 t = gen_rtx_VEC_DUPLICATE (vmode, t);
5190 t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
5191 emit_insn (gen_rtx_SET (op0, t));
5195 ;; Break partial reg stall for cvtsd2ss.
5198 [(set (match_operand:SF 0 "register_operand")
5200 (match_operand:DF 1 "nonimmediate_operand")))]
5201 "TARGET_SSE2 && TARGET_SSE_MATH
5202 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5203 && optimize_function_for_speed_p (cfun)
5204 && SSE_REG_P (operands[0])
5205 && (!SSE_REG_P (operands[1])
5206 || REGNO (operands[0]) != REGNO (operands[1]))
5207 && (!EXT_REX_SSE_REG_P (operands[0])
5208 || TARGET_AVX512VL)"
5212 (float_truncate:V2SF
5217 operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
5219 operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
5221 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5224 ;; Break partial reg stall for cvtss2sd.
5227 [(set (match_operand:DF 0 "register_operand")
5229 (match_operand:SF 1 "nonimmediate_operand")))]
5230 "TARGET_SSE2 && TARGET_SSE_MATH
5231 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5232 && optimize_function_for_speed_p (cfun)
5233 && SSE_REG_P (operands[0])
5234 && (!SSE_REG_P (operands[1])
5235 || REGNO (operands[0]) != REGNO (operands[1]))
5236 && (!EXT_REX_SSE_REG_P (operands[0])
5237 || TARGET_AVX512VL)"
5243 (parallel [(const_int 0) (const_int 1)])))
5247 operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
5249 operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
5251 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5254 ;; Avoid store forwarding (partial memory) stall penalty
5255 ;; by passing DImode value through XMM registers. */
5257 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5258 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5260 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5261 (clobber (match_scratch:V4SI 3 "=X,x"))
5262 (clobber (match_scratch:V4SI 4 "=X,x"))
5263 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5264 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5265 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5266 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5268 [(set_attr "type" "multi")
5269 (set_attr "mode" "<X87MODEF:MODE>")
5270 (set_attr "unit" "i387")
5271 (set_attr "fp_int_src" "true")])
5274 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5275 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5276 (clobber (match_scratch:V4SI 3))
5277 (clobber (match_scratch:V4SI 4))
5278 (clobber (match_operand:DI 2 "memory_operand"))]
5279 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5280 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5281 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5282 && reload_completed"
5283 [(set (match_dup 2) (match_dup 3))
5284 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5286 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5287 Assemble the 64-bit DImode value in an xmm register. */
5288 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5289 gen_lowpart (SImode, operands[1])));
5290 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5291 gen_highpart (SImode, operands[1])));
5292 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5295 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5299 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5300 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5301 (clobber (match_scratch:V4SI 3))
5302 (clobber (match_scratch:V4SI 4))
5303 (clobber (match_operand:DI 2 "memory_operand"))]
5304 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5305 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5306 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5307 && reload_completed"
5308 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5310 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5311 [(set (match_operand:MODEF 0 "register_operand")
5312 (unsigned_float:MODEF
5313 (match_operand:SWI12 1 "nonimmediate_operand")))]
5315 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5317 operands[1] = convert_to_mode (SImode, operands[1], 1);
5318 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5322 ;; Avoid store forwarding (partial memory) stall penalty by extending
5323 ;; SImode value to DImode through XMM register instead of pushing two
5324 ;; SImode values to stack. Also note that fild loads from memory only.
5326 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5327 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5328 (unsigned_float:X87MODEF
5329 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5330 (clobber (match_scratch:DI 3 "=x"))
5331 (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5333 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5334 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5336 "&& reload_completed"
5337 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5338 (set (match_dup 2) (match_dup 3))
5340 (float:X87MODEF (match_dup 2)))]
5342 [(set_attr "type" "multi")
5343 (set_attr "mode" "<MODE>")])
5345 (define_expand "floatunssi<mode>2"
5347 [(set (match_operand:X87MODEF 0 "register_operand")
5348 (unsigned_float:X87MODEF
5349 (match_operand:SI 1 "nonimmediate_operand")))
5350 (clobber (match_scratch:DI 3))
5351 (clobber (match_dup 2))])]
5353 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5354 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5355 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5357 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5359 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5363 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5366 (define_expand "floatunsdisf2"
5367 [(use (match_operand:SF 0 "register_operand"))
5368 (use (match_operand:DI 1 "nonimmediate_operand"))]
5369 "TARGET_64BIT && TARGET_SSE_MATH"
5370 "x86_emit_floatuns (operands); DONE;")
5372 (define_expand "floatunsdidf2"
5373 [(use (match_operand:DF 0 "register_operand"))
5374 (use (match_operand:DI 1 "nonimmediate_operand"))]
5375 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5376 && TARGET_SSE2 && TARGET_SSE_MATH"
5379 x86_emit_floatuns (operands);
5381 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5385 ;; Load effective address instructions
5387 (define_insn_and_split "*lea<mode>"
5388 [(set (match_operand:SWI48 0 "register_operand" "=r")
5389 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5392 if (SImode_address_operand (operands[1], VOIDmode))
5394 gcc_assert (TARGET_64BIT);
5395 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5398 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5400 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5403 machine_mode mode = <MODE>mode;
5406 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5407 change operands[] array behind our back. */
5408 pat = PATTERN (curr_insn);
5410 operands[0] = SET_DEST (pat);
5411 operands[1] = SET_SRC (pat);
5413 /* Emit all operations in SImode for zero-extended addresses. */
5414 if (SImode_address_operand (operands[1], VOIDmode))
5417 ix86_split_lea_for_addr (curr_insn, operands, mode);
5419 /* Zero-extend return register to DImode for zero-extended addresses. */
5420 if (mode != <MODE>mode)
5421 emit_insn (gen_zero_extendsidi2
5422 (operands[0], gen_lowpart (mode, operands[0])));
5426 [(set_attr "type" "lea")
5429 (match_operand 1 "SImode_address_operand")
5431 (const_string "<MODE>")))])
5435 (define_expand "add<mode>3"
5436 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5437 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5438 (match_operand:SDWIM 2 "<general_operand>")))]
5440 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5442 (define_insn_and_split "*add<dwi>3_doubleword"
5443 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5445 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5446 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5447 (clobber (reg:CC FLAGS_REG))]
5448 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5451 [(parallel [(set (reg:CCC FLAGS_REG)
5453 (plus:DWIH (match_dup 1) (match_dup 2))
5456 (plus:DWIH (match_dup 1) (match_dup 2)))])
5457 (parallel [(set (match_dup 3)
5460 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5463 (clobber (reg:CC FLAGS_REG))])]
5465 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5466 if (operands[2] == const0_rtx)
5468 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5473 (define_insn "*add<mode>_1"
5474 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5476 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5477 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5478 (clobber (reg:CC FLAGS_REG))]
5479 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5481 switch (get_attr_type (insn))
5487 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5488 if (operands[2] == const1_rtx)
5489 return "inc{<imodesuffix>}\t%0";
5492 gcc_assert (operands[2] == constm1_rtx);
5493 return "dec{<imodesuffix>}\t%0";
5497 /* For most processors, ADD is faster than LEA. This alternative
5498 was added to use ADD as much as possible. */
5499 if (which_alternative == 2)
5500 std::swap (operands[1], operands[2]);
5502 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5503 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5504 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5506 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5510 (cond [(eq_attr "alternative" "3")
5511 (const_string "lea")
5512 (match_operand:SWI48 2 "incdec_operand")
5513 (const_string "incdec")
5515 (const_string "alu")))
5516 (set (attr "length_immediate")
5518 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5520 (const_string "*")))
5521 (set_attr "mode" "<MODE>")])
5523 ;; It may seem that nonimmediate operand is proper one for operand 1.
5524 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5525 ;; we take care in ix86_binary_operator_ok to not allow two memory
5526 ;; operands so proper swapping will be done in reload. This allow
5527 ;; patterns constructed from addsi_1 to match.
5529 (define_insn "addsi_1_zext"
5530 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5532 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5533 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5534 (clobber (reg:CC FLAGS_REG))]
5535 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5537 switch (get_attr_type (insn))
5543 if (operands[2] == const1_rtx)
5544 return "inc{l}\t%k0";
5547 gcc_assert (operands[2] == constm1_rtx);
5548 return "dec{l}\t%k0";
5552 /* For most processors, ADD is faster than LEA. This alternative
5553 was added to use ADD as much as possible. */
5554 if (which_alternative == 1)
5555 std::swap (operands[1], operands[2]);
5557 if (x86_maybe_negate_const_int (&operands[2], SImode))
5558 return "sub{l}\t{%2, %k0|%k0, %2}";
5560 return "add{l}\t{%2, %k0|%k0, %2}";
5564 (cond [(eq_attr "alternative" "2")
5565 (const_string "lea")
5566 (match_operand:SI 2 "incdec_operand")
5567 (const_string "incdec")
5569 (const_string "alu")))
5570 (set (attr "length_immediate")
5572 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5574 (const_string "*")))
5575 (set_attr "mode" "SI")])
5577 (define_insn "*addhi_1"
5578 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5579 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5580 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5581 (clobber (reg:CC FLAGS_REG))]
5582 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5584 switch (get_attr_type (insn))
5590 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5591 if (operands[2] == const1_rtx)
5592 return "inc{w}\t%0";
5595 gcc_assert (operands[2] == constm1_rtx);
5596 return "dec{w}\t%0";
5600 /* For most processors, ADD is faster than LEA. This alternative
5601 was added to use ADD as much as possible. */
5602 if (which_alternative == 2)
5603 std::swap (operands[1], operands[2]);
5605 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5606 if (x86_maybe_negate_const_int (&operands[2], HImode))
5607 return "sub{w}\t{%2, %0|%0, %2}";
5609 return "add{w}\t{%2, %0|%0, %2}";
5613 (cond [(eq_attr "alternative" "3")
5614 (const_string "lea")
5615 (match_operand:HI 2 "incdec_operand")
5616 (const_string "incdec")
5618 (const_string "alu")))
5619 (set (attr "length_immediate")
5621 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5623 (const_string "*")))
5624 (set_attr "mode" "HI,HI,HI,SI")])
5626 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5627 (define_insn "*addqi_1"
5628 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5629 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5630 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5631 (clobber (reg:CC FLAGS_REG))]
5632 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5634 bool widen = (which_alternative == 3 || which_alternative == 4);
5636 switch (get_attr_type (insn))
5642 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5643 if (operands[2] == const1_rtx)
5644 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5647 gcc_assert (operands[2] == constm1_rtx);
5648 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5652 /* For most processors, ADD is faster than LEA. These alternatives
5653 were added to use ADD as much as possible. */
5654 if (which_alternative == 2 || which_alternative == 4)
5655 std::swap (operands[1], operands[2]);
5657 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5658 if (x86_maybe_negate_const_int (&operands[2], QImode))
5661 return "sub{l}\t{%2, %k0|%k0, %2}";
5663 return "sub{b}\t{%2, %0|%0, %2}";
5666 return "add{l}\t{%k2, %k0|%k0, %k2}";
5668 return "add{b}\t{%2, %0|%0, %2}";
5672 (cond [(eq_attr "alternative" "5")
5673 (const_string "lea")
5674 (match_operand:QI 2 "incdec_operand")
5675 (const_string "incdec")
5677 (const_string "alu")))
5678 (set (attr "length_immediate")
5680 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5682 (const_string "*")))
5683 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5685 (define_insn "*addqi_1_slp"
5686 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5687 (plus:QI (match_dup 0)
5688 (match_operand:QI 1 "general_operand" "qn,qm")))
5689 (clobber (reg:CC FLAGS_REG))]
5690 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5691 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5693 switch (get_attr_type (insn))
5696 if (operands[1] == const1_rtx)
5697 return "inc{b}\t%0";
5700 gcc_assert (operands[1] == constm1_rtx);
5701 return "dec{b}\t%0";
5705 if (x86_maybe_negate_const_int (&operands[1], QImode))
5706 return "sub{b}\t{%1, %0|%0, %1}";
5708 return "add{b}\t{%1, %0|%0, %1}";
5712 (if_then_else (match_operand:QI 1 "incdec_operand")
5713 (const_string "incdec")
5714 (const_string "alu1")))
5715 (set (attr "memory")
5716 (if_then_else (match_operand 1 "memory_operand")
5717 (const_string "load")
5718 (const_string "none")))
5719 (set_attr "mode" "QI")])
5721 ;; Split non destructive adds if we cannot use lea.
5723 [(set (match_operand:SWI48 0 "register_operand")
5724 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5725 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5726 (clobber (reg:CC FLAGS_REG))]
5727 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5728 [(set (match_dup 0) (match_dup 1))
5729 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5730 (clobber (reg:CC FLAGS_REG))])])
5732 ;; Convert add to the lea pattern to avoid flags dependency.
5734 [(set (match_operand:SWI 0 "register_operand")
5735 (plus:SWI (match_operand:SWI 1 "register_operand")
5736 (match_operand:SWI 2 "<nonmemory_operand>")))
5737 (clobber (reg:CC FLAGS_REG))]
5738 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5741 machine_mode mode = <MODE>mode;
5744 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5747 operands[0] = gen_lowpart (mode, operands[0]);
5748 operands[1] = gen_lowpart (mode, operands[1]);
5749 operands[2] = gen_lowpart (mode, operands[2]);
5752 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5754 emit_insn (gen_rtx_SET (operands[0], pat));
5758 ;; Split non destructive adds if we cannot use lea.
5760 [(set (match_operand:DI 0 "register_operand")
5762 (plus:SI (match_operand:SI 1 "register_operand")
5763 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5764 (clobber (reg:CC FLAGS_REG))]
5766 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5767 [(set (match_dup 3) (match_dup 1))
5768 (parallel [(set (match_dup 0)
5769 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5770 (clobber (reg:CC FLAGS_REG))])]
5771 "operands[3] = gen_lowpart (SImode, operands[0]);")
5773 ;; Convert add to the lea pattern to avoid flags dependency.
5775 [(set (match_operand:DI 0 "register_operand")
5777 (plus:SI (match_operand:SI 1 "register_operand")
5778 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5779 (clobber (reg:CC FLAGS_REG))]
5780 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5782 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5784 (define_insn "*add<mode>_2"
5785 [(set (reg FLAGS_REG)
5788 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5789 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5791 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5792 (plus:SWI (match_dup 1) (match_dup 2)))]
5793 "ix86_match_ccmode (insn, CCGOCmode)
5794 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5796 switch (get_attr_type (insn))
5799 if (operands[2] == const1_rtx)
5800 return "inc{<imodesuffix>}\t%0";
5803 gcc_assert (operands[2] == constm1_rtx);
5804 return "dec{<imodesuffix>}\t%0";
5808 if (which_alternative == 2)
5809 std::swap (operands[1], operands[2]);
5811 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5812 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5813 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5815 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5819 (if_then_else (match_operand:SWI 2 "incdec_operand")
5820 (const_string "incdec")
5821 (const_string "alu")))
5822 (set (attr "length_immediate")
5824 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5826 (const_string "*")))
5827 (set_attr "mode" "<MODE>")])
5829 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5830 (define_insn "*addsi_2_zext"
5831 [(set (reg FLAGS_REG)
5833 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5834 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5836 (set (match_operand:DI 0 "register_operand" "=r,r")
5837 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5838 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5839 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5841 switch (get_attr_type (insn))
5844 if (operands[2] == const1_rtx)
5845 return "inc{l}\t%k0";
5848 gcc_assert (operands[2] == constm1_rtx);
5849 return "dec{l}\t%k0";
5853 if (which_alternative == 1)
5854 std::swap (operands[1], operands[2]);
5856 if (x86_maybe_negate_const_int (&operands[2], SImode))
5857 return "sub{l}\t{%2, %k0|%k0, %2}";
5859 return "add{l}\t{%2, %k0|%k0, %2}";
5863 (if_then_else (match_operand:SI 2 "incdec_operand")
5864 (const_string "incdec")
5865 (const_string "alu")))
5866 (set (attr "length_immediate")
5868 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5870 (const_string "*")))
5871 (set_attr "mode" "SI")])
5873 (define_insn "*add<mode>_3"
5874 [(set (reg FLAGS_REG)
5876 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5877 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5878 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5879 "ix86_match_ccmode (insn, CCZmode)
5880 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5882 switch (get_attr_type (insn))
5885 if (operands[2] == const1_rtx)
5886 return "inc{<imodesuffix>}\t%0";
5889 gcc_assert (operands[2] == constm1_rtx);
5890 return "dec{<imodesuffix>}\t%0";
5894 if (which_alternative == 1)
5895 std::swap (operands[1], operands[2]);
5897 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5898 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5899 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5901 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5905 (if_then_else (match_operand:SWI 2 "incdec_operand")
5906 (const_string "incdec")
5907 (const_string "alu")))
5908 (set (attr "length_immediate")
5910 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5912 (const_string "*")))
5913 (set_attr "mode" "<MODE>")])
5915 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5916 (define_insn "*addsi_3_zext"
5917 [(set (reg FLAGS_REG)
5919 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5920 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5921 (set (match_operand:DI 0 "register_operand" "=r,r")
5922 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5923 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5924 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5926 switch (get_attr_type (insn))
5929 if (operands[2] == const1_rtx)
5930 return "inc{l}\t%k0";
5933 gcc_assert (operands[2] == constm1_rtx);
5934 return "dec{l}\t%k0";
5938 if (which_alternative == 1)
5939 std::swap (operands[1], operands[2]);
5941 if (x86_maybe_negate_const_int (&operands[2], SImode))
5942 return "sub{l}\t{%2, %k0|%k0, %2}";
5944 return "add{l}\t{%2, %k0|%k0, %2}";
5948 (if_then_else (match_operand:SI 2 "incdec_operand")
5949 (const_string "incdec")
5950 (const_string "alu")))
5951 (set (attr "length_immediate")
5953 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5955 (const_string "*")))
5956 (set_attr "mode" "SI")])
5958 ; For comparisons against 1, -1 and 128, we may generate better code
5959 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5960 ; is matched then. We can't accept general immediate, because for
5961 ; case of overflows, the result is messed up.
5962 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5963 ; only for comparisons not depending on it.
5965 (define_insn "*adddi_4"
5966 [(set (reg FLAGS_REG)
5968 (match_operand:DI 1 "nonimmediate_operand" "0")
5969 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5970 (clobber (match_scratch:DI 0 "=rm"))]
5972 && ix86_match_ccmode (insn, CCGCmode)"
5974 switch (get_attr_type (insn))
5977 if (operands[2] == constm1_rtx)
5978 return "inc{q}\t%0";
5981 gcc_assert (operands[2] == const1_rtx);
5982 return "dec{q}\t%0";
5986 if (x86_maybe_negate_const_int (&operands[2], DImode))
5987 return "add{q}\t{%2, %0|%0, %2}";
5989 return "sub{q}\t{%2, %0|%0, %2}";
5993 (if_then_else (match_operand:DI 2 "incdec_operand")
5994 (const_string "incdec")
5995 (const_string "alu")))
5996 (set (attr "length_immediate")
5998 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6000 (const_string "*")))
6001 (set_attr "mode" "DI")])
6003 ; For comparisons against 1, -1 and 128, we may generate better code
6004 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6005 ; is matched then. We can't accept general immediate, because for
6006 ; case of overflows, the result is messed up.
6007 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6008 ; only for comparisons not depending on it.
6010 (define_insn "*add<mode>_4"
6011 [(set (reg FLAGS_REG)
6013 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6014 (match_operand:SWI124 2 "const_int_operand" "n")))
6015 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6016 "ix86_match_ccmode (insn, CCGCmode)"
6018 switch (get_attr_type (insn))
6021 if (operands[2] == constm1_rtx)
6022 return "inc{<imodesuffix>}\t%0";
6025 gcc_assert (operands[2] == const1_rtx);
6026 return "dec{<imodesuffix>}\t%0";
6030 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6031 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6033 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6037 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6038 (const_string "incdec")
6039 (const_string "alu")))
6040 (set (attr "length_immediate")
6042 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6044 (const_string "*")))
6045 (set_attr "mode" "<MODE>")])
6047 (define_insn "*add<mode>_5"
6048 [(set (reg FLAGS_REG)
6051 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6052 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6054 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6055 "ix86_match_ccmode (insn, CCGOCmode)
6056 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6058 switch (get_attr_type (insn))
6061 if (operands[2] == const1_rtx)
6062 return "inc{<imodesuffix>}\t%0";
6065 gcc_assert (operands[2] == constm1_rtx);
6066 return "dec{<imodesuffix>}\t%0";
6070 if (which_alternative == 1)
6071 std::swap (operands[1], operands[2]);
6073 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6074 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6075 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6077 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6081 (if_then_else (match_operand:SWI 2 "incdec_operand")
6082 (const_string "incdec")
6083 (const_string "alu")))
6084 (set (attr "length_immediate")
6086 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6088 (const_string "*")))
6089 (set_attr "mode" "<MODE>")])
6091 (define_insn "addqi_ext_1"
6092 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
6097 (match_operand 1 "ext_register_operand" "0,0")
6100 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
6101 (clobber (reg:CC FLAGS_REG))]
6104 switch (get_attr_type (insn))
6107 if (operands[2] == const1_rtx)
6108 return "inc{b}\t%h0";
6111 gcc_assert (operands[2] == constm1_rtx);
6112 return "dec{b}\t%h0";
6116 return "add{b}\t{%2, %h0|%h0, %2}";
6119 [(set_attr "isa" "*,nox64")
6121 (if_then_else (match_operand:QI 2 "incdec_operand")
6122 (const_string "incdec")
6123 (const_string "alu")))
6124 (set_attr "modrm" "1")
6125 (set_attr "mode" "QI")])
6127 (define_insn "*addqi_ext_2"
6128 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6133 (match_operand 1 "ext_register_operand" "%0")
6137 (match_operand 2 "ext_register_operand" "Q")
6140 (clobber (reg:CC FLAGS_REG))]
6142 "add{b}\t{%h2, %h0|%h0, %h2}"
6143 [(set_attr "type" "alu")
6144 (set_attr "mode" "QI")])
6146 ;; Add with jump on overflow.
6147 (define_expand "addv<mode>4"
6148 [(parallel [(set (reg:CCO FLAGS_REG)
6151 (match_operand:SWI 1 "nonimmediate_operand"))
6154 (plus:SWI (match_dup 1)
6155 (match_operand:SWI 2
6156 "<general_operand>")))))
6157 (set (match_operand:SWI 0 "register_operand")
6158 (plus:SWI (match_dup 1) (match_dup 2)))])
6159 (set (pc) (if_then_else
6160 (eq (reg:CCO FLAGS_REG) (const_int 0))
6161 (label_ref (match_operand 3))
6165 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6166 if (CONST_INT_P (operands[2]))
6167 operands[4] = operands[2];
6169 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6172 (define_insn "*addv<mode>4"
6173 [(set (reg:CCO FLAGS_REG)
6176 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6178 (match_operand:SWI 2 "<general_sext_operand>"
6181 (plus:SWI (match_dup 1) (match_dup 2)))))
6182 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6183 (plus:SWI (match_dup 1) (match_dup 2)))]
6184 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6185 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6186 [(set_attr "type" "alu")
6187 (set_attr "mode" "<MODE>")])
6189 (define_insn "*addv<mode>4_1"
6190 [(set (reg:CCO FLAGS_REG)
6193 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6194 (match_operand:<DWI> 3 "const_int_operand" "i"))
6196 (plus:SWI (match_dup 1)
6197 (match_operand:SWI 2 "x86_64_immediate_operand"
6199 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6200 (plus:SWI (match_dup 1) (match_dup 2)))]
6201 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6202 && CONST_INT_P (operands[2])
6203 && INTVAL (operands[2]) == INTVAL (operands[3])"
6204 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6205 [(set_attr "type" "alu")
6206 (set_attr "mode" "<MODE>")
6207 (set (attr "length_immediate")
6208 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6210 (match_test "<MODE_SIZE> == 8")
6212 (const_string "<MODE_SIZE>")))])
6214 (define_expand "uaddv<mode>4"
6215 [(parallel [(set (reg:CCC FLAGS_REG)
6218 (match_operand:SWI 1 "nonimmediate_operand")
6219 (match_operand:SWI 2 "<general_operand>"))
6221 (set (match_operand:SWI 0 "register_operand")
6222 (plus:SWI (match_dup 1) (match_dup 2)))])
6223 (set (pc) (if_then_else
6224 (ltu (reg:CCC FLAGS_REG) (const_int 0))
6225 (label_ref (match_operand 3))
6228 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6230 ;; The lea patterns for modes less than 32 bits need to be matched by
6231 ;; several insns converted to real lea by splitters.
6233 (define_insn_and_split "*lea_general_1"
6234 [(set (match_operand 0 "register_operand" "=r")
6235 (plus (plus (match_operand 1 "index_register_operand" "l")
6236 (match_operand 2 "register_operand" "r"))
6237 (match_operand 3 "immediate_operand" "i")))]
6238 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6239 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6240 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6241 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6242 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6243 || GET_MODE (operands[3]) == VOIDmode)"
6245 "&& reload_completed"
6248 machine_mode mode = SImode;
6251 operands[0] = gen_lowpart (mode, operands[0]);
6252 operands[1] = gen_lowpart (mode, operands[1]);
6253 operands[2] = gen_lowpart (mode, operands[2]);
6254 operands[3] = gen_lowpart (mode, operands[3]);
6256 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6259 emit_insn (gen_rtx_SET (operands[0], pat));
6262 [(set_attr "type" "lea")
6263 (set_attr "mode" "SI")])
6265 (define_insn_and_split "*lea_general_2"
6266 [(set (match_operand 0 "register_operand" "=r")
6267 (plus (mult (match_operand 1 "index_register_operand" "l")
6268 (match_operand 2 "const248_operand" "n"))
6269 (match_operand 3 "nonmemory_operand" "ri")))]
6270 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6271 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6272 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6273 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6274 || GET_MODE (operands[3]) == VOIDmode)"
6276 "&& reload_completed"
6279 machine_mode mode = SImode;
6282 operands[0] = gen_lowpart (mode, operands[0]);
6283 operands[1] = gen_lowpart (mode, operands[1]);
6284 operands[3] = gen_lowpart (mode, operands[3]);
6286 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6289 emit_insn (gen_rtx_SET (operands[0], pat));
6292 [(set_attr "type" "lea")
6293 (set_attr "mode" "SI")])
6295 (define_insn_and_split "*lea_general_3"
6296 [(set (match_operand 0 "register_operand" "=r")
6297 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6298 (match_operand 2 "const248_operand" "n"))
6299 (match_operand 3 "register_operand" "r"))
6300 (match_operand 4 "immediate_operand" "i")))]
6301 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6302 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6303 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6304 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6306 "&& reload_completed"
6309 machine_mode mode = SImode;
6312 operands[0] = gen_lowpart (mode, operands[0]);
6313 operands[1] = gen_lowpart (mode, operands[1]);
6314 operands[3] = gen_lowpart (mode, operands[3]);
6315 operands[4] = gen_lowpart (mode, operands[4]);
6317 pat = gen_rtx_PLUS (mode,
6319 gen_rtx_MULT (mode, operands[1],
6324 emit_insn (gen_rtx_SET (operands[0], pat));
6327 [(set_attr "type" "lea")
6328 (set_attr "mode" "SI")])
6330 (define_insn_and_split "*lea_general_4"
6331 [(set (match_operand 0 "register_operand" "=r")
6333 (match_operand 1 "index_register_operand" "l")
6334 (match_operand 2 "const_int_operand" "n"))
6335 (match_operand 3 "const_int_operand" "n")))]
6336 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6337 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6338 || GET_MODE (operands[0]) == SImode
6339 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6340 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6341 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6342 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6343 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6345 "&& reload_completed"
6348 machine_mode mode = GET_MODE (operands[0]);
6351 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6354 operands[0] = gen_lowpart (mode, operands[0]);
6355 operands[1] = gen_lowpart (mode, operands[1]);
6358 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6360 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6361 INTVAL (operands[3]));
6363 emit_insn (gen_rtx_SET (operands[0], pat));
6366 [(set_attr "type" "lea")
6368 (if_then_else (match_operand:DI 0)
6370 (const_string "SI")))])
6372 ;; Subtract instructions
6374 (define_expand "sub<mode>3"
6375 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6376 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6377 (match_operand:SDWIM 2 "<general_operand>")))]
6379 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6381 (define_insn_and_split "*sub<dwi>3_doubleword"
6382 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6384 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6385 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6386 (clobber (reg:CC FLAGS_REG))]
6387 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6390 [(parallel [(set (reg:CC FLAGS_REG)
6391 (compare:CC (match_dup 1) (match_dup 2)))
6393 (minus:DWIH (match_dup 1) (match_dup 2)))])
6394 (parallel [(set (match_dup 3)
6398 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6400 (clobber (reg:CC FLAGS_REG))])]
6402 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6403 if (operands[2] == const0_rtx)
6405 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6410 (define_insn "*sub<mode>_1"
6411 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6413 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6414 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6415 (clobber (reg:CC FLAGS_REG))]
6416 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6417 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6418 [(set_attr "type" "alu")
6419 (set_attr "mode" "<MODE>")])
6421 (define_insn "*subsi_1_zext"
6422 [(set (match_operand:DI 0 "register_operand" "=r")
6424 (minus:SI (match_operand:SI 1 "register_operand" "0")
6425 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6426 (clobber (reg:CC FLAGS_REG))]
6427 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6428 "sub{l}\t{%2, %k0|%k0, %2}"
6429 [(set_attr "type" "alu")
6430 (set_attr "mode" "SI")])
6432 (define_insn "*subqi_1_slp"
6433 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6434 (minus:QI (match_dup 0)
6435 (match_operand:QI 1 "general_operand" "qn,qm")))
6436 (clobber (reg:CC FLAGS_REG))]
6437 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6438 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6439 "sub{b}\t{%1, %0|%0, %1}"
6440 [(set_attr "type" "alu1")
6441 (set_attr "mode" "QI")])
6443 (define_insn "*sub<mode>_2"
6444 [(set (reg FLAGS_REG)
6447 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6448 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6450 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6451 (minus:SWI (match_dup 1) (match_dup 2)))]
6452 "ix86_match_ccmode (insn, CCGOCmode)
6453 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6454 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6455 [(set_attr "type" "alu")
6456 (set_attr "mode" "<MODE>")])
6458 (define_insn "*subsi_2_zext"
6459 [(set (reg FLAGS_REG)
6461 (minus:SI (match_operand:SI 1 "register_operand" "0")
6462 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6464 (set (match_operand:DI 0 "register_operand" "=r")
6466 (minus:SI (match_dup 1)
6468 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6469 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6470 "sub{l}\t{%2, %k0|%k0, %2}"
6471 [(set_attr "type" "alu")
6472 (set_attr "mode" "SI")])
6474 ;; Subtract with jump on overflow.
6475 (define_expand "subv<mode>4"
6476 [(parallel [(set (reg:CCO FLAGS_REG)
6477 (eq:CCO (minus:<DWI>
6479 (match_operand:SWI 1 "nonimmediate_operand"))
6482 (minus:SWI (match_dup 1)
6483 (match_operand:SWI 2
6484 "<general_operand>")))))
6485 (set (match_operand:SWI 0 "register_operand")
6486 (minus:SWI (match_dup 1) (match_dup 2)))])
6487 (set (pc) (if_then_else
6488 (eq (reg:CCO FLAGS_REG) (const_int 0))
6489 (label_ref (match_operand 3))
6493 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6494 if (CONST_INT_P (operands[2]))
6495 operands[4] = operands[2];
6497 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6500 (define_insn "*subv<mode>4"
6501 [(set (reg:CCO FLAGS_REG)
6502 (eq:CCO (minus:<DWI>
6504 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6506 (match_operand:SWI 2 "<general_sext_operand>"
6509 (minus:SWI (match_dup 1) (match_dup 2)))))
6510 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6511 (minus:SWI (match_dup 1) (match_dup 2)))]
6512 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6513 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6514 [(set_attr "type" "alu")
6515 (set_attr "mode" "<MODE>")])
6517 (define_insn "*subv<mode>4_1"
6518 [(set (reg:CCO FLAGS_REG)
6519 (eq:CCO (minus:<DWI>
6521 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6522 (match_operand:<DWI> 3 "const_int_operand" "i"))
6524 (minus:SWI (match_dup 1)
6525 (match_operand:SWI 2 "x86_64_immediate_operand"
6527 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6528 (minus:SWI (match_dup 1) (match_dup 2)))]
6529 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6530 && CONST_INT_P (operands[2])
6531 && INTVAL (operands[2]) == INTVAL (operands[3])"
6532 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6533 [(set_attr "type" "alu")
6534 (set_attr "mode" "<MODE>")
6535 (set (attr "length_immediate")
6536 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6538 (match_test "<MODE_SIZE> == 8")
6540 (const_string "<MODE_SIZE>")))])
6542 (define_expand "usubv<mode>4"
6543 [(parallel [(set (reg:CC FLAGS_REG)
6545 (match_operand:SWI 1 "nonimmediate_operand")
6546 (match_operand:SWI 2 "<general_operand>")))
6547 (set (match_operand:SWI 0 "register_operand")
6548 (minus:SWI (match_dup 1) (match_dup 2)))])
6549 (set (pc) (if_then_else
6550 (ltu (reg:CC FLAGS_REG) (const_int 0))
6551 (label_ref (match_operand 3))
6554 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6556 (define_insn "*sub<mode>_3"
6557 [(set (reg FLAGS_REG)
6558 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6559 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6560 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6561 (minus:SWI (match_dup 1) (match_dup 2)))]
6562 "ix86_match_ccmode (insn, CCmode)
6563 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6564 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6565 [(set_attr "type" "alu")
6566 (set_attr "mode" "<MODE>")])
6568 (define_insn "*subsi_3_zext"
6569 [(set (reg FLAGS_REG)
6570 (compare (match_operand:SI 1 "register_operand" "0")
6571 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6572 (set (match_operand:DI 0 "register_operand" "=r")
6574 (minus:SI (match_dup 1)
6576 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6577 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6578 "sub{l}\t{%2, %1|%1, %2}"
6579 [(set_attr "type" "alu")
6580 (set_attr "mode" "SI")])
6582 ;; Add with carry and subtract with borrow
6584 (define_insn "add<mode>3_carry"
6585 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6588 (match_operator:SWI 4 "ix86_carry_flag_operator"
6589 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6590 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6591 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6592 (clobber (reg:CC FLAGS_REG))]
6593 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6594 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6595 [(set_attr "type" "alu")
6596 (set_attr "use_carry" "1")
6597 (set_attr "pent_pair" "pu")
6598 (set_attr "mode" "<MODE>")])
6600 (define_insn "*addsi3_carry_zext"
6601 [(set (match_operand:DI 0 "register_operand" "=r")
6604 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6605 [(reg FLAGS_REG) (const_int 0)])
6606 (match_operand:SI 1 "register_operand" "%0"))
6607 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6608 (clobber (reg:CC FLAGS_REG))]
6609 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6610 "adc{l}\t{%2, %k0|%k0, %2}"
6611 [(set_attr "type" "alu")
6612 (set_attr "use_carry" "1")
6613 (set_attr "pent_pair" "pu")
6614 (set_attr "mode" "SI")])
6616 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6618 (define_insn "addcarry<mode>"
6619 [(set (reg:CCC FLAGS_REG)
6623 (match_operator:SWI48 4 "ix86_carry_flag_operator"
6624 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6625 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6626 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))
6628 (set (match_operand:SWI48 0 "register_operand" "=r")
6629 (plus:SWI48 (plus:SWI48 (match_op_dup 4
6630 [(match_dup 3) (const_int 0)])
6633 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6634 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6635 [(set_attr "type" "alu")
6636 (set_attr "use_carry" "1")
6637 (set_attr "pent_pair" "pu")
6638 (set_attr "mode" "<MODE>")])
6640 (define_insn "sub<mode>3_carry"
6641 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6644 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6645 (match_operator:SWI 4 "ix86_carry_flag_operator"
6646 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6647 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6648 (clobber (reg:CC FLAGS_REG))]
6649 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6650 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6651 [(set_attr "type" "alu")
6652 (set_attr "use_carry" "1")
6653 (set_attr "pent_pair" "pu")
6654 (set_attr "mode" "<MODE>")])
6656 (define_insn "*subsi3_carry_zext"
6657 [(set (match_operand:DI 0 "register_operand" "=r")
6661 (match_operand:SI 1 "register_operand" "0")
6662 (match_operator:SI 3 "ix86_carry_flag_operator"
6663 [(reg FLAGS_REG) (const_int 0)]))
6664 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6665 (clobber (reg:CC FLAGS_REG))]
6666 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6667 "sbb{l}\t{%2, %k0|%k0, %2}"
6668 [(set_attr "type" "alu")
6669 (set_attr "use_carry" "1")
6670 (set_attr "pent_pair" "pu")
6671 (set_attr "mode" "SI")])
6673 (define_insn "subborrow<mode>"
6674 [(set (reg:CCC FLAGS_REG)
6676 (match_operand:SWI48 1 "nonimmediate_operand" "0")
6678 (match_operator:SWI48 4 "ix86_carry_flag_operator"
6679 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6680 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
6681 (set (match_operand:SWI48 0 "register_operand" "=r")
6682 (minus:SWI48 (minus:SWI48 (match_dup 1)
6684 [(match_dup 3) (const_int 0)]))
6686 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6687 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6688 [(set_attr "type" "alu")
6689 (set_attr "use_carry" "1")
6690 (set_attr "pent_pair" "pu")
6691 (set_attr "mode" "<MODE>")])
6693 ;; Overflow setting add instructions
6695 (define_expand "addqi3_cconly_overflow"
6697 [(set (reg:CCC FLAGS_REG)
6700 (match_operand:QI 0 "nonimmediate_operand")
6701 (match_operand:QI 1 "general_operand"))
6703 (clobber (match_scratch:QI 2))])]
6704 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
6706 (define_insn "*add<mode>3_cconly_overflow_1"
6707 [(set (reg:CCC FLAGS_REG)
6710 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6711 (match_operand:SWI 2 "<general_operand>" "<g>"))
6713 (clobber (match_scratch:SWI 0 "=<r>"))]
6714 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6715 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6716 [(set_attr "type" "alu")
6717 (set_attr "mode" "<MODE>")])
6719 (define_insn "*add<mode>3_cconly_overflow_2"
6720 [(set (reg:CCC FLAGS_REG)
6723 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6724 (match_operand:SWI 2 "<general_operand>" "<g>"))
6726 (clobber (match_scratch:SWI 0 "=<r>"))]
6727 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6728 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6729 [(set_attr "type" "alu")
6730 (set_attr "mode" "<MODE>")])
6732 (define_insn "*add<mode>3_cc_overflow_1"
6733 [(set (reg:CCC FLAGS_REG)
6736 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6737 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6739 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6740 (plus:SWI (match_dup 1) (match_dup 2)))]
6741 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6742 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6743 [(set_attr "type" "alu")
6744 (set_attr "mode" "<MODE>")])
6746 (define_insn "*add<mode>3_cc_overflow_2"
6747 [(set (reg:CCC FLAGS_REG)
6750 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6751 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6753 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6754 (plus:SWI (match_dup 1) (match_dup 2)))]
6755 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6756 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6757 [(set_attr "type" "alu")
6758 (set_attr "mode" "<MODE>")])
6760 (define_insn "*addsi3_zext_cc_overflow_1"
6761 [(set (reg:CCC FLAGS_REG)
6764 (match_operand:SI 1 "nonimmediate_operand" "%0")
6765 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6767 (set (match_operand:DI 0 "register_operand" "=r")
6768 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6769 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6770 "add{l}\t{%2, %k0|%k0, %2}"
6771 [(set_attr "type" "alu")
6772 (set_attr "mode" "SI")])
6774 (define_insn "*addsi3_zext_cc_overflow_2"
6775 [(set (reg:CCC FLAGS_REG)
6778 (match_operand:SI 1 "nonimmediate_operand" "%0")
6779 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6781 (set (match_operand:DI 0 "register_operand" "=r")
6782 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6783 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6784 "add{l}\t{%2, %k0|%k0, %2}"
6785 [(set_attr "type" "alu")
6786 (set_attr "mode" "SI")])
6788 ;; The patterns that match these are at the end of this file.
6790 (define_expand "<plusminus_insn>xf3"
6791 [(set (match_operand:XF 0 "register_operand")
6793 (match_operand:XF 1 "register_operand")
6794 (match_operand:XF 2 "register_operand")))]
6797 (define_expand "<plusminus_insn><mode>3"
6798 [(set (match_operand:MODEF 0 "register_operand")
6800 (match_operand:MODEF 1 "register_operand")
6801 (match_operand:MODEF 2 "nonimmediate_operand")))]
6802 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6803 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6805 ;; Multiply instructions
6807 (define_expand "mul<mode>3"
6808 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6810 (match_operand:SWIM248 1 "register_operand")
6811 (match_operand:SWIM248 2 "<general_operand>")))
6812 (clobber (reg:CC FLAGS_REG))])])
6814 (define_expand "mulqi3"
6815 [(parallel [(set (match_operand:QI 0 "register_operand")
6817 (match_operand:QI 1 "register_operand")
6818 (match_operand:QI 2 "nonimmediate_operand")))
6819 (clobber (reg:CC FLAGS_REG))])]
6820 "TARGET_QIMODE_MATH")
6823 ;; IMUL reg32/64, reg32/64, imm8 Direct
6824 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6825 ;; IMUL reg32/64, reg32/64, imm32 Direct
6826 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6827 ;; IMUL reg32/64, reg32/64 Direct
6828 ;; IMUL reg32/64, mem32/64 Direct
6830 ;; On BDVER1, all above IMULs use DirectPath
6833 ;; IMUL reg16, reg16, imm8 VectorPath
6834 ;; IMUL reg16, mem16, imm8 VectorPath
6835 ;; IMUL reg16, reg16, imm16 VectorPath
6836 ;; IMUL reg16, mem16, imm16 VectorPath
6837 ;; IMUL reg16, reg16 Direct
6838 ;; IMUL reg16, mem16 Direct
6840 ;; On BDVER1, all HI MULs use DoublePath
6842 (define_insn "*mul<mode>3_1"
6843 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
6845 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
6846 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
6847 (clobber (reg:CC FLAGS_REG))]
6848 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6850 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6851 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6852 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6853 [(set_attr "type" "imul")
6854 (set_attr "prefix_0f" "0,0,1")
6855 (set (attr "athlon_decode")
6856 (cond [(eq_attr "cpu" "athlon")
6857 (const_string "vector")
6858 (eq_attr "alternative" "1")
6859 (const_string "vector")
6860 (and (eq_attr "alternative" "2")
6861 (ior (match_test "<MODE>mode == HImode")
6862 (match_operand 1 "memory_operand")))
6863 (const_string "vector")]
6864 (const_string "direct")))
6865 (set (attr "amdfam10_decode")
6866 (cond [(and (eq_attr "alternative" "0,1")
6867 (ior (match_test "<MODE>mode == HImode")
6868 (match_operand 1 "memory_operand")))
6869 (const_string "vector")]
6870 (const_string "direct")))
6871 (set (attr "bdver1_decode")
6873 (match_test "<MODE>mode == HImode")
6874 (const_string "double")
6875 (const_string "direct")))
6876 (set_attr "mode" "<MODE>")])
6878 (define_insn "*mulsi3_1_zext"
6879 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6881 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6882 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6883 (clobber (reg:CC FLAGS_REG))]
6885 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6887 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6888 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6889 imul{l}\t{%2, %k0|%k0, %2}"
6890 [(set_attr "type" "imul")
6891 (set_attr "prefix_0f" "0,0,1")
6892 (set (attr "athlon_decode")
6893 (cond [(eq_attr "cpu" "athlon")
6894 (const_string "vector")
6895 (eq_attr "alternative" "1")
6896 (const_string "vector")
6897 (and (eq_attr "alternative" "2")
6898 (match_operand 1 "memory_operand"))
6899 (const_string "vector")]
6900 (const_string "direct")))
6901 (set (attr "amdfam10_decode")
6902 (cond [(and (eq_attr "alternative" "0,1")
6903 (match_operand 1 "memory_operand"))
6904 (const_string "vector")]
6905 (const_string "direct")))
6906 (set_attr "bdver1_decode" "direct")
6907 (set_attr "mode" "SI")])
6909 ;;On AMDFAM10 and BDVER1
6913 (define_insn "*mulqi3_1"
6914 [(set (match_operand:QI 0 "register_operand" "=a")
6915 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6916 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6917 (clobber (reg:CC FLAGS_REG))]
6919 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6921 [(set_attr "type" "imul")
6922 (set_attr "length_immediate" "0")
6923 (set (attr "athlon_decode")
6924 (if_then_else (eq_attr "cpu" "athlon")
6925 (const_string "vector")
6926 (const_string "direct")))
6927 (set_attr "amdfam10_decode" "direct")
6928 (set_attr "bdver1_decode" "direct")
6929 (set_attr "mode" "QI")])
6931 ;; Multiply with jump on overflow.
6932 (define_expand "mulv<mode>4"
6933 [(parallel [(set (reg:CCO FLAGS_REG)
6936 (match_operand:SWI248 1 "register_operand"))
6939 (mult:SWI248 (match_dup 1)
6940 (match_operand:SWI248 2
6941 "<general_operand>")))))
6942 (set (match_operand:SWI248 0 "register_operand")
6943 (mult:SWI248 (match_dup 1) (match_dup 2)))])
6944 (set (pc) (if_then_else
6945 (eq (reg:CCO FLAGS_REG) (const_int 0))
6946 (label_ref (match_operand 3))
6950 if (CONST_INT_P (operands[2]))
6951 operands[4] = operands[2];
6953 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6956 (define_insn "*mulv<mode>4"
6957 [(set (reg:CCO FLAGS_REG)
6960 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6962 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
6964 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6965 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6966 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6967 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6969 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6970 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6971 [(set_attr "type" "imul")
6972 (set_attr "prefix_0f" "0,1")
6973 (set (attr "athlon_decode")
6974 (cond [(eq_attr "cpu" "athlon")
6975 (const_string "vector")
6976 (eq_attr "alternative" "0")
6977 (const_string "vector")
6978 (and (eq_attr "alternative" "1")
6979 (match_operand 1 "memory_operand"))
6980 (const_string "vector")]
6981 (const_string "direct")))
6982 (set (attr "amdfam10_decode")
6983 (cond [(and (eq_attr "alternative" "1")
6984 (match_operand 1 "memory_operand"))
6985 (const_string "vector")]
6986 (const_string "direct")))
6987 (set_attr "bdver1_decode" "direct")
6988 (set_attr "mode" "<MODE>")])
6990 (define_insn "*mulvhi4"
6991 [(set (reg:CCO FLAGS_REG)
6994 (match_operand:HI 1 "nonimmediate_operand" "%0"))
6996 (match_operand:HI 2 "nonimmediate_operand" "mr")))
6998 (mult:HI (match_dup 1) (match_dup 2)))))
6999 (set (match_operand:HI 0 "register_operand" "=r")
7000 (mult:HI (match_dup 1) (match_dup 2)))]
7001 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7002 "imul{w}\t{%2, %0|%0, %2}"
7003 [(set_attr "type" "imul")
7004 (set_attr "prefix_0f" "1")
7005 (set_attr "athlon_decode" "vector")
7006 (set_attr "amdfam10_decode" "direct")
7007 (set_attr "bdver1_decode" "double")
7008 (set_attr "mode" "HI")])
7010 (define_insn "*mulv<mode>4_1"
7011 [(set (reg:CCO FLAGS_REG)
7014 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7015 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7017 (mult:SWI248 (match_dup 1)
7018 (match_operand:SWI248 2
7019 "<immediate_operand>" "K,<i>")))))
7020 (set (match_operand:SWI248 0 "register_operand" "=r,r")
7021 (mult:SWI248 (match_dup 1) (match_dup 2)))]
7022 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7023 && CONST_INT_P (operands[2])
7024 && INTVAL (operands[2]) == INTVAL (operands[3])"
7025 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7026 [(set_attr "type" "imul")
7027 (set (attr "prefix_0f")
7029 (match_test "<MODE>mode == HImode")
7031 (const_string "*")))
7032 (set (attr "athlon_decode")
7033 (cond [(eq_attr "cpu" "athlon")
7034 (const_string "vector")
7035 (eq_attr "alternative" "1")
7036 (const_string "vector")]
7037 (const_string "direct")))
7038 (set (attr "amdfam10_decode")
7039 (cond [(ior (match_test "<MODE>mode == HImode")
7040 (match_operand 1 "memory_operand"))
7041 (const_string "vector")]
7042 (const_string "direct")))
7043 (set (attr "bdver1_decode")
7045 (match_test "<MODE>mode == HImode")
7046 (const_string "double")
7047 (const_string "direct")))
7048 (set_attr "mode" "<MODE>")
7049 (set (attr "length_immediate")
7050 (cond [(eq_attr "alternative" "0")
7052 (match_test "<MODE_SIZE> == 8")
7054 (const_string "<MODE_SIZE>")))])
7056 (define_expand "umulv<mode>4"
7057 [(parallel [(set (reg:CCO FLAGS_REG)
7060 (match_operand:SWI248 1
7061 "nonimmediate_operand"))
7063 (match_operand:SWI248 2
7064 "nonimmediate_operand")))
7066 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7067 (set (match_operand:SWI248 0 "register_operand")
7068 (mult:SWI248 (match_dup 1) (match_dup 2)))
7069 (clobber (match_scratch:SWI248 4))])
7070 (set (pc) (if_then_else
7071 (eq (reg:CCO FLAGS_REG) (const_int 0))
7072 (label_ref (match_operand 3))
7076 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7077 operands[1] = force_reg (<MODE>mode, operands[1]);
7080 (define_insn "*umulv<mode>4"
7081 [(set (reg:CCO FLAGS_REG)
7084 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7086 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7088 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7089 (set (match_operand:SWI248 0 "register_operand" "=a")
7090 (mult:SWI248 (match_dup 1) (match_dup 2)))
7091 (clobber (match_scratch:SWI248 3 "=d"))]
7092 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7093 "mul{<imodesuffix>}\t%2"
7094 [(set_attr "type" "imul")
7095 (set_attr "length_immediate" "0")
7096 (set (attr "athlon_decode")
7097 (if_then_else (eq_attr "cpu" "athlon")
7098 (const_string "vector")
7099 (const_string "double")))
7100 (set_attr "amdfam10_decode" "double")
7101 (set_attr "bdver1_decode" "direct")
7102 (set_attr "mode" "<MODE>")])
7104 (define_expand "<u>mulvqi4"
7105 [(parallel [(set (reg:CCO FLAGS_REG)
7108 (match_operand:QI 1 "nonimmediate_operand"))
7110 (match_operand:QI 2 "nonimmediate_operand")))
7112 (mult:QI (match_dup 1) (match_dup 2)))))
7113 (set (match_operand:QI 0 "register_operand")
7114 (mult:QI (match_dup 1) (match_dup 2)))])
7115 (set (pc) (if_then_else
7116 (eq (reg:CCO FLAGS_REG) (const_int 0))
7117 (label_ref (match_operand 3))
7119 "TARGET_QIMODE_MATH"
7121 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7122 operands[1] = force_reg (QImode, operands[1]);
7125 (define_insn "*<u>mulvqi4"
7126 [(set (reg:CCO FLAGS_REG)
7129 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7131 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7133 (mult:QI (match_dup 1) (match_dup 2)))))
7134 (set (match_operand:QI 0 "register_operand" "=a")
7135 (mult:QI (match_dup 1) (match_dup 2)))]
7137 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7138 "<sgnprefix>mul{b}\t%2"
7139 [(set_attr "type" "imul")
7140 (set_attr "length_immediate" "0")
7141 (set (attr "athlon_decode")
7142 (if_then_else (eq_attr "cpu" "athlon")
7143 (const_string "vector")
7144 (const_string "direct")))
7145 (set_attr "amdfam10_decode" "direct")
7146 (set_attr "bdver1_decode" "direct")
7147 (set_attr "mode" "QI")])
7149 (define_expand "<u>mul<mode><dwi>3"
7150 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7153 (match_operand:DWIH 1 "nonimmediate_operand"))
7155 (match_operand:DWIH 2 "register_operand"))))
7156 (clobber (reg:CC FLAGS_REG))])])
7158 (define_expand "<u>mulqihi3"
7159 [(parallel [(set (match_operand:HI 0 "register_operand")
7162 (match_operand:QI 1 "nonimmediate_operand"))
7164 (match_operand:QI 2 "register_operand"))))
7165 (clobber (reg:CC FLAGS_REG))])]
7166 "TARGET_QIMODE_MATH")
7168 (define_insn "*bmi2_umul<mode><dwi>3_1"
7169 [(set (match_operand:DWIH 0 "register_operand" "=r")
7171 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7172 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7173 (set (match_operand:DWIH 1 "register_operand" "=r")
7176 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7177 (zero_extend:<DWI> (match_dup 3)))
7178 (match_operand:QI 4 "const_int_operand" "n"))))]
7179 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7180 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7181 "mulx\t{%3, %0, %1|%1, %0, %3}"
7182 [(set_attr "type" "imulx")
7183 (set_attr "prefix" "vex")
7184 (set_attr "mode" "<MODE>")])
7186 (define_insn "*umul<mode><dwi>3_1"
7187 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7190 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7192 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7193 (clobber (reg:CC FLAGS_REG))]
7194 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7197 mul{<imodesuffix>}\t%2"
7198 [(set_attr "isa" "bmi2,*")
7199 (set_attr "type" "imulx,imul")
7200 (set_attr "length_immediate" "*,0")
7201 (set (attr "athlon_decode")
7202 (cond [(eq_attr "alternative" "1")
7203 (if_then_else (eq_attr "cpu" "athlon")
7204 (const_string "vector")
7205 (const_string "double"))]
7206 (const_string "*")))
7207 (set_attr "amdfam10_decode" "*,double")
7208 (set_attr "bdver1_decode" "*,direct")
7209 (set_attr "prefix" "vex,orig")
7210 (set_attr "mode" "<MODE>")])
7212 ;; Convert mul to the mulx pattern to avoid flags dependency.
7214 [(set (match_operand:<DWI> 0 "register_operand")
7217 (match_operand:DWIH 1 "register_operand"))
7219 (match_operand:DWIH 2 "nonimmediate_operand"))))
7220 (clobber (reg:CC FLAGS_REG))]
7221 "TARGET_BMI2 && reload_completed
7222 && true_regnum (operands[1]) == DX_REG"
7223 [(parallel [(set (match_dup 3)
7224 (mult:DWIH (match_dup 1) (match_dup 2)))
7228 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7229 (zero_extend:<DWI> (match_dup 2)))
7232 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7234 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7237 (define_insn "*mul<mode><dwi>3_1"
7238 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7241 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7243 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7244 (clobber (reg:CC FLAGS_REG))]
7245 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7246 "imul{<imodesuffix>}\t%2"
7247 [(set_attr "type" "imul")
7248 (set_attr "length_immediate" "0")
7249 (set (attr "athlon_decode")
7250 (if_then_else (eq_attr "cpu" "athlon")
7251 (const_string "vector")
7252 (const_string "double")))
7253 (set_attr "amdfam10_decode" "double")
7254 (set_attr "bdver1_decode" "direct")
7255 (set_attr "mode" "<MODE>")])
7257 (define_insn "*<u>mulqihi3_1"
7258 [(set (match_operand:HI 0 "register_operand" "=a")
7261 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7263 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7264 (clobber (reg:CC FLAGS_REG))]
7266 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7267 "<sgnprefix>mul{b}\t%2"
7268 [(set_attr "type" "imul")
7269 (set_attr "length_immediate" "0")
7270 (set (attr "athlon_decode")
7271 (if_then_else (eq_attr "cpu" "athlon")
7272 (const_string "vector")
7273 (const_string "direct")))
7274 (set_attr "amdfam10_decode" "direct")
7275 (set_attr "bdver1_decode" "direct")
7276 (set_attr "mode" "QI")])
7278 (define_expand "<s>mul<mode>3_highpart"
7279 [(parallel [(set (match_operand:SWI48 0 "register_operand")
7284 (match_operand:SWI48 1 "nonimmediate_operand"))
7286 (match_operand:SWI48 2 "register_operand")))
7288 (clobber (match_scratch:SWI48 3))
7289 (clobber (reg:CC FLAGS_REG))])]
7291 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7293 (define_insn "*<s>muldi3_highpart_1"
7294 [(set (match_operand:DI 0 "register_operand" "=d")
7299 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7301 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7303 (clobber (match_scratch:DI 3 "=1"))
7304 (clobber (reg:CC FLAGS_REG))]
7306 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7307 "<sgnprefix>mul{q}\t%2"
7308 [(set_attr "type" "imul")
7309 (set_attr "length_immediate" "0")
7310 (set (attr "athlon_decode")
7311 (if_then_else (eq_attr "cpu" "athlon")
7312 (const_string "vector")
7313 (const_string "double")))
7314 (set_attr "amdfam10_decode" "double")
7315 (set_attr "bdver1_decode" "direct")
7316 (set_attr "mode" "DI")])
7318 (define_insn "*<s>mulsi3_highpart_1"
7319 [(set (match_operand:SI 0 "register_operand" "=d")
7324 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7326 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7328 (clobber (match_scratch:SI 3 "=1"))
7329 (clobber (reg:CC FLAGS_REG))]
7330 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7331 "<sgnprefix>mul{l}\t%2"
7332 [(set_attr "type" "imul")
7333 (set_attr "length_immediate" "0")
7334 (set (attr "athlon_decode")
7335 (if_then_else (eq_attr "cpu" "athlon")
7336 (const_string "vector")
7337 (const_string "double")))
7338 (set_attr "amdfam10_decode" "double")
7339 (set_attr "bdver1_decode" "direct")
7340 (set_attr "mode" "SI")])
7342 (define_insn "*<s>mulsi3_highpart_zext"
7343 [(set (match_operand:DI 0 "register_operand" "=d")
7344 (zero_extend:DI (truncate:SI
7346 (mult:DI (any_extend:DI
7347 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7349 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7351 (clobber (match_scratch:SI 3 "=1"))
7352 (clobber (reg:CC FLAGS_REG))]
7354 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7355 "<sgnprefix>mul{l}\t%2"
7356 [(set_attr "type" "imul")
7357 (set_attr "length_immediate" "0")
7358 (set (attr "athlon_decode")
7359 (if_then_else (eq_attr "cpu" "athlon")
7360 (const_string "vector")
7361 (const_string "double")))
7362 (set_attr "amdfam10_decode" "double")
7363 (set_attr "bdver1_decode" "direct")
7364 (set_attr "mode" "SI")])
7366 ;; The patterns that match these are at the end of this file.
7368 (define_expand "mulxf3"
7369 [(set (match_operand:XF 0 "register_operand")
7370 (mult:XF (match_operand:XF 1 "register_operand")
7371 (match_operand:XF 2 "register_operand")))]
7374 (define_expand "mul<mode>3"
7375 [(set (match_operand:MODEF 0 "register_operand")
7376 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7377 (match_operand:MODEF 2 "nonimmediate_operand")))]
7378 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7379 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7381 ;; Divide instructions
7383 ;; The patterns that match these are at the end of this file.
7385 (define_expand "divxf3"
7386 [(set (match_operand:XF 0 "register_operand")
7387 (div:XF (match_operand:XF 1 "register_operand")
7388 (match_operand:XF 2 "register_operand")))]
7391 (define_expand "divdf3"
7392 [(set (match_operand:DF 0 "register_operand")
7393 (div:DF (match_operand:DF 1 "register_operand")
7394 (match_operand:DF 2 "nonimmediate_operand")))]
7395 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7396 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7398 (define_expand "divsf3"
7399 [(set (match_operand:SF 0 "register_operand")
7400 (div:SF (match_operand:SF 1 "register_operand")
7401 (match_operand:SF 2 "nonimmediate_operand")))]
7402 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7407 && optimize_insn_for_speed_p ()
7408 && flag_finite_math_only && !flag_trapping_math
7409 && flag_unsafe_math_optimizations)
7411 ix86_emit_swdivsf (operands[0], operands[1],
7412 operands[2], SFmode);
7417 ;; Divmod instructions.
7419 (define_expand "divmod<mode>4"
7420 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7422 (match_operand:SWIM248 1 "register_operand")
7423 (match_operand:SWIM248 2 "nonimmediate_operand")))
7424 (set (match_operand:SWIM248 3 "register_operand")
7425 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7426 (clobber (reg:CC FLAGS_REG))])])
7428 ;; Split with 8bit unsigned divide:
7429 ;; if (dividend an divisor are in [0-255])
7430 ;; use 8bit unsigned integer divide
7432 ;; use original integer divide
7434 [(set (match_operand:SWI48 0 "register_operand")
7435 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7436 (match_operand:SWI48 3 "nonimmediate_operand")))
7437 (set (match_operand:SWI48 1 "register_operand")
7438 (mod:SWI48 (match_dup 2) (match_dup 3)))
7439 (clobber (reg:CC FLAGS_REG))]
7440 "TARGET_USE_8BIT_IDIV
7441 && TARGET_QIMODE_MATH
7442 && can_create_pseudo_p ()
7443 && !optimize_insn_for_size_p ()"
7445 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7447 (define_insn_and_split "divmod<mode>4_1"
7448 [(set (match_operand:SWI48 0 "register_operand" "=a")
7449 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7450 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7451 (set (match_operand:SWI48 1 "register_operand" "=&d")
7452 (mod:SWI48 (match_dup 2) (match_dup 3)))
7453 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7454 (clobber (reg:CC FLAGS_REG))]
7458 [(parallel [(set (match_dup 1)
7459 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7460 (clobber (reg:CC FLAGS_REG))])
7461 (parallel [(set (match_dup 0)
7462 (div:SWI48 (match_dup 2) (match_dup 3)))
7464 (mod:SWI48 (match_dup 2) (match_dup 3)))
7466 (clobber (reg:CC FLAGS_REG))])]
7468 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7470 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7471 operands[4] = operands[2];
7474 /* Avoid use of cltd in favor of a mov+shift. */
7475 emit_move_insn (operands[1], operands[2]);
7476 operands[4] = operands[1];
7479 [(set_attr "type" "multi")
7480 (set_attr "mode" "<MODE>")])
7482 (define_insn_and_split "*divmod<mode>4"
7483 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7484 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7485 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7486 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7487 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7488 (clobber (reg:CC FLAGS_REG))]
7492 [(parallel [(set (match_dup 1)
7493 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7494 (clobber (reg:CC FLAGS_REG))])
7495 (parallel [(set (match_dup 0)
7496 (div:SWIM248 (match_dup 2) (match_dup 3)))
7498 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7500 (clobber (reg:CC FLAGS_REG))])]
7502 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7504 if (<MODE>mode != HImode
7505 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7506 operands[4] = operands[2];
7509 /* Avoid use of cltd in favor of a mov+shift. */
7510 emit_move_insn (operands[1], operands[2]);
7511 operands[4] = operands[1];
7514 [(set_attr "type" "multi")
7515 (set_attr "mode" "<MODE>")])
7517 (define_insn "*divmod<mode>4_noext"
7518 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7519 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7520 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7521 (set (match_operand:SWIM248 1 "register_operand" "=d")
7522 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7523 (use (match_operand:SWIM248 4 "register_operand" "1"))
7524 (clobber (reg:CC FLAGS_REG))]
7526 "idiv{<imodesuffix>}\t%3"
7527 [(set_attr "type" "idiv")
7528 (set_attr "mode" "<MODE>")])
7530 (define_expand "divmodqi4"
7531 [(parallel [(set (match_operand:QI 0 "register_operand")
7533 (match_operand:QI 1 "register_operand")
7534 (match_operand:QI 2 "nonimmediate_operand")))
7535 (set (match_operand:QI 3 "register_operand")
7536 (mod:QI (match_dup 1) (match_dup 2)))
7537 (clobber (reg:CC FLAGS_REG))])]
7538 "TARGET_QIMODE_MATH"
7543 tmp0 = gen_reg_rtx (HImode);
7544 tmp1 = gen_reg_rtx (HImode);
7546 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7548 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7549 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7551 /* Extract remainder from AH. */
7552 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7553 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7555 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7556 set_unique_reg_note (insn, REG_EQUAL, mod);
7558 /* Extract quotient from AL. */
7559 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7561 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7562 set_unique_reg_note (insn, REG_EQUAL, div);
7567 ;; Divide AX by r/m8, with result stored in
7570 ;; Change div/mod to HImode and extend the second argument to HImode
7571 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7572 ;; combine may fail.
7573 (define_insn "divmodhiqi3"
7574 [(set (match_operand:HI 0 "register_operand" "=a")
7579 (mod:HI (match_operand:HI 1 "register_operand" "0")
7581 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7585 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7586 (clobber (reg:CC FLAGS_REG))]
7587 "TARGET_QIMODE_MATH"
7589 [(set_attr "type" "idiv")
7590 (set_attr "mode" "QI")])
7592 (define_expand "udivmod<mode>4"
7593 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7595 (match_operand:SWIM248 1 "register_operand")
7596 (match_operand:SWIM248 2 "nonimmediate_operand")))
7597 (set (match_operand:SWIM248 3 "register_operand")
7598 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7599 (clobber (reg:CC FLAGS_REG))])])
7601 ;; Split with 8bit unsigned divide:
7602 ;; if (dividend an divisor are in [0-255])
7603 ;; use 8bit unsigned integer divide
7605 ;; use original integer divide
7607 [(set (match_operand:SWI48 0 "register_operand")
7608 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7609 (match_operand:SWI48 3 "nonimmediate_operand")))
7610 (set (match_operand:SWI48 1 "register_operand")
7611 (umod:SWI48 (match_dup 2) (match_dup 3)))
7612 (clobber (reg:CC FLAGS_REG))]
7613 "TARGET_USE_8BIT_IDIV
7614 && TARGET_QIMODE_MATH
7615 && can_create_pseudo_p ()
7616 && !optimize_insn_for_size_p ()"
7618 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7620 (define_insn_and_split "udivmod<mode>4_1"
7621 [(set (match_operand:SWI48 0 "register_operand" "=a")
7622 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7623 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7624 (set (match_operand:SWI48 1 "register_operand" "=&d")
7625 (umod:SWI48 (match_dup 2) (match_dup 3)))
7626 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7627 (clobber (reg:CC FLAGS_REG))]
7631 [(set (match_dup 1) (const_int 0))
7632 (parallel [(set (match_dup 0)
7633 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7635 (umod:SWI48 (match_dup 2) (match_dup 3)))
7637 (clobber (reg:CC FLAGS_REG))])]
7639 [(set_attr "type" "multi")
7640 (set_attr "mode" "<MODE>")])
7642 (define_insn_and_split "*udivmod<mode>4"
7643 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7644 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7645 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7646 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7647 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7648 (clobber (reg:CC FLAGS_REG))]
7652 [(set (match_dup 1) (const_int 0))
7653 (parallel [(set (match_dup 0)
7654 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7656 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7658 (clobber (reg:CC FLAGS_REG))])]
7660 [(set_attr "type" "multi")
7661 (set_attr "mode" "<MODE>")])
7663 ;; Optimize division or modulo by constant power of 2, if the constant
7664 ;; materializes only after expansion.
7665 (define_insn_and_split "*udivmod<mode>4_pow2"
7666 [(set (match_operand:SWI48 0 "register_operand" "=r")
7667 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7668 (match_operand:SWI48 3 "const_int_operand" "n")))
7669 (set (match_operand:SWI48 1 "register_operand" "=r")
7670 (umod:SWI48 (match_dup 2) (match_dup 3)))
7671 (clobber (reg:CC FLAGS_REG))]
7672 "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
7673 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
7676 [(set (match_dup 1) (match_dup 2))
7677 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7678 (clobber (reg:CC FLAGS_REG))])
7679 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7680 (clobber (reg:CC FLAGS_REG))])]
7682 int v = exact_log2 (UINTVAL (operands[3]));
7683 operands[4] = GEN_INT (v);
7684 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7686 [(set_attr "type" "multi")
7687 (set_attr "mode" "<MODE>")])
7689 (define_insn "*udivmod<mode>4_noext"
7690 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7691 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7692 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7693 (set (match_operand:SWIM248 1 "register_operand" "=d")
7694 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7695 (use (match_operand:SWIM248 4 "register_operand" "1"))
7696 (clobber (reg:CC FLAGS_REG))]
7698 "div{<imodesuffix>}\t%3"
7699 [(set_attr "type" "idiv")
7700 (set_attr "mode" "<MODE>")])
7702 (define_expand "udivmodqi4"
7703 [(parallel [(set (match_operand:QI 0 "register_operand")
7705 (match_operand:QI 1 "register_operand")
7706 (match_operand:QI 2 "nonimmediate_operand")))
7707 (set (match_operand:QI 3 "register_operand")
7708 (umod:QI (match_dup 1) (match_dup 2)))
7709 (clobber (reg:CC FLAGS_REG))])]
7710 "TARGET_QIMODE_MATH"
7715 tmp0 = gen_reg_rtx (HImode);
7716 tmp1 = gen_reg_rtx (HImode);
7718 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7720 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7721 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7723 /* Extract remainder from AH. */
7724 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7725 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7726 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7728 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7729 set_unique_reg_note (insn, REG_EQUAL, mod);
7731 /* Extract quotient from AL. */
7732 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7734 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7735 set_unique_reg_note (insn, REG_EQUAL, div);
7740 (define_insn "udivmodhiqi3"
7741 [(set (match_operand:HI 0 "register_operand" "=a")
7746 (mod:HI (match_operand:HI 1 "register_operand" "0")
7748 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7752 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7753 (clobber (reg:CC FLAGS_REG))]
7754 "TARGET_QIMODE_MATH"
7756 [(set_attr "type" "idiv")
7757 (set_attr "mode" "QI")])
7759 ;; We cannot use div/idiv for double division, because it causes
7760 ;; "division by zero" on the overflow and that's not what we expect
7761 ;; from truncate. Because true (non truncating) double division is
7762 ;; never generated, we can't create this insn anyway.
7765 ; [(set (match_operand:SI 0 "register_operand" "=a")
7767 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7769 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7770 ; (set (match_operand:SI 3 "register_operand" "=d")
7772 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7773 ; (clobber (reg:CC FLAGS_REG))]
7775 ; "div{l}\t{%2, %0|%0, %2}"
7776 ; [(set_attr "type" "idiv")])
7778 ;;- Logical AND instructions
7780 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7781 ;; Note that this excludes ah.
7783 (define_expand "testsi_ccno_1"
7784 [(set (reg:CCNO FLAGS_REG)
7786 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7787 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7790 (define_expand "testqi_ccz_1"
7791 [(set (reg:CCZ FLAGS_REG)
7792 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7793 (match_operand:QI 1 "nonmemory_operand"))
7796 (define_expand "testdi_ccno_1"
7797 [(set (reg:CCNO FLAGS_REG)
7799 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7800 (match_operand:DI 1 "x86_64_szext_general_operand"))
7802 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7804 (define_insn "*testdi_1"
7805 [(set (reg FLAGS_REG)
7808 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7809 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7811 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7812 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7814 test{l}\t{%k1, %k0|%k0, %k1}
7815 test{l}\t{%k1, %k0|%k0, %k1}
7816 test{q}\t{%1, %0|%0, %1}
7817 test{q}\t{%1, %0|%0, %1}
7818 test{q}\t{%1, %0|%0, %1}"
7819 [(set_attr "type" "test")
7820 (set_attr "modrm" "0,1,0,1,1")
7821 (set_attr "mode" "SI,SI,DI,DI,DI")])
7823 (define_insn "*testqi_1_maybe_si"
7824 [(set (reg FLAGS_REG)
7827 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7828 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7830 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7831 && ix86_match_ccmode (insn,
7832 CONST_INT_P (operands[1])
7833 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7835 if (which_alternative == 3)
7837 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7838 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7839 return "test{l}\t{%1, %k0|%k0, %1}";
7841 return "test{b}\t{%1, %0|%0, %1}";
7843 [(set_attr "type" "test")
7844 (set_attr "modrm" "0,1,1,1")
7845 (set_attr "mode" "QI,QI,QI,SI")
7846 (set_attr "pent_pair" "uv,np,uv,np")])
7848 (define_insn "*test<mode>_1"
7849 [(set (reg FLAGS_REG)
7852 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7853 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7855 "ix86_match_ccmode (insn, CCNOmode)
7856 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7857 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7858 [(set_attr "type" "test")
7859 (set_attr "modrm" "0,1,1")
7860 (set_attr "mode" "<MODE>")
7861 (set_attr "pent_pair" "uv,np,uv")])
7863 (define_expand "testqi_ext_ccno_0"
7864 [(set (reg:CCNO FLAGS_REG)
7868 (match_operand 0 "ext_register_operand")
7871 (match_operand 1 "const_int_operand"))
7874 (define_insn "*testqi_ext_0"
7875 [(set (reg FLAGS_REG)
7879 (match_operand 0 "ext_register_operand" "Q")
7882 (match_operand 1 "const_int_operand" "n"))
7884 "ix86_match_ccmode (insn, CCNOmode)"
7885 "test{b}\t{%1, %h0|%h0, %1}"
7886 [(set_attr "type" "test")
7887 (set_attr "mode" "QI")
7888 (set_attr "length_immediate" "1")
7889 (set_attr "modrm" "1")
7890 (set_attr "pent_pair" "np")])
7892 (define_insn "*testqi_ext_1"
7893 [(set (reg FLAGS_REG)
7897 (match_operand 0 "ext_register_operand" "Q,Q")
7901 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7903 "ix86_match_ccmode (insn, CCNOmode)"
7904 "test{b}\t{%1, %h0|%h0, %1}"
7905 [(set_attr "isa" "*,nox64")
7906 (set_attr "type" "test")
7907 (set_attr "mode" "QI")])
7909 (define_insn "*testqi_ext_2"
7910 [(set (reg FLAGS_REG)
7914 (match_operand 0 "ext_register_operand" "Q")
7918 (match_operand 1 "ext_register_operand" "Q")
7922 "ix86_match_ccmode (insn, CCNOmode)"
7923 "test{b}\t{%h1, %h0|%h0, %h1}"
7924 [(set_attr "type" "test")
7925 (set_attr "mode" "QI")])
7927 ;; Combine likes to form bit extractions for some tests. Humor it.
7928 (define_insn "*testqi_ext_3"
7929 [(set (reg FLAGS_REG)
7930 (compare (zero_extract:SWI248
7931 (match_operand 0 "nonimmediate_operand" "rm")
7932 (match_operand 1 "const_int_operand" "n")
7933 (match_operand 2 "const_int_operand" "n"))
7935 "ix86_match_ccmode (insn, CCNOmode)
7936 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7937 || GET_MODE (operands[0]) == SImode
7938 || GET_MODE (operands[0]) == HImode
7939 || GET_MODE (operands[0]) == QImode)
7940 /* Ensure that resulting mask is zero or sign extended operand. */
7941 && INTVAL (operands[2]) >= 0
7942 && ((INTVAL (operands[1]) > 0
7943 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7944 || (<MODE>mode == DImode
7945 && INTVAL (operands[1]) > 32
7946 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7950 [(set (match_operand 0 "flags_reg_operand")
7951 (match_operator 1 "compare_operator"
7953 (match_operand 2 "nonimmediate_operand")
7954 (match_operand 3 "const_int_operand")
7955 (match_operand 4 "const_int_operand"))
7957 "ix86_match_ccmode (insn, CCNOmode)"
7958 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7960 rtx val = operands[2];
7961 HOST_WIDE_INT len = INTVAL (operands[3]);
7962 HOST_WIDE_INT pos = INTVAL (operands[4]);
7964 machine_mode mode, submode;
7966 mode = GET_MODE (val);
7969 /* ??? Combine likes to put non-volatile mem extractions in QImode
7970 no matter the size of the test. So find a mode that works. */
7971 if (! MEM_VOLATILE_P (val))
7973 mode = smallest_mode_for_size (pos + len, MODE_INT);
7974 val = adjust_address (val, mode, 0);
7977 else if (SUBREG_P (val)
7978 && (submode = GET_MODE (SUBREG_REG (val)),
7979 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7980 && pos + len <= GET_MODE_BITSIZE (submode)
7981 && GET_MODE_CLASS (submode) == MODE_INT)
7983 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7985 val = SUBREG_REG (val);
7987 else if (mode == HImode && pos + len <= 8)
7989 /* Small HImode tests can be converted to QImode. */
7991 val = gen_lowpart (QImode, val);
7994 if (len == HOST_BITS_PER_WIDE_INT)
7997 mask = ((HOST_WIDE_INT)1 << len) - 1;
8000 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8003 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8004 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8005 ;; this is relatively important trick.
8006 ;; Do the conversion only post-reload to avoid limiting of the register class
8009 [(set (match_operand 0 "flags_reg_operand")
8010 (match_operator 1 "compare_operator"
8011 [(and (match_operand 2 "QIreg_operand")
8012 (match_operand 3 "const_int_operand"))
8015 && GET_MODE (operands[2]) != QImode
8016 && ((ix86_match_ccmode (insn, CCZmode)
8017 && !(INTVAL (operands[3]) & ~(255 << 8)))
8018 || (ix86_match_ccmode (insn, CCNOmode)
8019 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8022 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8026 operands[2] = gen_lowpart (SImode, operands[2]);
8027 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
8031 [(set (match_operand 0 "flags_reg_operand")
8032 (match_operator 1 "compare_operator"
8033 [(and (match_operand 2 "nonimmediate_operand")
8034 (match_operand 3 "const_int_operand"))
8037 && GET_MODE (operands[2]) != QImode
8038 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8039 && ((ix86_match_ccmode (insn, CCZmode)
8040 && !(INTVAL (operands[3]) & ~255))
8041 || (ix86_match_ccmode (insn, CCNOmode)
8042 && !(INTVAL (operands[3]) & ~127)))"
8044 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8047 operands[2] = gen_lowpart (QImode, operands[2]);
8048 operands[3] = gen_lowpart (QImode, operands[3]);
8052 [(set (match_operand:SWI1248x 0 "mask_reg_operand")
8053 (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
8054 (match_operand:SWI1248x 2 "mask_reg_operand")))
8055 (clobber (reg:CC FLAGS_REG))]
8056 "TARGET_AVX512F && reload_completed"
8058 (any_logic:SWI1248x (match_dup 1)
8061 (define_mode_iterator SWI1248_AVX512BW
8062 [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
8064 (define_insn "*k<logic><mode>"
8065 [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
8066 (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
8067 (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
8070 if (!TARGET_AVX512DQ && <MODE>mode == QImode)
8071 return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
8073 return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
8075 [(set_attr "mode" "<MODE>")
8076 (set_attr "type" "msklog")
8077 (set_attr "prefix" "vex")])
8079 ;; %%% This used to optimize known byte-wide and operations to memory,
8080 ;; and sometimes to QImode registers. If this is considered useful,
8081 ;; it should be done with splitters.
8083 (define_expand "and<mode>3"
8084 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8085 (and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8086 (match_operand:SWIM1248x 2 "<general_szext_operand>")))]
8089 machine_mode mode = <MODE>mode;
8090 rtx (*insn) (rtx, rtx);
8092 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
8094 HOST_WIDE_INT ival = INTVAL (operands[2]);
8096 if (ival == (HOST_WIDE_INT) 0xffffffff)
8098 else if (ival == 0xffff)
8100 else if (ival == 0xff)
8104 if (mode == <MODE>mode)
8106 ix86_expand_binary_operator (AND, <MODE>mode, operands);
8110 if (<MODE>mode == DImode)
8111 insn = (mode == SImode)
8112 ? gen_zero_extendsidi2
8114 ? gen_zero_extendhidi2
8115 : gen_zero_extendqidi2;
8116 else if (<MODE>mode == SImode)
8117 insn = (mode == HImode)
8118 ? gen_zero_extendhisi2
8119 : gen_zero_extendqisi2;
8120 else if (<MODE>mode == HImode)
8121 insn = gen_zero_extendqihi2;
8125 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8129 (define_insn "*anddi_1"
8130 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
8132 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
8133 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
8134 (clobber (reg:CC FLAGS_REG))]
8135 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8137 switch (get_attr_type (insn))
8143 return "kandq\t{%2, %1, %0|%0, %1, %2}";
8146 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8147 if (get_attr_mode (insn) == MODE_SI)
8148 return "and{l}\t{%k2, %k0|%k0, %k2}";
8150 return "and{q}\t{%2, %0|%0, %2}";
8153 [(set_attr "type" "alu,alu,alu,imovx,msklog")
8154 (set_attr "length_immediate" "*,*,*,0,0")
8155 (set (attr "prefix_rex")
8157 (and (eq_attr "type" "imovx")
8158 (and (match_test "INTVAL (operands[2]) == 0xff")
8159 (match_operand 1 "ext_QIreg_operand")))
8161 (const_string "*")))
8162 (set_attr "mode" "SI,DI,DI,SI,DI")])
8164 (define_insn_and_split "*anddi3_doubleword"
8165 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8167 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8168 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8169 (clobber (reg:CC FLAGS_REG))]
8170 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8171 && ix86_binary_operator_ok (AND, DImode, operands)"
8173 "&& reload_completed"
8176 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8177 if (operands[2] == const0_rtx)
8179 operands[1] = const0_rtx;
8180 ix86_expand_move (SImode, &operands[0]);
8182 else if (operands[2] != constm1_rtx)
8183 ix86_expand_binary_operator (AND, SImode, &operands[0]);
8184 else if (operands[5] == constm1_rtx)
8185 emit_note (NOTE_INSN_DELETED);
8186 if (operands[5] == const0_rtx)
8188 operands[4] = const0_rtx;
8189 ix86_expand_move (SImode, &operands[3]);
8191 else if (operands[5] != constm1_rtx)
8192 ix86_expand_binary_operator (AND, SImode, &operands[3]);
8196 (define_insn "*andsi_1"
8197 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
8198 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
8199 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
8200 (clobber (reg:CC FLAGS_REG))]
8201 "ix86_binary_operator_ok (AND, SImode, operands)"
8203 switch (get_attr_type (insn))
8209 return "kandd\t{%2, %1, %0|%0, %1, %2}";
8212 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8213 return "and{l}\t{%2, %0|%0, %2}";
8216 [(set_attr "type" "alu,alu,imovx,msklog")
8217 (set (attr "prefix_rex")
8219 (and (eq_attr "type" "imovx")
8220 (and (match_test "INTVAL (operands[2]) == 0xff")
8221 (match_operand 1 "ext_QIreg_operand")))
8223 (const_string "*")))
8224 (set_attr "length_immediate" "*,*,0,0")
8225 (set_attr "mode" "SI")])
8227 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8228 (define_insn "*andsi_1_zext"
8229 [(set (match_operand:DI 0 "register_operand" "=r")
8231 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8232 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8233 (clobber (reg:CC FLAGS_REG))]
8234 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8235 "and{l}\t{%2, %k0|%k0, %2}"
8236 [(set_attr "type" "alu")
8237 (set_attr "mode" "SI")])
8239 (define_insn "*andhi_1"
8240 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
8241 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
8242 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
8243 (clobber (reg:CC FLAGS_REG))]
8244 "ix86_binary_operator_ok (AND, HImode, operands)"
8246 switch (get_attr_type (insn))
8252 return "kandw\t{%2, %1, %0|%0, %1, %2}";
8255 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8256 return "and{w}\t{%2, %0|%0, %2}";
8259 [(set_attr "type" "alu,alu,imovx,msklog")
8260 (set_attr "length_immediate" "*,*,0,*")
8261 (set (attr "prefix_rex")
8263 (and (eq_attr "type" "imovx")
8264 (match_operand 1 "ext_QIreg_operand"))
8266 (const_string "*")))
8267 (set_attr "mode" "HI,HI,SI,HI")])
8269 ;; %%% Potential partial reg stall on alternative 2. What to do?
8270 (define_insn "*andqi_1"
8271 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
8272 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8273 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
8274 (clobber (reg:CC FLAGS_REG))]
8275 "ix86_binary_operator_ok (AND, QImode, operands)"
8277 switch (which_alternative)
8281 return "and{b}\t{%2, %0|%0, %2}";
8283 return "and{l}\t{%k2, %k0|%k0, %k2}";
8285 return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
8286 : "kandw\t{%2, %1, %0|%0, %1, %2}";
8291 [(set_attr "type" "alu,alu,alu,msklog")
8292 (set_attr "mode" "QI,QI,SI,HI")])
8294 (define_insn "*andqi_1_slp"
8295 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8296 (and:QI (match_dup 0)
8297 (match_operand:QI 1 "general_operand" "qn,qmn")))
8298 (clobber (reg:CC FLAGS_REG))]
8299 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8300 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8301 "and{b}\t{%1, %0|%0, %1}"
8302 [(set_attr "type" "alu1")
8303 (set_attr "mode" "QI")])
8305 (define_insn "kandn<mode>"
8306 [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
8309 (match_operand:SWI12 1 "register_operand" "r,0,k"))
8310 (match_operand:SWI12 2 "register_operand" "r,r,k")))
8311 (clobber (reg:CC FLAGS_REG))]
8314 switch (which_alternative)
8317 return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
8321 if (TARGET_AVX512DQ && <MODE>mode == QImode)
8322 return "kandnb\t{%2, %1, %0|%0, %1, %2}";
8324 return "kandnw\t{%2, %1, %0|%0, %1, %2}";
8329 [(set_attr "isa" "bmi,*,avx512f")
8330 (set_attr "type" "bitmanip,*,msklog")
8331 (set_attr "prefix" "*,*,vex")
8332 (set_attr "btver2_decode" "direct,*,*")
8333 (set_attr "mode" "<MODE>")])
8336 [(set (match_operand:SWI12 0 "general_reg_operand")
8340 (match_operand:SWI12 1 "general_reg_operand")))
8341 (clobber (reg:CC FLAGS_REG))]
8342 "TARGET_AVX512F && !TARGET_BMI && reload_completed"
8344 (not:SWI12 (match_dup 0)))
8345 (parallel [(set (match_dup 0)
8346 (and:SWI12 (match_dup 0)
8348 (clobber (reg:CC FLAGS_REG))])])
8350 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8352 [(set (match_operand:DI 0 "register_operand")
8353 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8354 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8355 (clobber (reg:CC FLAGS_REG))]
8357 [(parallel [(set (match_dup 0)
8358 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8359 (clobber (reg:CC FLAGS_REG))])]
8360 "operands[2] = gen_lowpart (SImode, operands[2]);")
8363 [(set (match_operand:SWI248 0 "register_operand")
8364 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8365 (match_operand:SWI248 2 "const_int_operand")))
8366 (clobber (reg:CC FLAGS_REG))]
8368 && true_regnum (operands[0]) != true_regnum (operands[1])"
8371 HOST_WIDE_INT ival = INTVAL (operands[2]);
8373 rtx (*insn) (rtx, rtx);
8375 if (ival == (HOST_WIDE_INT) 0xffffffff)
8377 else if (ival == 0xffff)
8381 gcc_assert (ival == 0xff);
8385 if (<MODE>mode == DImode)
8386 insn = (mode == SImode)
8387 ? gen_zero_extendsidi2
8389 ? gen_zero_extendhidi2
8390 : gen_zero_extendqidi2;
8393 if (<MODE>mode != SImode)
8394 /* Zero extend to SImode to avoid partial register stalls. */
8395 operands[0] = gen_lowpart (SImode, operands[0]);
8397 insn = (mode == HImode)
8398 ? gen_zero_extendhisi2
8399 : gen_zero_extendqisi2;
8401 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8406 [(set (match_operand:SWI48 0 "register_operand")
8407 (and:SWI48 (match_dup 0)
8408 (const_int -65536)))
8409 (clobber (reg:CC FLAGS_REG))]
8410 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8411 || optimize_function_for_size_p (cfun)"
8412 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8413 "operands[1] = gen_lowpart (HImode, operands[0]);")
8416 [(set (match_operand:SWI248 0 "any_QIreg_operand")
8417 (and:SWI248 (match_dup 0)
8419 (clobber (reg:CC FLAGS_REG))]
8420 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8421 && reload_completed"
8422 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8423 "operands[1] = gen_lowpart (QImode, operands[0]);")
8426 [(set (match_operand:SWI248 0 "QIreg_operand")
8427 (and:SWI248 (match_dup 0)
8428 (const_int -65281)))
8429 (clobber (reg:CC FLAGS_REG))]
8430 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8431 && reload_completed"
8432 [(parallel [(set (zero_extract:SI (match_dup 0)
8436 (zero_extract:SI (match_dup 0)
8439 (zero_extract:SI (match_dup 0)
8442 (clobber (reg:CC FLAGS_REG))])]
8443 "operands[0] = gen_lowpart (SImode, operands[0]);")
8445 (define_insn "*anddi_2"
8446 [(set (reg FLAGS_REG)
8449 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8450 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8452 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8453 (and:DI (match_dup 1) (match_dup 2)))]
8455 && ix86_match_ccmode
8457 /* If we are going to emit andl instead of andq, and the operands[2]
8458 constant might have the SImode sign bit set, make sure the sign
8459 flag isn't tested, because the instruction will set the sign flag
8460 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8461 conservatively assume it might have bit 31 set. */
8462 (satisfies_constraint_Z (operands[2])
8463 && (!CONST_INT_P (operands[2])
8464 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8465 ? CCZmode : CCNOmode)
8466 && ix86_binary_operator_ok (AND, DImode, operands)"
8468 and{l}\t{%k2, %k0|%k0, %k2}
8469 and{q}\t{%2, %0|%0, %2}
8470 and{q}\t{%2, %0|%0, %2}"
8471 [(set_attr "type" "alu")
8472 (set_attr "mode" "SI,DI,DI")])
8474 (define_insn "*andqi_2_maybe_si"
8475 [(set (reg FLAGS_REG)
8477 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8478 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8480 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8481 (and:QI (match_dup 1) (match_dup 2)))]
8482 "ix86_binary_operator_ok (AND, QImode, operands)
8483 && ix86_match_ccmode (insn,
8484 CONST_INT_P (operands[2])
8485 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8487 if (which_alternative == 2)
8489 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8490 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8491 return "and{l}\t{%2, %k0|%k0, %2}";
8493 return "and{b}\t{%2, %0|%0, %2}";
8495 [(set_attr "type" "alu")
8496 (set_attr "mode" "QI,QI,SI")])
8498 (define_insn "*and<mode>_2"
8499 [(set (reg FLAGS_REG)
8500 (compare (and:SWI124
8501 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8502 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8504 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8505 (and:SWI124 (match_dup 1) (match_dup 2)))]
8506 "ix86_match_ccmode (insn, CCNOmode)
8507 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8508 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8509 [(set_attr "type" "alu")
8510 (set_attr "mode" "<MODE>")])
8512 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8513 (define_insn "*andsi_2_zext"
8514 [(set (reg FLAGS_REG)
8516 (match_operand:SI 1 "nonimmediate_operand" "%0")
8517 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8519 (set (match_operand:DI 0 "register_operand" "=r")
8520 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8521 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8522 && ix86_binary_operator_ok (AND, SImode, operands)"
8523 "and{l}\t{%2, %k0|%k0, %2}"
8524 [(set_attr "type" "alu")
8525 (set_attr "mode" "SI")])
8527 (define_insn "*andqi_2_slp"
8528 [(set (reg FLAGS_REG)
8530 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8531 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8533 (set (strict_low_part (match_dup 0))
8534 (and:QI (match_dup 0) (match_dup 1)))]
8535 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8536 && ix86_match_ccmode (insn, CCNOmode)
8537 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8538 "and{b}\t{%1, %0|%0, %1}"
8539 [(set_attr "type" "alu1")
8540 (set_attr "mode" "QI")])
8542 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8543 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8544 ;; for a QImode operand, which of course failed.
8545 (define_insn "andqi_ext_0"
8546 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8551 (match_operand 1 "ext_register_operand" "0")
8554 (match_operand 2 "const_int_operand" "n")))
8555 (clobber (reg:CC FLAGS_REG))]
8557 "and{b}\t{%2, %h0|%h0, %2}"
8558 [(set_attr "type" "alu")
8559 (set_attr "length_immediate" "1")
8560 (set_attr "modrm" "1")
8561 (set_attr "mode" "QI")])
8563 ;; Generated by peephole translating test to and. This shows up
8564 ;; often in fp comparisons.
8565 (define_insn "*andqi_ext_0_cc"
8566 [(set (reg FLAGS_REG)
8570 (match_operand 1 "ext_register_operand" "0")
8573 (match_operand 2 "const_int_operand" "n"))
8575 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8584 "ix86_match_ccmode (insn, CCNOmode)"
8585 "and{b}\t{%2, %h0|%h0, %2}"
8586 [(set_attr "type" "alu")
8587 (set_attr "length_immediate" "1")
8588 (set_attr "modrm" "1")
8589 (set_attr "mode" "QI")])
8591 (define_insn "*andqi_ext_1"
8592 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8597 (match_operand 1 "ext_register_operand" "0,0")
8601 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8602 (clobber (reg:CC FLAGS_REG))]
8604 "and{b}\t{%2, %h0|%h0, %2}"
8605 [(set_attr "isa" "*,nox64")
8606 (set_attr "type" "alu")
8607 (set_attr "length_immediate" "0")
8608 (set_attr "mode" "QI")])
8610 (define_insn "*andqi_ext_2"
8611 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8616 (match_operand 1 "ext_register_operand" "%0")
8620 (match_operand 2 "ext_register_operand" "Q")
8623 (clobber (reg:CC FLAGS_REG))]
8625 "and{b}\t{%h2, %h0|%h0, %h2}"
8626 [(set_attr "type" "alu")
8627 (set_attr "length_immediate" "0")
8628 (set_attr "mode" "QI")])
8630 ;; Convert wide AND instructions with immediate operand to shorter QImode
8631 ;; equivalents when possible.
8632 ;; Don't do the splitting with memory operands, since it introduces risk
8633 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8634 ;; for size, but that can (should?) be handled by generic code instead.
8636 [(set (match_operand 0 "QIreg_operand")
8637 (and (match_operand 1 "register_operand")
8638 (match_operand 2 "const_int_operand")))
8639 (clobber (reg:CC FLAGS_REG))]
8641 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8642 && !(~INTVAL (operands[2]) & ~(255 << 8))
8643 && GET_MODE (operands[0]) != QImode"
8644 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8645 (and:SI (zero_extract:SI (match_dup 1)
8646 (const_int 8) (const_int 8))
8648 (clobber (reg:CC FLAGS_REG))])]
8650 operands[0] = gen_lowpart (SImode, operands[0]);
8651 operands[1] = gen_lowpart (SImode, operands[1]);
8652 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8655 ;; Since AND can be encoded with sign extended immediate, this is only
8656 ;; profitable when 7th bit is not set.
8658 [(set (match_operand 0 "any_QIreg_operand")
8659 (and (match_operand 1 "general_operand")
8660 (match_operand 2 "const_int_operand")))
8661 (clobber (reg:CC FLAGS_REG))]
8663 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8664 && !(~INTVAL (operands[2]) & ~255)
8665 && !(INTVAL (operands[2]) & 128)
8666 && GET_MODE (operands[0]) != QImode"
8667 [(parallel [(set (strict_low_part (match_dup 0))
8668 (and:QI (match_dup 1)
8670 (clobber (reg:CC FLAGS_REG))])]
8672 operands[0] = gen_lowpart (QImode, operands[0]);
8673 operands[1] = gen_lowpart (QImode, operands[1]);
8674 operands[2] = gen_lowpart (QImode, operands[2]);
8677 ;; Logical inclusive and exclusive OR instructions
8679 ;; %%% This used to optimize known byte-wide and operations to memory.
8680 ;; If this is considered useful, it should be done with splitters.
8682 (define_expand "<code><mode>3"
8683 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8684 (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8685 (match_operand:SWIM1248x 2 "<general_operand>")))]
8687 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8689 (define_insn "*<code><mode>_1"
8690 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8692 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8693 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8694 (clobber (reg:CC FLAGS_REG))]
8695 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8697 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8698 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8699 k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8700 [(set_attr "type" "alu,alu,msklog")
8701 (set_attr "mode" "<MODE>")])
8703 (define_insn_and_split "*<code>di3_doubleword"
8704 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8706 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8707 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8708 (clobber (reg:CC FLAGS_REG))]
8709 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8710 && ix86_binary_operator_ok (<CODE>, DImode, operands)"
8712 "&& reload_completed"
8715 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8716 if (operands[2] == constm1_rtx)
8720 operands[1] = constm1_rtx;
8721 ix86_expand_move (SImode, &operands[0]);
8724 ix86_expand_unary_operator (NOT, SImode, &operands[0]);
8726 else if (operands[2] != const0_rtx)
8727 ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
8728 else if (operands[5] == const0_rtx)
8729 emit_note (NOTE_INSN_DELETED);
8730 if (operands[5] == constm1_rtx)
8734 operands[4] = constm1_rtx;
8735 ix86_expand_move (SImode, &operands[3]);
8738 ix86_expand_unary_operator (NOT, SImode, &operands[3]);
8740 else if (operands[5] != const0_rtx)
8741 ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
8745 (define_insn_and_split "*andndi3_doubleword"
8746 [(set (match_operand:DI 0 "register_operand" "=r,r")
8748 (not:DI (match_operand:DI 1 "register_operand" "r,r"))
8749 (match_operand:DI 2 "nonimmediate_operand" "r,m")))
8750 (clobber (reg:CC FLAGS_REG))]
8751 "TARGET_BMI && !TARGET_64BIT && TARGET_STV && TARGET_SSE"
8753 "&& reload_completed"
8754 [(parallel [(set (match_dup 0)
8755 (and:SI (not:SI (match_dup 1)) (match_dup 2)))
8756 (clobber (reg:CC FLAGS_REG))])
8757 (parallel [(set (match_dup 3)
8758 (and:SI (not:SI (match_dup 4)) (match_dup 5)))
8759 (clobber (reg:CC FLAGS_REG))])]
8760 "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
8762 (define_insn "*<code>hi_1"
8763 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8765 (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8766 (match_operand:HI 2 "general_operand" "rmn,rn,k")))
8767 (clobber (reg:CC FLAGS_REG))]
8768 "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8770 <logic>{w}\t{%2, %0|%0, %2}
8771 <logic>{w}\t{%2, %0|%0, %2}
8772 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8773 [(set_attr "type" "alu,alu,msklog")
8774 (set_attr "mode" "HI")])
8776 ;; %%% Potential partial reg stall on alternative 2. What to do?
8777 (define_insn "*<code>qi_1"
8778 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8779 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8780 (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8781 (clobber (reg:CC FLAGS_REG))]
8782 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8784 <logic>{b}\t{%2, %0|%0, %2}
8785 <logic>{b}\t{%2, %0|%0, %2}
8786 <logic>{l}\t{%k2, %k0|%k0, %k2}
8787 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8788 [(set_attr "type" "alu,alu,alu,msklog")
8789 (set_attr "mode" "QI,QI,SI,HI")])
8791 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8792 (define_insn "*<code>si_1_zext"
8793 [(set (match_operand:DI 0 "register_operand" "=r")
8795 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8796 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8797 (clobber (reg:CC FLAGS_REG))]
8798 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8799 "<logic>{l}\t{%2, %k0|%k0, %2}"
8800 [(set_attr "type" "alu")
8801 (set_attr "mode" "SI")])
8803 (define_insn "*<code>si_1_zext_imm"
8804 [(set (match_operand:DI 0 "register_operand" "=r")
8806 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8807 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8808 (clobber (reg:CC FLAGS_REG))]
8809 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8810 "<logic>{l}\t{%2, %k0|%k0, %2}"
8811 [(set_attr "type" "alu")
8812 (set_attr "mode" "SI")])
8814 (define_insn "*<code>qi_1_slp"
8815 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8816 (any_or:QI (match_dup 0)
8817 (match_operand:QI 1 "general_operand" "qmn,qn")))
8818 (clobber (reg:CC FLAGS_REG))]
8819 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8820 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8821 "<logic>{b}\t{%1, %0|%0, %1}"
8822 [(set_attr "type" "alu1")
8823 (set_attr "mode" "QI")])
8825 (define_insn "*<code><mode>_2"
8826 [(set (reg FLAGS_REG)
8827 (compare (any_or:SWI
8828 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8829 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8831 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8832 (any_or:SWI (match_dup 1) (match_dup 2)))]
8833 "ix86_match_ccmode (insn, CCNOmode)
8834 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8835 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8836 [(set_attr "type" "alu")
8837 (set_attr "mode" "<MODE>")])
8839 (define_insn "kxnor<mode>"
8840 [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8843 (match_operand:SWI12 1 "register_operand" "0,k")
8844 (match_operand:SWI12 2 "register_operand" "r,k"))))
8845 (clobber (reg:CC FLAGS_REG))]
8848 if (which_alternative == 0)
8851 if (<MODE>mode == QImode && TARGET_AVX512DQ)
8852 return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8853 return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8855 [(set_attr "type" "*,msklog")
8856 (set_attr "prefix" "*,vex")
8857 (set_attr "mode" "<MODE>")])
8859 (define_insn "kxnor<mode>"
8860 [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8863 (match_operand:SWI48x 1 "register_operand" "0,k")
8864 (match_operand:SWI48x 2 "register_operand" "r,k"))))
8865 (clobber (reg:CC FLAGS_REG))]
8869 kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8870 [(set_attr "type" "*,msklog")
8871 (set_attr "prefix" "*,vex")
8872 (set_attr "mode" "<MODE>")])
8875 [(set (match_operand:SWI1248x 0 "general_reg_operand")
8879 (match_operand:SWI1248x 1 "general_reg_operand"))))
8880 (clobber (reg:CC FLAGS_REG))]
8881 "TARGET_AVX512F && reload_completed"
8882 [(parallel [(set (match_dup 0)
8883 (xor:SWI1248x (match_dup 0)
8885 (clobber (reg:CC FLAGS_REG))])
8887 (not:SWI1248x (match_dup 0)))])
8889 ;;There are kortrest[bdq] but no intrinsics for them.
8890 ;;We probably don't need to implement them.
8891 (define_insn "kortestzhi"
8892 [(set (reg:CCZ FLAGS_REG)
8895 (match_operand:HI 0 "register_operand" "k")
8896 (match_operand:HI 1 "register_operand" "k"))
8898 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8899 "kortestw\t{%1, %0|%0, %1}"
8900 [(set_attr "mode" "HI")
8901 (set_attr "type" "msklog")
8902 (set_attr "prefix" "vex")])
8904 (define_insn "kortestchi"
8905 [(set (reg:CCC FLAGS_REG)
8908 (match_operand:HI 0 "register_operand" "k")
8909 (match_operand:HI 1 "register_operand" "k"))
8911 "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8912 "kortestw\t{%1, %0|%0, %1}"
8913 [(set_attr "mode" "HI")
8914 (set_attr "type" "msklog")
8915 (set_attr "prefix" "vex")])
8917 (define_insn "kunpckhi"
8918 [(set (match_operand:HI 0 "register_operand" "=k")
8921 (zero_extend:HI (match_operand:QI 1 "register_operand" "k"))
8923 (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8925 "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8926 [(set_attr "mode" "HI")
8927 (set_attr "type" "msklog")
8928 (set_attr "prefix" "vex")])
8930 (define_insn "kunpcksi"
8931 [(set (match_operand:SI 0 "register_operand" "=k")
8934 (zero_extend:SI (match_operand:HI 1 "register_operand" "k"))
8936 (zero_extend:SI (match_operand:HI 2 "register_operand" "k"))))]
8938 "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8939 [(set_attr "mode" "SI")])
8941 (define_insn "kunpckdi"
8942 [(set (match_operand:DI 0 "register_operand" "=k")
8945 (zero_extend:DI (match_operand:SI 1 "register_operand" "k"))
8947 (zero_extend:DI (match_operand:SI 2 "register_operand" "k"))))]
8949 "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8950 [(set_attr "mode" "DI")])
8952 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8953 ;; ??? Special case for immediate operand is missing - it is tricky.
8954 (define_insn "*<code>si_2_zext"
8955 [(set (reg FLAGS_REG)
8956 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8957 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8959 (set (match_operand:DI 0 "register_operand" "=r")
8960 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8961 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8962 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8963 "<logic>{l}\t{%2, %k0|%k0, %2}"
8964 [(set_attr "type" "alu")
8965 (set_attr "mode" "SI")])
8967 (define_insn "*<code>si_2_zext_imm"
8968 [(set (reg FLAGS_REG)
8970 (match_operand:SI 1 "nonimmediate_operand" "%0")
8971 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8973 (set (match_operand:DI 0 "register_operand" "=r")
8974 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8975 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8976 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8977 "<logic>{l}\t{%2, %k0|%k0, %2}"
8978 [(set_attr "type" "alu")
8979 (set_attr "mode" "SI")])
8981 (define_insn "*<code>qi_2_slp"
8982 [(set (reg FLAGS_REG)
8983 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8984 (match_operand:QI 1 "general_operand" "qmn,qn"))
8986 (set (strict_low_part (match_dup 0))
8987 (any_or:QI (match_dup 0) (match_dup 1)))]
8988 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8989 && ix86_match_ccmode (insn, CCNOmode)
8990 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8991 "<logic>{b}\t{%1, %0|%0, %1}"
8992 [(set_attr "type" "alu1")
8993 (set_attr "mode" "QI")])
8995 (define_insn "*<code><mode>_3"
8996 [(set (reg FLAGS_REG)
8997 (compare (any_or:SWI
8998 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8999 (match_operand:SWI 2 "<general_operand>" "<g>"))
9001 (clobber (match_scratch:SWI 0 "=<r>"))]
9002 "ix86_match_ccmode (insn, CCNOmode)
9003 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9004 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9005 [(set_attr "type" "alu")
9006 (set_attr "mode" "<MODE>")])
9008 (define_insn "*<code>qi_ext_0"
9009 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9014 (match_operand 1 "ext_register_operand" "0")
9017 (match_operand 2 "const_int_operand" "n")))
9018 (clobber (reg:CC FLAGS_REG))]
9019 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9020 "<logic>{b}\t{%2, %h0|%h0, %2}"
9021 [(set_attr "type" "alu")
9022 (set_attr "length_immediate" "1")
9023 (set_attr "modrm" "1")
9024 (set_attr "mode" "QI")])
9026 (define_insn "*<code>qi_ext_1"
9027 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
9032 (match_operand 1 "ext_register_operand" "0,0")
9036 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
9037 (clobber (reg:CC FLAGS_REG))]
9038 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9039 "<logic>{b}\t{%2, %h0|%h0, %2}"
9040 [(set_attr "isa" "*,nox64")
9041 (set_attr "type" "alu")
9042 (set_attr "length_immediate" "0")
9043 (set_attr "mode" "QI")])
9045 (define_insn "*<code>qi_ext_2"
9046 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9050 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9053 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9056 (clobber (reg:CC FLAGS_REG))]
9057 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9058 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9059 [(set_attr "type" "alu")
9060 (set_attr "length_immediate" "0")
9061 (set_attr "mode" "QI")])
9064 [(set (match_operand 0 "QIreg_operand")
9065 (any_or (match_operand 1 "register_operand")
9066 (match_operand 2 "const_int_operand")))
9067 (clobber (reg:CC FLAGS_REG))]
9069 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9070 && !(INTVAL (operands[2]) & ~(255 << 8))
9071 && GET_MODE (operands[0]) != QImode"
9072 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9073 (any_or:SI (zero_extract:SI (match_dup 1)
9074 (const_int 8) (const_int 8))
9076 (clobber (reg:CC FLAGS_REG))])]
9078 operands[0] = gen_lowpart (SImode, operands[0]);
9079 operands[1] = gen_lowpart (SImode, operands[1]);
9080 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
9083 ;; Since OR can be encoded with sign extended immediate, this is only
9084 ;; profitable when 7th bit is set.
9086 [(set (match_operand 0 "any_QIreg_operand")
9087 (any_or (match_operand 1 "general_operand")
9088 (match_operand 2 "const_int_operand")))
9089 (clobber (reg:CC FLAGS_REG))]
9091 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9092 && !(INTVAL (operands[2]) & ~255)
9093 && (INTVAL (operands[2]) & 128)
9094 && GET_MODE (operands[0]) != QImode"
9095 [(parallel [(set (strict_low_part (match_dup 0))
9096 (any_or:QI (match_dup 1)
9098 (clobber (reg:CC FLAGS_REG))])]
9100 operands[0] = gen_lowpart (QImode, operands[0]);
9101 operands[1] = gen_lowpart (QImode, operands[1]);
9102 operands[2] = gen_lowpart (QImode, operands[2]);
9105 (define_expand "xorqi_cc_ext_1"
9107 (set (reg:CCNO FLAGS_REG)
9111 (match_operand 1 "ext_register_operand")
9114 (match_operand:QI 2 "const_int_operand"))
9116 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9126 (define_insn "*xorqi_cc_ext_1"
9127 [(set (reg FLAGS_REG)
9131 (match_operand 1 "ext_register_operand" "0,0")
9134 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
9136 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
9145 "ix86_match_ccmode (insn, CCNOmode)"
9146 "xor{b}\t{%2, %h0|%h0, %2}"
9147 [(set_attr "isa" "*,nox64")
9148 (set_attr "type" "alu")
9149 (set_attr "modrm" "1")
9150 (set_attr "mode" "QI")])
9152 ;; Negation instructions
9154 (define_expand "neg<mode>2"
9155 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
9156 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
9158 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9160 (define_insn_and_split "*neg<dwi>2_doubleword"
9161 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9162 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9163 (clobber (reg:CC FLAGS_REG))]
9164 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9168 [(set (reg:CCZ FLAGS_REG)
9169 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9170 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9173 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9176 (clobber (reg:CC FLAGS_REG))])
9179 (neg:DWIH (match_dup 2)))
9180 (clobber (reg:CC FLAGS_REG))])]
9181 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
9183 (define_insn "*neg<mode>2_1"
9184 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9185 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9186 (clobber (reg:CC FLAGS_REG))]
9187 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9188 "neg{<imodesuffix>}\t%0"
9189 [(set_attr "type" "negnot")
9190 (set_attr "mode" "<MODE>")])
9192 ;; Combine is quite creative about this pattern.
9193 (define_insn "*negsi2_1_zext"
9194 [(set (match_operand:DI 0 "register_operand" "=r")
9196 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9199 (clobber (reg:CC FLAGS_REG))]
9200 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9202 [(set_attr "type" "negnot")
9203 (set_attr "mode" "SI")])
9205 ;; The problem with neg is that it does not perform (compare x 0),
9206 ;; it really performs (compare 0 x), which leaves us with the zero
9207 ;; flag being the only useful item.
9209 (define_insn "*neg<mode>2_cmpz"
9210 [(set (reg:CCZ FLAGS_REG)
9212 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9214 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9215 (neg:SWI (match_dup 1)))]
9216 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9217 "neg{<imodesuffix>}\t%0"
9218 [(set_attr "type" "negnot")
9219 (set_attr "mode" "<MODE>")])
9221 (define_insn "*negsi2_cmpz_zext"
9222 [(set (reg:CCZ FLAGS_REG)
9226 (match_operand:DI 1 "register_operand" "0")
9230 (set (match_operand:DI 0 "register_operand" "=r")
9231 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9234 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9236 [(set_attr "type" "negnot")
9237 (set_attr "mode" "SI")])
9239 ;; Negate with jump on overflow.
9240 (define_expand "negv<mode>3"
9241 [(parallel [(set (reg:CCO FLAGS_REG)
9242 (ne:CCO (match_operand:SWI 1 "register_operand")
9244 (set (match_operand:SWI 0 "register_operand")
9245 (neg:SWI (match_dup 1)))])
9246 (set (pc) (if_then_else
9247 (eq (reg:CCO FLAGS_REG) (const_int 0))
9248 (label_ref (match_operand 2))
9253 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
9257 (define_insn "*negv<mode>3"
9258 [(set (reg:CCO FLAGS_REG)
9259 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
9260 (match_operand:SWI 2 "const_int_operand")))
9261 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9262 (neg:SWI (match_dup 1)))]
9263 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
9264 && mode_signbit_p (<MODE>mode, operands[2])"
9265 "neg{<imodesuffix>}\t%0"
9266 [(set_attr "type" "negnot")
9267 (set_attr "mode" "<MODE>")])
9269 ;; Changing of sign for FP values is doable using integer unit too.
9271 (define_expand "<code><mode>2"
9272 [(set (match_operand:X87MODEF 0 "register_operand")
9273 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
9274 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9275 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9277 (define_insn "*absneg<mode>2_mixed"
9278 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9279 (match_operator:MODEF 3 "absneg_operator"
9280 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9281 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9282 (clobber (reg:CC FLAGS_REG))]
9283 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9285 [(set (attr "enabled")
9286 (cond [(eq_attr "alternative" "2")
9287 (symbol_ref "TARGET_MIX_SSE_I387")
9289 (symbol_ref "true")))])
9291 (define_insn "*absneg<mode>2_i387"
9292 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9293 (match_operator:X87MODEF 3 "absneg_operator"
9294 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9295 (use (match_operand 2))
9296 (clobber (reg:CC FLAGS_REG))]
9297 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9300 (define_expand "<code>tf2"
9301 [(set (match_operand:TF 0 "register_operand")
9302 (absneg:TF (match_operand:TF 1 "register_operand")))]
9304 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9306 (define_insn "*absnegtf2_sse"
9307 [(set (match_operand:TF 0 "register_operand" "=x,x")
9308 (match_operator:TF 3 "absneg_operator"
9309 [(match_operand:TF 1 "register_operand" "0,x")]))
9310 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9311 (clobber (reg:CC FLAGS_REG))]
9315 ;; Splitters for fp abs and neg.
9318 [(set (match_operand 0 "fp_register_operand")
9319 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9320 (use (match_operand 2))
9321 (clobber (reg:CC FLAGS_REG))]
9323 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9326 [(set (match_operand 0 "register_operand")
9327 (match_operator 3 "absneg_operator"
9328 [(match_operand 1 "register_operand")]))
9329 (use (match_operand 2 "nonimmediate_operand"))
9330 (clobber (reg:CC FLAGS_REG))]
9331 "reload_completed && SSE_REG_P (operands[0])"
9332 [(set (match_dup 0) (match_dup 3))]
9334 machine_mode mode = GET_MODE (operands[0]);
9335 machine_mode vmode = GET_MODE (operands[2]);
9338 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9339 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9340 if (operands_match_p (operands[0], operands[2]))
9341 std::swap (operands[1], operands[2]);
9342 if (GET_CODE (operands[3]) == ABS)
9343 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9345 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9350 [(set (match_operand:SF 0 "general_reg_operand")
9351 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9352 (use (match_operand:V4SF 2))
9353 (clobber (reg:CC FLAGS_REG))]
9355 [(parallel [(set (match_dup 0) (match_dup 1))
9356 (clobber (reg:CC FLAGS_REG))])]
9359 operands[0] = gen_lowpart (SImode, operands[0]);
9360 if (GET_CODE (operands[1]) == ABS)
9362 tmp = gen_int_mode (0x7fffffff, SImode);
9363 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9367 tmp = gen_int_mode (0x80000000, SImode);
9368 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9374 [(set (match_operand:DF 0 "general_reg_operand")
9375 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9376 (use (match_operand 2))
9377 (clobber (reg:CC FLAGS_REG))]
9379 [(parallel [(set (match_dup 0) (match_dup 1))
9380 (clobber (reg:CC FLAGS_REG))])]
9385 tmp = gen_lowpart (DImode, operands[0]);
9386 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9389 if (GET_CODE (operands[1]) == ABS)
9392 tmp = gen_rtx_NOT (DImode, tmp);
9396 operands[0] = gen_highpart (SImode, operands[0]);
9397 if (GET_CODE (operands[1]) == ABS)
9399 tmp = gen_int_mode (0x7fffffff, SImode);
9400 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9404 tmp = gen_int_mode (0x80000000, SImode);
9405 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9412 [(set (match_operand:XF 0 "general_reg_operand")
9413 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9414 (use (match_operand 2))
9415 (clobber (reg:CC FLAGS_REG))]
9417 [(parallel [(set (match_dup 0) (match_dup 1))
9418 (clobber (reg:CC FLAGS_REG))])]
9421 operands[0] = gen_rtx_REG (SImode,
9422 true_regnum (operands[0])
9423 + (TARGET_64BIT ? 1 : 2));
9424 if (GET_CODE (operands[1]) == ABS)
9426 tmp = GEN_INT (0x7fff);
9427 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9431 tmp = GEN_INT (0x8000);
9432 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9437 ;; Conditionalize these after reload. If they match before reload, we
9438 ;; lose the clobber and ability to use integer instructions.
9440 (define_insn "*<code><mode>2_1"
9441 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9442 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9444 && (reload_completed
9445 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9446 "f<absneg_mnemonic>"
9447 [(set_attr "type" "fsgn")
9448 (set_attr "mode" "<MODE>")])
9450 (define_insn "*<code>extendsfdf2"
9451 [(set (match_operand:DF 0 "register_operand" "=f")
9452 (absneg:DF (float_extend:DF
9453 (match_operand:SF 1 "register_operand" "0"))))]
9454 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9455 "f<absneg_mnemonic>"
9456 [(set_attr "type" "fsgn")
9457 (set_attr "mode" "DF")])
9459 (define_insn "*<code>extendsfxf2"
9460 [(set (match_operand:XF 0 "register_operand" "=f")
9461 (absneg:XF (float_extend:XF
9462 (match_operand:SF 1 "register_operand" "0"))))]
9464 "f<absneg_mnemonic>"
9465 [(set_attr "type" "fsgn")
9466 (set_attr "mode" "XF")])
9468 (define_insn "*<code>extenddfxf2"
9469 [(set (match_operand:XF 0 "register_operand" "=f")
9470 (absneg:XF (float_extend:XF
9471 (match_operand:DF 1 "register_operand" "0"))))]
9473 "f<absneg_mnemonic>"
9474 [(set_attr "type" "fsgn")
9475 (set_attr "mode" "XF")])
9477 ;; Copysign instructions
9479 (define_mode_iterator CSGNMODE [SF DF TF])
9480 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9482 (define_expand "copysign<mode>3"
9483 [(match_operand:CSGNMODE 0 "register_operand")
9484 (match_operand:CSGNMODE 1 "nonmemory_operand")
9485 (match_operand:CSGNMODE 2 "register_operand")]
9486 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9487 || (TARGET_SSE && (<MODE>mode == TFmode))"
9488 "ix86_expand_copysign (operands); DONE;")
9490 (define_insn_and_split "copysign<mode>3_const"
9491 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9493 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9494 (match_operand:CSGNMODE 2 "register_operand" "0")
9495 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9497 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9498 || (TARGET_SSE && (<MODE>mode == TFmode))"
9500 "&& reload_completed"
9502 "ix86_split_copysign_const (operands); DONE;")
9504 (define_insn "copysign<mode>3_var"
9505 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9507 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9508 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9509 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9510 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9512 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9513 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9514 || (TARGET_SSE && (<MODE>mode == TFmode))"
9518 [(set (match_operand:CSGNMODE 0 "register_operand")
9520 [(match_operand:CSGNMODE 2 "register_operand")
9521 (match_operand:CSGNMODE 3 "register_operand")
9522 (match_operand:<CSGNVMODE> 4)
9523 (match_operand:<CSGNVMODE> 5)]
9525 (clobber (match_scratch:<CSGNVMODE> 1))]
9526 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9527 || (TARGET_SSE && (<MODE>mode == TFmode)))
9528 && reload_completed"
9530 "ix86_split_copysign_var (operands); DONE;")
9532 ;; One complement instructions
9534 (define_expand "one_cmpl<mode>2"
9535 [(set (match_operand:SWIM 0 "nonimmediate_operand")
9536 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9538 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9540 (define_insn "*one_cmpl<mode>2_1"
9541 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
9542 (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
9543 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9545 not{<imodesuffix>}\t%0
9546 knot<mskmodesuffix>\t{%1, %0|%0, %1}"
9547 [(set_attr "isa" "*,avx512bw")
9548 (set_attr "type" "negnot,msklog")
9549 (set_attr "prefix" "*,vex")
9550 (set_attr "mode" "<MODE>")])
9552 (define_insn "*one_cmplhi2_1"
9553 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
9554 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
9555 "ix86_unary_operator_ok (NOT, HImode, operands)"
9558 knotw\t{%1, %0|%0, %1}"
9559 [(set_attr "isa" "*,avx512f")
9560 (set_attr "type" "negnot,msklog")
9561 (set_attr "prefix" "*,vex")
9562 (set_attr "mode" "HI")])
9564 ;; %%% Potential partial reg stall on alternative 1. What to do?
9565 (define_insn "*one_cmplqi2_1"
9566 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
9567 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
9568 "ix86_unary_operator_ok (NOT, QImode, operands)"
9570 switch (which_alternative)
9573 return "not{b}\t%0";
9575 return "not{l}\t%k0";
9577 if (TARGET_AVX512DQ)
9578 return "knotb\t{%1, %0|%0, %1}";
9579 return "knotw\t{%1, %0|%0, %1}";
9584 [(set_attr "isa" "*,*,avx512f")
9585 (set_attr "type" "negnot,negnot,msklog")
9586 (set_attr "prefix" "*,*,vex")
9587 (set_attr "mode" "QI,SI,QI")])
9589 ;; ??? Currently never generated - xor is used instead.
9590 (define_insn "*one_cmplsi2_1_zext"
9591 [(set (match_operand:DI 0 "register_operand" "=r")
9593 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9594 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9596 [(set_attr "type" "negnot")
9597 (set_attr "mode" "SI")])
9599 (define_insn "*one_cmpl<mode>2_2"
9600 [(set (reg FLAGS_REG)
9601 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9603 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9604 (not:SWI (match_dup 1)))]
9605 "ix86_match_ccmode (insn, CCNOmode)
9606 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9608 [(set_attr "type" "alu1")
9609 (set_attr "mode" "<MODE>")])
9612 [(set (match_operand 0 "flags_reg_operand")
9613 (match_operator 2 "compare_operator"
9614 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9616 (set (match_operand:SWI 1 "nonimmediate_operand")
9617 (not:SWI (match_dup 3)))]
9618 "ix86_match_ccmode (insn, CCNOmode)"
9619 [(parallel [(set (match_dup 0)
9620 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9623 (xor:SWI (match_dup 3) (const_int -1)))])])
9625 ;; ??? Currently never generated - xor is used instead.
9626 (define_insn "*one_cmplsi2_2_zext"
9627 [(set (reg FLAGS_REG)
9628 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9630 (set (match_operand:DI 0 "register_operand" "=r")
9631 (zero_extend:DI (not:SI (match_dup 1))))]
9632 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9633 && ix86_unary_operator_ok (NOT, SImode, operands)"
9635 [(set_attr "type" "alu1")
9636 (set_attr "mode" "SI")])
9639 [(set (match_operand 0 "flags_reg_operand")
9640 (match_operator 2 "compare_operator"
9641 [(not:SI (match_operand:SI 3 "register_operand"))
9643 (set (match_operand:DI 1 "register_operand")
9644 (zero_extend:DI (not:SI (match_dup 3))))]
9645 "ix86_match_ccmode (insn, CCNOmode)"
9646 [(parallel [(set (match_dup 0)
9647 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9650 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9652 ;; Shift instructions
9654 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9655 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9656 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9657 ;; from the assembler input.
9659 ;; This instruction shifts the target reg/mem as usual, but instead of
9660 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9661 ;; is a left shift double, bits are taken from the high order bits of
9662 ;; reg, else if the insn is a shift right double, bits are taken from the
9663 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9664 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9666 ;; Since sh[lr]d does not change the `reg' operand, that is done
9667 ;; separately, making all shifts emit pairs of shift double and normal
9668 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9669 ;; support a 63 bit shift, each shift where the count is in a reg expands
9670 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9672 ;; If the shift count is a constant, we need never emit more than one
9673 ;; shift pair, instead using moves and sign extension for counts greater
9676 (define_insn "*<mshift><mode>3"
9677 [(set (match_operand:SWI1248_AVX512BWDQ 0 "register_operand" "=k")
9678 (any_lshift:SWI1248_AVX512BWDQ (match_operand:SWI1248_AVX512BWDQ 1 "register_operand" "k")
9679 (match_operand:QI 2 "immediate_operand" "i")))]
9681 "k<mshift><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
9682 [(set_attr "type" "msklog")
9683 (set_attr "prefix" "vex")])
9685 (define_expand "ashl<mode>3"
9686 [(set (match_operand:SDWIM 0 "<shift_operand>")
9687 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9688 (match_operand:QI 2 "nonmemory_operand")))]
9690 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9692 (define_insn "*ashl<mode>3_doubleword"
9693 [(set (match_operand:DWI 0 "register_operand" "=&r,&r")
9694 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9695 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9696 (clobber (reg:CC FLAGS_REG))]
9699 [(set_attr "type" "multi")])
9702 [(set (match_operand:DWI 0 "register_operand")
9703 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9704 (match_operand:QI 2 "nonmemory_operand")))
9705 (clobber (reg:CC FLAGS_REG))]
9706 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9708 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9710 ;; By default we don't ask for a scratch register, because when DWImode
9711 ;; values are manipulated, registers are already at a premium. But if
9712 ;; we have one handy, we won't turn it away.
9715 [(match_scratch:DWIH 3 "r")
9716 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9718 (match_operand:<DWI> 1 "nonmemory_operand")
9719 (match_operand:QI 2 "nonmemory_operand")))
9720 (clobber (reg:CC FLAGS_REG))])
9724 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9726 (define_insn "x86_64_shld"
9727 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9728 (ior:DI (ashift:DI (match_dup 0)
9729 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9730 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9731 (minus:QI (const_int 64) (match_dup 2)))))
9732 (clobber (reg:CC FLAGS_REG))]
9734 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9735 [(set_attr "type" "ishift")
9736 (set_attr "prefix_0f" "1")
9737 (set_attr "mode" "DI")
9738 (set_attr "athlon_decode" "vector")
9739 (set_attr "amdfam10_decode" "vector")
9740 (set_attr "bdver1_decode" "vector")])
9742 (define_insn "x86_shld"
9743 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9744 (ior:SI (ashift:SI (match_dup 0)
9745 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9746 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9747 (minus:QI (const_int 32) (match_dup 2)))))
9748 (clobber (reg:CC FLAGS_REG))]
9750 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9751 [(set_attr "type" "ishift")
9752 (set_attr "prefix_0f" "1")
9753 (set_attr "mode" "SI")
9754 (set_attr "pent_pair" "np")
9755 (set_attr "athlon_decode" "vector")
9756 (set_attr "amdfam10_decode" "vector")
9757 (set_attr "bdver1_decode" "vector")])
9759 (define_expand "x86_shift<mode>_adj_1"
9760 [(set (reg:CCZ FLAGS_REG)
9761 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9764 (set (match_operand:SWI48 0 "register_operand")
9765 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9766 (match_operand:SWI48 1 "register_operand")
9769 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9770 (match_operand:SWI48 3 "register_operand")
9773 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9775 (define_expand "x86_shift<mode>_adj_2"
9776 [(use (match_operand:SWI48 0 "register_operand"))
9777 (use (match_operand:SWI48 1 "register_operand"))
9778 (use (match_operand:QI 2 "register_operand"))]
9781 rtx_code_label *label = gen_label_rtx ();
9784 emit_insn (gen_testqi_ccz_1 (operands[2],
9785 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9787 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9788 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9789 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9790 gen_rtx_LABEL_REF (VOIDmode, label),
9792 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
9793 JUMP_LABEL (tmp) = label;
9795 emit_move_insn (operands[0], operands[1]);
9796 ix86_expand_clear (operands[1]);
9799 LABEL_NUSES (label) = 1;
9804 ;; Avoid useless masking of count operand.
9805 (define_insn "*ashl<mode>3_mask"
9806 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9808 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9811 (match_operand:SI 2 "register_operand" "c")
9812 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9813 (clobber (reg:CC FLAGS_REG))]
9814 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9815 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9816 == GET_MODE_BITSIZE (<MODE>mode)-1"
9818 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9820 [(set_attr "type" "ishift")
9821 (set_attr "mode" "<MODE>")])
9823 (define_insn "*bmi2_ashl<mode>3_1"
9824 [(set (match_operand:SWI48 0 "register_operand" "=r")
9825 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9826 (match_operand:SWI48 2 "register_operand" "r")))]
9828 "shlx\t{%2, %1, %0|%0, %1, %2}"
9829 [(set_attr "type" "ishiftx")
9830 (set_attr "mode" "<MODE>")])
9832 (define_insn "*ashl<mode>3_1"
9833 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9834 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9835 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9836 (clobber (reg:CC FLAGS_REG))]
9837 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9839 switch (get_attr_type (insn))
9846 gcc_assert (operands[2] == const1_rtx);
9847 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9848 return "add{<imodesuffix>}\t%0, %0";
9851 if (operands[2] == const1_rtx
9852 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9853 return "sal{<imodesuffix>}\t%0";
9855 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9858 [(set_attr "isa" "*,*,bmi2")
9860 (cond [(eq_attr "alternative" "1")
9861 (const_string "lea")
9862 (eq_attr "alternative" "2")
9863 (const_string "ishiftx")
9864 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9865 (match_operand 0 "register_operand"))
9866 (match_operand 2 "const1_operand"))
9867 (const_string "alu")
9869 (const_string "ishift")))
9870 (set (attr "length_immediate")
9872 (ior (eq_attr "type" "alu")
9873 (and (eq_attr "type" "ishift")
9874 (and (match_operand 2 "const1_operand")
9875 (ior (match_test "TARGET_SHIFT1")
9876 (match_test "optimize_function_for_size_p (cfun)")))))
9878 (const_string "*")))
9879 (set_attr "mode" "<MODE>")])
9881 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9883 [(set (match_operand:SWI48 0 "register_operand")
9884 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9885 (match_operand:QI 2 "register_operand")))
9886 (clobber (reg:CC FLAGS_REG))]
9887 "TARGET_BMI2 && reload_completed"
9889 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9890 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9892 (define_insn "*bmi2_ashlsi3_1_zext"
9893 [(set (match_operand:DI 0 "register_operand" "=r")
9895 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9896 (match_operand:SI 2 "register_operand" "r"))))]
9897 "TARGET_64BIT && TARGET_BMI2"
9898 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9899 [(set_attr "type" "ishiftx")
9900 (set_attr "mode" "SI")])
9902 (define_insn "*ashlsi3_1_zext"
9903 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9905 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9906 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9907 (clobber (reg:CC FLAGS_REG))]
9908 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9910 switch (get_attr_type (insn))
9917 gcc_assert (operands[2] == const1_rtx);
9918 return "add{l}\t%k0, %k0";
9921 if (operands[2] == const1_rtx
9922 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9923 return "sal{l}\t%k0";
9925 return "sal{l}\t{%2, %k0|%k0, %2}";
9928 [(set_attr "isa" "*,*,bmi2")
9930 (cond [(eq_attr "alternative" "1")
9931 (const_string "lea")
9932 (eq_attr "alternative" "2")
9933 (const_string "ishiftx")
9934 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9935 (match_operand 2 "const1_operand"))
9936 (const_string "alu")
9938 (const_string "ishift")))
9939 (set (attr "length_immediate")
9941 (ior (eq_attr "type" "alu")
9942 (and (eq_attr "type" "ishift")
9943 (and (match_operand 2 "const1_operand")
9944 (ior (match_test "TARGET_SHIFT1")
9945 (match_test "optimize_function_for_size_p (cfun)")))))
9947 (const_string "*")))
9948 (set_attr "mode" "SI")])
9950 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9952 [(set (match_operand:DI 0 "register_operand")
9954 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9955 (match_operand:QI 2 "register_operand"))))
9956 (clobber (reg:CC FLAGS_REG))]
9957 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9959 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9960 "operands[2] = gen_lowpart (SImode, operands[2]);")
9962 (define_insn "*ashlhi3_1"
9963 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9964 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9965 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9966 (clobber (reg:CC FLAGS_REG))]
9967 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9969 switch (get_attr_type (insn))
9975 gcc_assert (operands[2] == const1_rtx);
9976 return "add{w}\t%0, %0";
9979 if (operands[2] == const1_rtx
9980 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9981 return "sal{w}\t%0";
9983 return "sal{w}\t{%2, %0|%0, %2}";
9987 (cond [(eq_attr "alternative" "1")
9988 (const_string "lea")
9989 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9990 (match_operand 0 "register_operand"))
9991 (match_operand 2 "const1_operand"))
9992 (const_string "alu")
9994 (const_string "ishift")))
9995 (set (attr "length_immediate")
9997 (ior (eq_attr "type" "alu")
9998 (and (eq_attr "type" "ishift")
9999 (and (match_operand 2 "const1_operand")
10000 (ior (match_test "TARGET_SHIFT1")
10001 (match_test "optimize_function_for_size_p (cfun)")))))
10003 (const_string "*")))
10004 (set_attr "mode" "HI,SI")])
10006 ;; %%% Potential partial reg stall on alternative 1. What to do?
10007 (define_insn "*ashlqi3_1"
10008 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
10009 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10010 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10011 (clobber (reg:CC FLAGS_REG))]
10012 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10014 switch (get_attr_type (insn))
10020 gcc_assert (operands[2] == const1_rtx);
10021 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
10022 return "add{l}\t%k0, %k0";
10024 return "add{b}\t%0, %0";
10027 if (operands[2] == const1_rtx
10028 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10030 if (get_attr_mode (insn) == MODE_SI)
10031 return "sal{l}\t%k0";
10033 return "sal{b}\t%0";
10037 if (get_attr_mode (insn) == MODE_SI)
10038 return "sal{l}\t{%2, %k0|%k0, %2}";
10040 return "sal{b}\t{%2, %0|%0, %2}";
10044 [(set (attr "type")
10045 (cond [(eq_attr "alternative" "2")
10046 (const_string "lea")
10047 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10048 (match_operand 0 "register_operand"))
10049 (match_operand 2 "const1_operand"))
10050 (const_string "alu")
10052 (const_string "ishift")))
10053 (set (attr "length_immediate")
10055 (ior (eq_attr "type" "alu")
10056 (and (eq_attr "type" "ishift")
10057 (and (match_operand 2 "const1_operand")
10058 (ior (match_test "TARGET_SHIFT1")
10059 (match_test "optimize_function_for_size_p (cfun)")))))
10061 (const_string "*")))
10062 (set_attr "mode" "QI,SI,SI")])
10064 (define_insn "*ashlqi3_1_slp"
10065 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10066 (ashift:QI (match_dup 0)
10067 (match_operand:QI 1 "nonmemory_operand" "cI")))
10068 (clobber (reg:CC FLAGS_REG))]
10069 "(optimize_function_for_size_p (cfun)
10070 || !TARGET_PARTIAL_FLAG_REG_STALL
10071 || (operands[1] == const1_rtx
10073 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10075 switch (get_attr_type (insn))
10078 gcc_assert (operands[1] == const1_rtx);
10079 return "add{b}\t%0, %0";
10082 if (operands[1] == const1_rtx
10083 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10084 return "sal{b}\t%0";
10086 return "sal{b}\t{%1, %0|%0, %1}";
10089 [(set (attr "type")
10090 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10091 (match_operand 0 "register_operand"))
10092 (match_operand 1 "const1_operand"))
10093 (const_string "alu")
10095 (const_string "ishift1")))
10096 (set (attr "length_immediate")
10098 (ior (eq_attr "type" "alu")
10099 (and (eq_attr "type" "ishift1")
10100 (and (match_operand 1 "const1_operand")
10101 (ior (match_test "TARGET_SHIFT1")
10102 (match_test "optimize_function_for_size_p (cfun)")))))
10104 (const_string "*")))
10105 (set_attr "mode" "QI")])
10107 ;; Convert ashift to the lea pattern to avoid flags dependency.
10109 [(set (match_operand 0 "register_operand")
10110 (ashift (match_operand 1 "index_register_operand")
10111 (match_operand:QI 2 "const_int_operand")))
10112 (clobber (reg:CC FLAGS_REG))]
10113 "GET_MODE (operands[0]) == GET_MODE (operands[1])
10114 && reload_completed
10115 && true_regnum (operands[0]) != true_regnum (operands[1])"
10118 machine_mode mode = GET_MODE (operands[0]);
10121 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
10124 operands[0] = gen_lowpart (mode, operands[0]);
10125 operands[1] = gen_lowpart (mode, operands[1]);
10128 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
10130 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
10132 emit_insn (gen_rtx_SET (operands[0], pat));
10136 ;; Convert ashift to the lea pattern to avoid flags dependency.
10138 [(set (match_operand:DI 0 "register_operand")
10140 (ashift:SI (match_operand:SI 1 "index_register_operand")
10141 (match_operand:QI 2 "const_int_operand"))))
10142 (clobber (reg:CC FLAGS_REG))]
10143 "TARGET_64BIT && reload_completed
10144 && true_regnum (operands[0]) != true_regnum (operands[1])"
10145 [(set (match_dup 0)
10146 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10148 operands[1] = gen_lowpart (SImode, operands[1]);
10149 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
10152 ;; This pattern can't accept a variable shift count, since shifts by
10153 ;; zero don't affect the flags. We assume that shifts by constant
10154 ;; zero are optimized away.
10155 (define_insn "*ashl<mode>3_cmp"
10156 [(set (reg FLAGS_REG)
10158 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10159 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10161 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10162 (ashift:SWI (match_dup 1) (match_dup 2)))]
10163 "(optimize_function_for_size_p (cfun)
10164 || !TARGET_PARTIAL_FLAG_REG_STALL
10165 || (operands[2] == const1_rtx
10167 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10168 && ix86_match_ccmode (insn, CCGOCmode)
10169 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10171 switch (get_attr_type (insn))
10174 gcc_assert (operands[2] == const1_rtx);
10175 return "add{<imodesuffix>}\t%0, %0";
10178 if (operands[2] == const1_rtx
10179 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10180 return "sal{<imodesuffix>}\t%0";
10182 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10185 [(set (attr "type")
10186 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10187 (match_operand 0 "register_operand"))
10188 (match_operand 2 "const1_operand"))
10189 (const_string "alu")
10191 (const_string "ishift")))
10192 (set (attr "length_immediate")
10194 (ior (eq_attr "type" "alu")
10195 (and (eq_attr "type" "ishift")
10196 (and (match_operand 2 "const1_operand")
10197 (ior (match_test "TARGET_SHIFT1")
10198 (match_test "optimize_function_for_size_p (cfun)")))))
10200 (const_string "*")))
10201 (set_attr "mode" "<MODE>")])
10203 (define_insn "*ashlsi3_cmp_zext"
10204 [(set (reg FLAGS_REG)
10206 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10207 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10209 (set (match_operand:DI 0 "register_operand" "=r")
10210 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10212 && (optimize_function_for_size_p (cfun)
10213 || !TARGET_PARTIAL_FLAG_REG_STALL
10214 || (operands[2] == const1_rtx
10216 || TARGET_DOUBLE_WITH_ADD)))
10217 && ix86_match_ccmode (insn, CCGOCmode)
10218 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10220 switch (get_attr_type (insn))
10223 gcc_assert (operands[2] == const1_rtx);
10224 return "add{l}\t%k0, %k0";
10227 if (operands[2] == const1_rtx
10228 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10229 return "sal{l}\t%k0";
10231 return "sal{l}\t{%2, %k0|%k0, %2}";
10234 [(set (attr "type")
10235 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
10236 (match_operand 2 "const1_operand"))
10237 (const_string "alu")
10239 (const_string "ishift")))
10240 (set (attr "length_immediate")
10242 (ior (eq_attr "type" "alu")
10243 (and (eq_attr "type" "ishift")
10244 (and (match_operand 2 "const1_operand")
10245 (ior (match_test "TARGET_SHIFT1")
10246 (match_test "optimize_function_for_size_p (cfun)")))))
10248 (const_string "*")))
10249 (set_attr "mode" "SI")])
10251 (define_insn "*ashl<mode>3_cconly"
10252 [(set (reg FLAGS_REG)
10254 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
10255 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10257 (clobber (match_scratch:SWI 0 "=<r>"))]
10258 "(optimize_function_for_size_p (cfun)
10259 || !TARGET_PARTIAL_FLAG_REG_STALL
10260 || (operands[2] == const1_rtx
10262 || TARGET_DOUBLE_WITH_ADD)))
10263 && ix86_match_ccmode (insn, CCGOCmode)"
10265 switch (get_attr_type (insn))
10268 gcc_assert (operands[2] == const1_rtx);
10269 return "add{<imodesuffix>}\t%0, %0";
10272 if (operands[2] == const1_rtx
10273 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10274 return "sal{<imodesuffix>}\t%0";
10276 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10279 [(set (attr "type")
10280 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10281 (match_operand 0 "register_operand"))
10282 (match_operand 2 "const1_operand"))
10283 (const_string "alu")
10285 (const_string "ishift")))
10286 (set (attr "length_immediate")
10288 (ior (eq_attr "type" "alu")
10289 (and (eq_attr "type" "ishift")
10290 (and (match_operand 2 "const1_operand")
10291 (ior (match_test "TARGET_SHIFT1")
10292 (match_test "optimize_function_for_size_p (cfun)")))))
10294 (const_string "*")))
10295 (set_attr "mode" "<MODE>")])
10297 ;; See comment above `ashl<mode>3' about how this works.
10299 (define_expand "<shift_insn><mode>3"
10300 [(set (match_operand:SDWIM 0 "<shift_operand>")
10301 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
10302 (match_operand:QI 2 "nonmemory_operand")))]
10304 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10306 ;; Avoid useless masking of count operand.
10307 (define_insn "*<shift_insn><mode>3_mask"
10308 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10310 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10313 (match_operand:SI 2 "register_operand" "c")
10314 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10315 (clobber (reg:CC FLAGS_REG))]
10316 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10317 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10318 == GET_MODE_BITSIZE (<MODE>mode)-1"
10320 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10322 [(set_attr "type" "ishift")
10323 (set_attr "mode" "<MODE>")])
10325 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
10326 [(set (match_operand:DWI 0 "register_operand" "=&r")
10327 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10328 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10329 (clobber (reg:CC FLAGS_REG))]
10332 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10334 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10335 [(set_attr "type" "multi")])
10337 ;; By default we don't ask for a scratch register, because when DWImode
10338 ;; values are manipulated, registers are already at a premium. But if
10339 ;; we have one handy, we won't turn it away.
10342 [(match_scratch:DWIH 3 "r")
10343 (parallel [(set (match_operand:<DWI> 0 "register_operand")
10345 (match_operand:<DWI> 1 "register_operand")
10346 (match_operand:QI 2 "nonmemory_operand")))
10347 (clobber (reg:CC FLAGS_REG))])
10351 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
10353 (define_insn "x86_64_shrd"
10354 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10355 (ior:DI (lshiftrt:DI (match_dup 0)
10356 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10357 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10358 (minus:QI (const_int 64) (match_dup 2)))))
10359 (clobber (reg:CC FLAGS_REG))]
10361 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10362 [(set_attr "type" "ishift")
10363 (set_attr "prefix_0f" "1")
10364 (set_attr "mode" "DI")
10365 (set_attr "athlon_decode" "vector")
10366 (set_attr "amdfam10_decode" "vector")
10367 (set_attr "bdver1_decode" "vector")])
10369 (define_insn "x86_shrd"
10370 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10371 (ior:SI (lshiftrt:SI (match_dup 0)
10372 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10373 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10374 (minus:QI (const_int 32) (match_dup 2)))))
10375 (clobber (reg:CC FLAGS_REG))]
10377 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10378 [(set_attr "type" "ishift")
10379 (set_attr "prefix_0f" "1")
10380 (set_attr "mode" "SI")
10381 (set_attr "pent_pair" "np")
10382 (set_attr "athlon_decode" "vector")
10383 (set_attr "amdfam10_decode" "vector")
10384 (set_attr "bdver1_decode" "vector")])
10386 (define_insn "ashrdi3_cvt"
10387 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10388 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10389 (match_operand:QI 2 "const_int_operand")))
10390 (clobber (reg:CC FLAGS_REG))]
10391 "TARGET_64BIT && INTVAL (operands[2]) == 63
10392 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10393 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10396 sar{q}\t{%2, %0|%0, %2}"
10397 [(set_attr "type" "imovx,ishift")
10398 (set_attr "prefix_0f" "0,*")
10399 (set_attr "length_immediate" "0,*")
10400 (set_attr "modrm" "0,1")
10401 (set_attr "mode" "DI")])
10403 (define_insn "ashrsi3_cvt"
10404 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10405 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10406 (match_operand:QI 2 "const_int_operand")))
10407 (clobber (reg:CC FLAGS_REG))]
10408 "INTVAL (operands[2]) == 31
10409 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10410 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10413 sar{l}\t{%2, %0|%0, %2}"
10414 [(set_attr "type" "imovx,ishift")
10415 (set_attr "prefix_0f" "0,*")
10416 (set_attr "length_immediate" "0,*")
10417 (set_attr "modrm" "0,1")
10418 (set_attr "mode" "SI")])
10420 (define_insn "*ashrsi3_cvt_zext"
10421 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10423 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10424 (match_operand:QI 2 "const_int_operand"))))
10425 (clobber (reg:CC FLAGS_REG))]
10426 "TARGET_64BIT && INTVAL (operands[2]) == 31
10427 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10428 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10431 sar{l}\t{%2, %k0|%k0, %2}"
10432 [(set_attr "type" "imovx,ishift")
10433 (set_attr "prefix_0f" "0,*")
10434 (set_attr "length_immediate" "0,*")
10435 (set_attr "modrm" "0,1")
10436 (set_attr "mode" "SI")])
10438 (define_expand "x86_shift<mode>_adj_3"
10439 [(use (match_operand:SWI48 0 "register_operand"))
10440 (use (match_operand:SWI48 1 "register_operand"))
10441 (use (match_operand:QI 2 "register_operand"))]
10444 rtx_code_label *label = gen_label_rtx ();
10447 emit_insn (gen_testqi_ccz_1 (operands[2],
10448 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10450 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10451 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10452 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10453 gen_rtx_LABEL_REF (VOIDmode, label),
10455 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10456 JUMP_LABEL (tmp) = label;
10458 emit_move_insn (operands[0], operands[1]);
10459 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10460 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10461 emit_label (label);
10462 LABEL_NUSES (label) = 1;
10467 (define_insn "*bmi2_<shift_insn><mode>3_1"
10468 [(set (match_operand:SWI48 0 "register_operand" "=r")
10469 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10470 (match_operand:SWI48 2 "register_operand" "r")))]
10472 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10473 [(set_attr "type" "ishiftx")
10474 (set_attr "mode" "<MODE>")])
10476 (define_insn "*<shift_insn><mode>3_1"
10477 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10479 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10480 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10481 (clobber (reg:CC FLAGS_REG))]
10482 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10484 switch (get_attr_type (insn))
10490 if (operands[2] == const1_rtx
10491 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10492 return "<shift>{<imodesuffix>}\t%0";
10494 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10497 [(set_attr "isa" "*,bmi2")
10498 (set_attr "type" "ishift,ishiftx")
10499 (set (attr "length_immediate")
10501 (and (match_operand 2 "const1_operand")
10502 (ior (match_test "TARGET_SHIFT1")
10503 (match_test "optimize_function_for_size_p (cfun)")))
10505 (const_string "*")))
10506 (set_attr "mode" "<MODE>")])
10508 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10510 [(set (match_operand:SWI48 0 "register_operand")
10511 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10512 (match_operand:QI 2 "register_operand")))
10513 (clobber (reg:CC FLAGS_REG))]
10514 "TARGET_BMI2 && reload_completed"
10515 [(set (match_dup 0)
10516 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10517 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10519 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10520 [(set (match_operand:DI 0 "register_operand" "=r")
10522 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10523 (match_operand:SI 2 "register_operand" "r"))))]
10524 "TARGET_64BIT && TARGET_BMI2"
10525 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10526 [(set_attr "type" "ishiftx")
10527 (set_attr "mode" "SI")])
10529 (define_insn "*<shift_insn>si3_1_zext"
10530 [(set (match_operand:DI 0 "register_operand" "=r,r")
10532 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10533 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10534 (clobber (reg:CC FLAGS_REG))]
10535 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10537 switch (get_attr_type (insn))
10543 if (operands[2] == const1_rtx
10544 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10545 return "<shift>{l}\t%k0";
10547 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10550 [(set_attr "isa" "*,bmi2")
10551 (set_attr "type" "ishift,ishiftx")
10552 (set (attr "length_immediate")
10554 (and (match_operand 2 "const1_operand")
10555 (ior (match_test "TARGET_SHIFT1")
10556 (match_test "optimize_function_for_size_p (cfun)")))
10558 (const_string "*")))
10559 (set_attr "mode" "SI")])
10561 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10563 [(set (match_operand:DI 0 "register_operand")
10565 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10566 (match_operand:QI 2 "register_operand"))))
10567 (clobber (reg:CC FLAGS_REG))]
10568 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10569 [(set (match_dup 0)
10570 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10571 "operands[2] = gen_lowpart (SImode, operands[2]);")
10573 (define_insn "*<shift_insn><mode>3_1"
10574 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10576 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10577 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10578 (clobber (reg:CC FLAGS_REG))]
10579 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10581 if (operands[2] == const1_rtx
10582 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10583 return "<shift>{<imodesuffix>}\t%0";
10585 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10587 [(set_attr "type" "ishift")
10588 (set (attr "length_immediate")
10590 (and (match_operand 2 "const1_operand")
10591 (ior (match_test "TARGET_SHIFT1")
10592 (match_test "optimize_function_for_size_p (cfun)")))
10594 (const_string "*")))
10595 (set_attr "mode" "<MODE>")])
10597 (define_insn "*<shift_insn>qi3_1_slp"
10598 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10599 (any_shiftrt:QI (match_dup 0)
10600 (match_operand:QI 1 "nonmemory_operand" "cI")))
10601 (clobber (reg:CC FLAGS_REG))]
10602 "(optimize_function_for_size_p (cfun)
10603 || !TARGET_PARTIAL_REG_STALL
10604 || (operands[1] == const1_rtx
10605 && TARGET_SHIFT1))"
10607 if (operands[1] == const1_rtx
10608 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10609 return "<shift>{b}\t%0";
10611 return "<shift>{b}\t{%1, %0|%0, %1}";
10613 [(set_attr "type" "ishift1")
10614 (set (attr "length_immediate")
10616 (and (match_operand 1 "const1_operand")
10617 (ior (match_test "TARGET_SHIFT1")
10618 (match_test "optimize_function_for_size_p (cfun)")))
10620 (const_string "*")))
10621 (set_attr "mode" "QI")])
10623 ;; This pattern can't accept a variable shift count, since shifts by
10624 ;; zero don't affect the flags. We assume that shifts by constant
10625 ;; zero are optimized away.
10626 (define_insn "*<shift_insn><mode>3_cmp"
10627 [(set (reg FLAGS_REG)
10630 (match_operand:SWI 1 "nonimmediate_operand" "0")
10631 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10633 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10634 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10635 "(optimize_function_for_size_p (cfun)
10636 || !TARGET_PARTIAL_FLAG_REG_STALL
10637 || (operands[2] == const1_rtx
10639 && ix86_match_ccmode (insn, CCGOCmode)
10640 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10642 if (operands[2] == const1_rtx
10643 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10644 return "<shift>{<imodesuffix>}\t%0";
10646 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10648 [(set_attr "type" "ishift")
10649 (set (attr "length_immediate")
10651 (and (match_operand 2 "const1_operand")
10652 (ior (match_test "TARGET_SHIFT1")
10653 (match_test "optimize_function_for_size_p (cfun)")))
10655 (const_string "*")))
10656 (set_attr "mode" "<MODE>")])
10658 (define_insn "*<shift_insn>si3_cmp_zext"
10659 [(set (reg FLAGS_REG)
10661 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10662 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10664 (set (match_operand:DI 0 "register_operand" "=r")
10665 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10667 && (optimize_function_for_size_p (cfun)
10668 || !TARGET_PARTIAL_FLAG_REG_STALL
10669 || (operands[2] == const1_rtx
10671 && ix86_match_ccmode (insn, CCGOCmode)
10672 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10674 if (operands[2] == const1_rtx
10675 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10676 return "<shift>{l}\t%k0";
10678 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10680 [(set_attr "type" "ishift")
10681 (set (attr "length_immediate")
10683 (and (match_operand 2 "const1_operand")
10684 (ior (match_test "TARGET_SHIFT1")
10685 (match_test "optimize_function_for_size_p (cfun)")))
10687 (const_string "*")))
10688 (set_attr "mode" "SI")])
10690 (define_insn "*<shift_insn><mode>3_cconly"
10691 [(set (reg FLAGS_REG)
10694 (match_operand:SWI 1 "register_operand" "0")
10695 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10697 (clobber (match_scratch:SWI 0 "=<r>"))]
10698 "(optimize_function_for_size_p (cfun)
10699 || !TARGET_PARTIAL_FLAG_REG_STALL
10700 || (operands[2] == const1_rtx
10702 && ix86_match_ccmode (insn, CCGOCmode)"
10704 if (operands[2] == const1_rtx
10705 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10706 return "<shift>{<imodesuffix>}\t%0";
10708 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10710 [(set_attr "type" "ishift")
10711 (set (attr "length_immediate")
10713 (and (match_operand 2 "const1_operand")
10714 (ior (match_test "TARGET_SHIFT1")
10715 (match_test "optimize_function_for_size_p (cfun)")))
10717 (const_string "*")))
10718 (set_attr "mode" "<MODE>")])
10720 ;; Rotate instructions
10722 (define_expand "<rotate_insn>ti3"
10723 [(set (match_operand:TI 0 "register_operand")
10724 (any_rotate:TI (match_operand:TI 1 "register_operand")
10725 (match_operand:QI 2 "nonmemory_operand")))]
10728 if (const_1_to_63_operand (operands[2], VOIDmode))
10729 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10730 (operands[0], operands[1], operands[2]));
10737 (define_expand "<rotate_insn>di3"
10738 [(set (match_operand:DI 0 "shiftdi_operand")
10739 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10740 (match_operand:QI 2 "nonmemory_operand")))]
10744 ix86_expand_binary_operator (<CODE>, DImode, operands);
10745 else if (const_1_to_31_operand (operands[2], VOIDmode))
10746 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10747 (operands[0], operands[1], operands[2]));
10754 (define_expand "<rotate_insn><mode>3"
10755 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10756 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10757 (match_operand:QI 2 "nonmemory_operand")))]
10759 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10761 ;; Avoid useless masking of count operand.
10762 (define_insn "*<rotate_insn><mode>3_mask"
10763 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10765 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10768 (match_operand:SI 2 "register_operand" "c")
10769 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10770 (clobber (reg:CC FLAGS_REG))]
10771 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10772 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10773 == GET_MODE_BITSIZE (<MODE>mode)-1"
10775 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10777 [(set_attr "type" "rotate")
10778 (set_attr "mode" "<MODE>")])
10780 ;; Implement rotation using two double-precision
10781 ;; shift instructions and a scratch register.
10783 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10784 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10785 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10786 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10787 (clobber (reg:CC FLAGS_REG))
10788 (clobber (match_scratch:DWIH 3 "=&r"))]
10792 [(set (match_dup 3) (match_dup 4))
10794 [(set (match_dup 4)
10795 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10796 (lshiftrt:DWIH (match_dup 5)
10797 (minus:QI (match_dup 6) (match_dup 2)))))
10798 (clobber (reg:CC FLAGS_REG))])
10800 [(set (match_dup 5)
10801 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10802 (lshiftrt:DWIH (match_dup 3)
10803 (minus:QI (match_dup 6) (match_dup 2)))))
10804 (clobber (reg:CC FLAGS_REG))])]
10806 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10808 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10811 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10812 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10813 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10814 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10815 (clobber (reg:CC FLAGS_REG))
10816 (clobber (match_scratch:DWIH 3 "=&r"))]
10820 [(set (match_dup 3) (match_dup 4))
10822 [(set (match_dup 4)
10823 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10824 (ashift:DWIH (match_dup 5)
10825 (minus:QI (match_dup 6) (match_dup 2)))))
10826 (clobber (reg:CC FLAGS_REG))])
10828 [(set (match_dup 5)
10829 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10830 (ashift:DWIH (match_dup 3)
10831 (minus:QI (match_dup 6) (match_dup 2)))))
10832 (clobber (reg:CC FLAGS_REG))])]
10834 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10836 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10839 (define_insn "*bmi2_rorx<mode>3_1"
10840 [(set (match_operand:SWI48 0 "register_operand" "=r")
10841 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10842 (match_operand:QI 2 "immediate_operand" "<S>")))]
10844 "rorx\t{%2, %1, %0|%0, %1, %2}"
10845 [(set_attr "type" "rotatex")
10846 (set_attr "mode" "<MODE>")])
10848 (define_insn "*<rotate_insn><mode>3_1"
10849 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10851 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10852 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10853 (clobber (reg:CC FLAGS_REG))]
10854 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10856 switch (get_attr_type (insn))
10862 if (operands[2] == const1_rtx
10863 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10864 return "<rotate>{<imodesuffix>}\t%0";
10866 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10869 [(set_attr "isa" "*,bmi2")
10870 (set_attr "type" "rotate,rotatex")
10871 (set (attr "length_immediate")
10873 (and (eq_attr "type" "rotate")
10874 (and (match_operand 2 "const1_operand")
10875 (ior (match_test "TARGET_SHIFT1")
10876 (match_test "optimize_function_for_size_p (cfun)"))))
10878 (const_string "*")))
10879 (set_attr "mode" "<MODE>")])
10881 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10883 [(set (match_operand:SWI48 0 "register_operand")
10884 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10885 (match_operand:QI 2 "immediate_operand")))
10886 (clobber (reg:CC FLAGS_REG))]
10887 "TARGET_BMI2 && reload_completed"
10888 [(set (match_dup 0)
10889 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10891 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
10893 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
10897 [(set (match_operand:SWI48 0 "register_operand")
10898 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10899 (match_operand:QI 2 "immediate_operand")))
10900 (clobber (reg:CC FLAGS_REG))]
10901 "TARGET_BMI2 && reload_completed"
10902 [(set (match_dup 0)
10903 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10905 (define_insn "*bmi2_rorxsi3_1_zext"
10906 [(set (match_operand:DI 0 "register_operand" "=r")
10908 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10909 (match_operand:QI 2 "immediate_operand" "I"))))]
10910 "TARGET_64BIT && TARGET_BMI2"
10911 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10912 [(set_attr "type" "rotatex")
10913 (set_attr "mode" "SI")])
10915 (define_insn "*<rotate_insn>si3_1_zext"
10916 [(set (match_operand:DI 0 "register_operand" "=r,r")
10918 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10919 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10920 (clobber (reg:CC FLAGS_REG))]
10921 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10923 switch (get_attr_type (insn))
10929 if (operands[2] == const1_rtx
10930 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10931 return "<rotate>{l}\t%k0";
10933 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10936 [(set_attr "isa" "*,bmi2")
10937 (set_attr "type" "rotate,rotatex")
10938 (set (attr "length_immediate")
10940 (and (eq_attr "type" "rotate")
10941 (and (match_operand 2 "const1_operand")
10942 (ior (match_test "TARGET_SHIFT1")
10943 (match_test "optimize_function_for_size_p (cfun)"))))
10945 (const_string "*")))
10946 (set_attr "mode" "SI")])
10948 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10950 [(set (match_operand:DI 0 "register_operand")
10952 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10953 (match_operand:QI 2 "immediate_operand"))))
10954 (clobber (reg:CC FLAGS_REG))]
10955 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10956 [(set (match_dup 0)
10957 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10959 int bitsize = GET_MODE_BITSIZE (SImode);
10961 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
10965 [(set (match_operand:DI 0 "register_operand")
10967 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10968 (match_operand:QI 2 "immediate_operand"))))
10969 (clobber (reg:CC FLAGS_REG))]
10970 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10971 [(set (match_dup 0)
10972 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10974 (define_insn "*<rotate_insn><mode>3_1"
10975 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10976 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10977 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10978 (clobber (reg:CC FLAGS_REG))]
10979 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10981 if (operands[2] == const1_rtx
10982 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10983 return "<rotate>{<imodesuffix>}\t%0";
10985 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10987 [(set_attr "type" "rotate")
10988 (set (attr "length_immediate")
10990 (and (match_operand 2 "const1_operand")
10991 (ior (match_test "TARGET_SHIFT1")
10992 (match_test "optimize_function_for_size_p (cfun)")))
10994 (const_string "*")))
10995 (set_attr "mode" "<MODE>")])
10997 (define_insn "*<rotate_insn>qi3_1_slp"
10998 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10999 (any_rotate:QI (match_dup 0)
11000 (match_operand:QI 1 "nonmemory_operand" "cI")))
11001 (clobber (reg:CC FLAGS_REG))]
11002 "(optimize_function_for_size_p (cfun)
11003 || !TARGET_PARTIAL_REG_STALL
11004 || (operands[1] == const1_rtx
11005 && TARGET_SHIFT1))"
11007 if (operands[1] == const1_rtx
11008 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11009 return "<rotate>{b}\t%0";
11011 return "<rotate>{b}\t{%1, %0|%0, %1}";
11013 [(set_attr "type" "rotate1")
11014 (set (attr "length_immediate")
11016 (and (match_operand 1 "const1_operand")
11017 (ior (match_test "TARGET_SHIFT1")
11018 (match_test "optimize_function_for_size_p (cfun)")))
11020 (const_string "*")))
11021 (set_attr "mode" "QI")])
11024 [(set (match_operand:HI 0 "register_operand")
11025 (any_rotate:HI (match_dup 0) (const_int 8)))
11026 (clobber (reg:CC FLAGS_REG))]
11028 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
11029 [(parallel [(set (strict_low_part (match_dup 0))
11030 (bswap:HI (match_dup 0)))
11031 (clobber (reg:CC FLAGS_REG))])])
11033 ;; Bit set / bit test instructions
11035 ;; %%% bts, btr, btc, bt.
11036 ;; In general these instructions are *slow* when applied to memory,
11037 ;; since they enforce atomic operation. When applied to registers,
11038 ;; it depends on the cpu implementation. They're never faster than
11039 ;; the corresponding and/ior/xor operations, so with 32-bit there's
11040 ;; no point. But in 64-bit, we can't hold the relevant immediates
11041 ;; within the instruction itself, so operating on bits in the high
11042 ;; 32-bits of a register becomes easier.
11044 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
11045 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
11046 ;; negdf respectively, so they can never be disabled entirely.
11048 (define_insn "*btsq"
11049 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
11051 (match_operand 1 "const_0_to_63_operand" "J"))
11053 (clobber (reg:CC FLAGS_REG))]
11054 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11055 "bts{q}\t{%1, %0|%0, %1}"
11056 [(set_attr "type" "alu1")
11057 (set_attr "prefix_0f" "1")
11058 (set_attr "znver1_decode" "double")
11059 (set_attr "mode" "DI")])
11061 (define_insn "*btrq"
11062 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
11064 (match_operand 1 "const_0_to_63_operand" "J"))
11066 (clobber (reg:CC FLAGS_REG))]
11067 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11068 "btr{q}\t{%1, %0|%0, %1}"
11069 [(set_attr "type" "alu1")
11070 (set_attr "prefix_0f" "1")
11071 (set_attr "znver1_decode" "double")
11072 (set_attr "mode" "DI")])
11074 (define_insn "*btcq"
11075 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
11077 (match_operand 1 "const_0_to_63_operand" "J"))
11078 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
11079 (clobber (reg:CC FLAGS_REG))]
11080 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11081 "btc{q}\t{%1, %0|%0, %1}"
11082 [(set_attr "type" "alu1")
11083 (set_attr "prefix_0f" "1")
11084 (set_attr "znver1_decode" "double")
11085 (set_attr "mode" "DI")])
11087 ;; Allow Nocona to avoid these instructions if a register is available.
11090 [(match_scratch:DI 2 "r")
11091 (parallel [(set (zero_extract:DI
11092 (match_operand:DI 0 "register_operand")
11094 (match_operand 1 "const_0_to_63_operand"))
11096 (clobber (reg:CC FLAGS_REG))])]
11097 "TARGET_64BIT && !TARGET_USE_BT"
11098 [(parallel [(set (match_dup 0)
11099 (ior:DI (match_dup 0) (match_dup 3)))
11100 (clobber (reg:CC FLAGS_REG))])]
11102 int i = INTVAL (operands[1]);
11104 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11106 if (!x86_64_immediate_operand (operands[3], DImode))
11108 emit_move_insn (operands[2], operands[3]);
11109 operands[3] = operands[2];
11114 [(match_scratch:DI 2 "r")
11115 (parallel [(set (zero_extract:DI
11116 (match_operand:DI 0 "register_operand")
11118 (match_operand 1 "const_0_to_63_operand"))
11120 (clobber (reg:CC FLAGS_REG))])]
11121 "TARGET_64BIT && !TARGET_USE_BT"
11122 [(parallel [(set (match_dup 0)
11123 (and:DI (match_dup 0) (match_dup 3)))
11124 (clobber (reg:CC FLAGS_REG))])]
11126 int i = INTVAL (operands[1]);
11128 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
11130 if (!x86_64_immediate_operand (operands[3], DImode))
11132 emit_move_insn (operands[2], operands[3]);
11133 operands[3] = operands[2];
11138 [(match_scratch:DI 2 "r")
11139 (parallel [(set (zero_extract:DI
11140 (match_operand:DI 0 "register_operand")
11142 (match_operand 1 "const_0_to_63_operand"))
11143 (not:DI (zero_extract:DI
11144 (match_dup 0) (const_int 1) (match_dup 1))))
11145 (clobber (reg:CC FLAGS_REG))])]
11146 "TARGET_64BIT && !TARGET_USE_BT"
11147 [(parallel [(set (match_dup 0)
11148 (xor:DI (match_dup 0) (match_dup 3)))
11149 (clobber (reg:CC FLAGS_REG))])]
11151 int i = INTVAL (operands[1]);
11153 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11155 if (!x86_64_immediate_operand (operands[3], DImode))
11157 emit_move_insn (operands[2], operands[3]);
11158 operands[3] = operands[2];
11162 (define_insn "*bt<mode>"
11163 [(set (reg:CCC FLAGS_REG)
11165 (zero_extract:SWI48
11166 (match_operand:SWI48 0 "register_operand" "r")
11168 (match_operand:SI 1 "nonmemory_operand" "rN"))
11172 switch (get_attr_mode (insn))
11175 return "bt{l}\t{%1, %k0|%k0, %1}";
11178 return "bt{q}\t{%q1, %0|%0, %q1}";
11181 gcc_unreachable ();
11184 [(set_attr "type" "alu1")
11185 (set_attr "prefix_0f" "1")
11188 (and (match_test "CONST_INT_P (operands[1])")
11189 (match_test "INTVAL (operands[1]) < 32"))
11190 (const_string "SI")
11191 (const_string "<MODE>")))])
11193 (define_insn_and_split "*jcc_bt<mode>"
11195 (if_then_else (match_operator 0 "bt_comparison_operator"
11196 [(zero_extract:SWI48
11197 (match_operand:SWI48 1 "register_operand")
11199 (match_operand:SI 2 "nonmemory_operand"))
11201 (label_ref (match_operand 3))
11203 (clobber (reg:CC FLAGS_REG))]
11204 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11205 && (CONST_INT_P (operands[2])
11206 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
11207 && INTVAL (operands[2])
11208 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
11209 : register_operand (operands[2], SImode))
11210 && can_create_pseudo_p ()"
11213 [(set (reg:CCC FLAGS_REG)
11215 (zero_extract:SWI48
11221 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11222 (label_ref (match_dup 3))
11225 operands[0] = shallow_copy_rtx (operands[0]);
11226 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11229 (define_insn_and_split "*jcc_bt<mode>_1"
11231 (if_then_else (match_operator 0 "bt_comparison_operator"
11232 [(zero_extract:SWI48
11233 (match_operand:SWI48 1 "register_operand")
11236 (match_operand:QI 2 "register_operand")))
11238 (label_ref (match_operand 3))
11240 (clobber (reg:CC FLAGS_REG))]
11241 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11242 && can_create_pseudo_p ()"
11245 [(set (reg:CCC FLAGS_REG)
11247 (zero_extract:SWI48
11253 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11254 (label_ref (match_dup 3))
11257 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11258 operands[0] = shallow_copy_rtx (operands[0]);
11259 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11262 ;; Avoid useless masking of bit offset operand.
11263 (define_insn_and_split "*jcc_bt<mode>_mask"
11265 (if_then_else (match_operator 0 "bt_comparison_operator"
11266 [(zero_extract:SWI48
11267 (match_operand:SWI48 1 "register_operand")
11270 (match_operand:SI 2 "register_operand")
11271 (match_operand 3 "const_int_operand")))])
11272 (label_ref (match_operand 4))
11274 (clobber (reg:CC FLAGS_REG))]
11275 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11276 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11277 == GET_MODE_BITSIZE (<MODE>mode)-1
11278 && can_create_pseudo_p ()"
11281 [(set (reg:CCC FLAGS_REG)
11283 (zero_extract:SWI48
11289 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11290 (label_ref (match_dup 4))
11293 operands[0] = shallow_copy_rtx (operands[0]);
11294 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11297 ;; Store-flag instructions.
11299 ;; For all sCOND expanders, also expand the compare or test insn that
11300 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
11302 (define_insn_and_split "*setcc_di_1"
11303 [(set (match_operand:DI 0 "register_operand" "=q")
11304 (match_operator:DI 1 "ix86_comparison_operator"
11305 [(reg FLAGS_REG) (const_int 0)]))]
11306 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
11308 "&& reload_completed"
11309 [(set (match_dup 2) (match_dup 1))
11310 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
11312 operands[1] = shallow_copy_rtx (operands[1]);
11313 PUT_MODE (operands[1], QImode);
11314 operands[2] = gen_lowpart (QImode, operands[0]);
11317 (define_insn_and_split "*setcc_si_1_and"
11318 [(set (match_operand:SI 0 "register_operand" "=q")
11319 (match_operator:SI 1 "ix86_comparison_operator"
11320 [(reg FLAGS_REG) (const_int 0)]))
11321 (clobber (reg:CC FLAGS_REG))]
11322 "!TARGET_PARTIAL_REG_STALL
11323 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
11325 "&& reload_completed"
11326 [(set (match_dup 2) (match_dup 1))
11327 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
11328 (clobber (reg:CC FLAGS_REG))])]
11330 operands[1] = shallow_copy_rtx (operands[1]);
11331 PUT_MODE (operands[1], QImode);
11332 operands[2] = gen_lowpart (QImode, operands[0]);
11335 (define_insn_and_split "*setcc_si_1_movzbl"
11336 [(set (match_operand:SI 0 "register_operand" "=q")
11337 (match_operator:SI 1 "ix86_comparison_operator"
11338 [(reg FLAGS_REG) (const_int 0)]))]
11339 "!TARGET_PARTIAL_REG_STALL
11340 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
11342 "&& reload_completed"
11343 [(set (match_dup 2) (match_dup 1))
11344 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
11346 operands[1] = shallow_copy_rtx (operands[1]);
11347 PUT_MODE (operands[1], QImode);
11348 operands[2] = gen_lowpart (QImode, operands[0]);
11351 (define_insn "*setcc_qi"
11352 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11353 (match_operator:QI 1 "ix86_comparison_operator"
11354 [(reg FLAGS_REG) (const_int 0)]))]
11357 [(set_attr "type" "setcc")
11358 (set_attr "mode" "QI")])
11360 (define_insn "*setcc_qi_slp"
11361 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11362 (match_operator:QI 1 "ix86_comparison_operator"
11363 [(reg FLAGS_REG) (const_int 0)]))]
11366 [(set_attr "type" "setcc")
11367 (set_attr "mode" "QI")])
11369 ;; In general it is not safe to assume too much about CCmode registers,
11370 ;; so simplify-rtx stops when it sees a second one. Under certain
11371 ;; conditions this is safe on x86, so help combine not create
11378 [(set (match_operand:QI 0 "nonimmediate_operand")
11379 (ne:QI (match_operator 1 "ix86_comparison_operator"
11380 [(reg FLAGS_REG) (const_int 0)])
11383 [(set (match_dup 0) (match_dup 1))]
11385 operands[1] = shallow_copy_rtx (operands[1]);
11386 PUT_MODE (operands[1], QImode);
11390 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11391 (ne:QI (match_operator 1 "ix86_comparison_operator"
11392 [(reg FLAGS_REG) (const_int 0)])
11395 [(set (match_dup 0) (match_dup 1))]
11397 operands[1] = shallow_copy_rtx (operands[1]);
11398 PUT_MODE (operands[1], QImode);
11402 [(set (match_operand:QI 0 "nonimmediate_operand")
11403 (eq:QI (match_operator 1 "ix86_comparison_operator"
11404 [(reg FLAGS_REG) (const_int 0)])
11407 [(set (match_dup 0) (match_dup 1))]
11409 operands[1] = shallow_copy_rtx (operands[1]);
11410 PUT_MODE (operands[1], QImode);
11411 PUT_CODE (operands[1],
11412 ix86_reverse_condition (GET_CODE (operands[1]),
11413 GET_MODE (XEXP (operands[1], 0))));
11415 /* Make sure that (a) the CCmode we have for the flags is strong
11416 enough for the reversed compare or (b) we have a valid FP compare. */
11417 if (! ix86_comparison_operator (operands[1], VOIDmode))
11422 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11423 (eq:QI (match_operator 1 "ix86_comparison_operator"
11424 [(reg FLAGS_REG) (const_int 0)])
11427 [(set (match_dup 0) (match_dup 1))]
11429 operands[1] = shallow_copy_rtx (operands[1]);
11430 PUT_MODE (operands[1], QImode);
11431 PUT_CODE (operands[1],
11432 ix86_reverse_condition (GET_CODE (operands[1]),
11433 GET_MODE (XEXP (operands[1], 0))));
11435 /* Make sure that (a) the CCmode we have for the flags is strong
11436 enough for the reversed compare or (b) we have a valid FP compare. */
11437 if (! ix86_comparison_operator (operands[1], VOIDmode))
11441 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
11442 ;; subsequent logical operations are used to imitate conditional moves.
11443 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
11446 (define_insn "setcc_<mode>_sse"
11447 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
11448 (match_operator:MODEF 3 "sse_comparison_operator"
11449 [(match_operand:MODEF 1 "register_operand" "0,x")
11450 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
11451 "SSE_FLOAT_MODE_P (<MODE>mode)"
11453 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
11454 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
11455 [(set_attr "isa" "noavx,avx")
11456 (set_attr "type" "ssecmp")
11457 (set_attr "length_immediate" "1")
11458 (set_attr "prefix" "orig,vex")
11459 (set_attr "mode" "<MODE>")])
11461 ;; Basic conditional jump instructions.
11462 ;; We ignore the overflow flag for signed branch instructions.
11464 (define_insn "*jcc_1"
11466 (if_then_else (match_operator 1 "ix86_comparison_operator"
11467 [(reg FLAGS_REG) (const_int 0)])
11468 (label_ref (match_operand 0))
11472 [(set_attr "type" "ibr")
11473 (set_attr "modrm" "0")
11474 (set (attr "length")
11476 (and (ge (minus (match_dup 0) (pc))
11478 (lt (minus (match_dup 0) (pc))
11482 (set_attr "maybe_prefix_bnd" "1")])
11484 (define_insn "*jcc_2"
11486 (if_then_else (match_operator 1 "ix86_comparison_operator"
11487 [(reg FLAGS_REG) (const_int 0)])
11489 (label_ref (match_operand 0))))]
11492 [(set_attr "type" "ibr")
11493 (set_attr "modrm" "0")
11494 (set (attr "length")
11496 (and (ge (minus (match_dup 0) (pc))
11498 (lt (minus (match_dup 0) (pc))
11502 (set_attr "maybe_prefix_bnd" "1")])
11504 ;; In general it is not safe to assume too much about CCmode registers,
11505 ;; so simplify-rtx stops when it sees a second one. Under certain
11506 ;; conditions this is safe on x86, so help combine not create
11514 (if_then_else (ne (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);
11531 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11532 [(reg FLAGS_REG) (const_int 0)])
11534 (label_ref (match_operand 1))
11538 (if_then_else (match_dup 0)
11539 (label_ref (match_dup 1))
11542 operands[0] = shallow_copy_rtx (operands[0]);
11543 PUT_MODE (operands[0], VOIDmode);
11544 PUT_CODE (operands[0],
11545 ix86_reverse_condition (GET_CODE (operands[0]),
11546 GET_MODE (XEXP (operands[0], 0))));
11548 /* Make sure that (a) the CCmode we have for the flags is strong
11549 enough for the reversed compare or (b) we have a valid FP compare. */
11550 if (! ix86_comparison_operator (operands[0], VOIDmode))
11554 ;; Define combination compare-and-branch fp compare instructions to help
11557 (define_insn "*jcc<mode>_0_i387"
11559 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11560 [(match_operand:X87MODEF 1 "register_operand" "f")
11561 (match_operand:X87MODEF 2 "const0_operand")])
11562 (label_ref (match_operand 3))
11564 (clobber (reg:CCFP FPSR_REG))
11565 (clobber (reg:CCFP FLAGS_REG))
11566 (clobber (match_scratch:HI 4 "=a"))]
11567 "TARGET_80387 && !TARGET_CMOVE"
11570 (define_insn "*jcc<mode>_0_r_i387"
11572 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11573 [(match_operand:X87MODEF 1 "register_operand" "f")
11574 (match_operand:X87MODEF 2 "const0_operand")])
11576 (label_ref (match_operand 3))))
11577 (clobber (reg:CCFP FPSR_REG))
11578 (clobber (reg:CCFP FLAGS_REG))
11579 (clobber (match_scratch:HI 4 "=a"))]
11580 "TARGET_80387 && !TARGET_CMOVE"
11583 (define_insn "*jccxf_i387"
11585 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11586 [(match_operand:XF 1 "register_operand" "f")
11587 (match_operand:XF 2 "register_operand" "f")])
11588 (label_ref (match_operand 3))
11590 (clobber (reg:CCFP FPSR_REG))
11591 (clobber (reg:CCFP FLAGS_REG))
11592 (clobber (match_scratch:HI 4 "=a"))]
11593 "TARGET_80387 && !TARGET_CMOVE"
11596 (define_insn "*jccxf_r_i387"
11598 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11599 [(match_operand:XF 1 "register_operand" "f")
11600 (match_operand:XF 2 "register_operand" "f")])
11602 (label_ref (match_operand 3))))
11603 (clobber (reg:CCFP FPSR_REG))
11604 (clobber (reg:CCFP FLAGS_REG))
11605 (clobber (match_scratch:HI 4 "=a"))]
11606 "TARGET_80387 && !TARGET_CMOVE"
11609 (define_insn "*jcc<mode>_i387"
11611 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11612 [(match_operand:MODEF 1 "register_operand" "f")
11613 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11614 (label_ref (match_operand 3))
11616 (clobber (reg:CCFP FPSR_REG))
11617 (clobber (reg:CCFP FLAGS_REG))
11618 (clobber (match_scratch:HI 4 "=a"))]
11619 "TARGET_80387 && !TARGET_CMOVE"
11622 (define_insn "*jcc<mode>_r_i387"
11624 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11625 [(match_operand:MODEF 1 "register_operand" "f")
11626 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11628 (label_ref (match_operand 3))))
11629 (clobber (reg:CCFP FPSR_REG))
11630 (clobber (reg:CCFP FLAGS_REG))
11631 (clobber (match_scratch:HI 4 "=a"))]
11632 "TARGET_80387 && !TARGET_CMOVE"
11635 (define_insn "*jccu<mode>_i387"
11637 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11638 [(match_operand:X87MODEF 1 "register_operand" "f")
11639 (match_operand:X87MODEF 2 "register_operand" "f")])
11640 (label_ref (match_operand 3))
11642 (clobber (reg:CCFP FPSR_REG))
11643 (clobber (reg:CCFP FLAGS_REG))
11644 (clobber (match_scratch:HI 4 "=a"))]
11645 "TARGET_80387 && !TARGET_CMOVE"
11648 (define_insn "*jccu<mode>_r_i387"
11650 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11651 [(match_operand:X87MODEF 1 "register_operand" "f")
11652 (match_operand:X87MODEF 2 "register_operand" "f")])
11654 (label_ref (match_operand 3))))
11655 (clobber (reg:CCFP FPSR_REG))
11656 (clobber (reg:CCFP FLAGS_REG))
11657 (clobber (match_scratch:HI 4 "=a"))]
11658 "TARGET_80387 && !TARGET_CMOVE"
11663 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11664 [(match_operand:X87MODEF 1 "register_operand")
11665 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11667 (match_operand 4)))
11668 (clobber (reg:CCFP FPSR_REG))
11669 (clobber (reg:CCFP FLAGS_REG))]
11670 "TARGET_80387 && !TARGET_CMOVE
11671 && reload_completed"
11674 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11675 operands[3], operands[4], NULL_RTX);
11681 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11682 [(match_operand:X87MODEF 1 "register_operand")
11683 (match_operand:X87MODEF 2 "general_operand")])
11685 (match_operand 4)))
11686 (clobber (reg:CCFP FPSR_REG))
11687 (clobber (reg:CCFP FLAGS_REG))
11688 (clobber (match_scratch:HI 5))]
11689 "TARGET_80387 && !TARGET_CMOVE
11690 && reload_completed"
11693 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11694 operands[3], operands[4], operands[5]);
11698 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11699 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11700 ;; with a precedence over other operators and is always put in the first
11701 ;; place. Swap condition and operands to match ficom instruction.
11703 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_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")])
11710 (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))"
11720 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11723 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11724 [(match_operator:X87MODEF 1 "float_operator"
11725 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11726 (match_operand:X87MODEF 3 "register_operand" "f")])
11728 (label_ref (match_operand 4))))
11729 (clobber (reg:CCFP FPSR_REG))
11730 (clobber (reg:CCFP FLAGS_REG))
11731 (clobber (match_scratch:HI 5 "=a"))]
11732 "TARGET_80387 && !TARGET_CMOVE
11733 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11734 || optimize_function_for_size_p (cfun))"
11740 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11741 [(match_operator:X87MODEF 1 "float_operator"
11742 [(match_operand:SWI24 2 "memory_operand")])
11743 (match_operand:X87MODEF 3 "register_operand")])
11745 (match_operand 5)))
11746 (clobber (reg:CCFP FPSR_REG))
11747 (clobber (reg:CCFP FLAGS_REG))
11748 (clobber (match_scratch:HI 6))]
11749 "TARGET_80387 && !TARGET_CMOVE
11750 && reload_completed"
11753 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11754 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11755 operands[4], operands[5], operands[6]);
11759 ;; Unconditional and other jump instructions
11761 (define_insn "jump"
11763 (label_ref (match_operand 0)))]
11766 [(set_attr "type" "ibr")
11767 (set_attr "modrm" "0")
11768 (set (attr "length")
11770 (and (ge (minus (match_dup 0) (pc))
11772 (lt (minus (match_dup 0) (pc))
11776 (set_attr "maybe_prefix_bnd" "1")])
11778 (define_expand "indirect_jump"
11779 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11783 operands[0] = convert_memory_address (word_mode, operands[0]);
11786 (define_insn "*indirect_jump"
11787 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11790 [(set_attr "type" "ibr")
11791 (set_attr "length_immediate" "0")
11792 (set_attr "maybe_prefix_bnd" "1")])
11794 (define_expand "tablejump"
11795 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11796 (use (label_ref (match_operand 1)))])]
11799 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11800 relative. Convert the relative address to an absolute address. */
11804 enum rtx_code code;
11806 /* We can't use @GOTOFF for text labels on VxWorks;
11807 see gotoff_operand. */
11808 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11812 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11814 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11818 op1 = pic_offset_table_rtx;
11823 op0 = pic_offset_table_rtx;
11827 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11832 operands[0] = convert_memory_address (word_mode, operands[0]);
11835 (define_insn "*tablejump_1"
11836 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11837 (use (label_ref (match_operand 1)))]
11840 [(set_attr "type" "ibr")
11841 (set_attr "length_immediate" "0")
11842 (set_attr "maybe_prefix_bnd" "1")])
11844 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11847 [(set (reg FLAGS_REG) (match_operand 0))
11848 (set (match_operand:QI 1 "register_operand")
11849 (match_operator:QI 2 "ix86_comparison_operator"
11850 [(reg FLAGS_REG) (const_int 0)]))
11851 (set (match_operand 3 "any_QIreg_operand")
11852 (zero_extend (match_dup 1)))]
11853 "(peep2_reg_dead_p (3, operands[1])
11854 || operands_match_p (operands[1], operands[3]))
11855 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11856 [(set (match_dup 4) (match_dup 0))
11857 (set (strict_low_part (match_dup 5))
11860 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11861 operands[5] = gen_lowpart (QImode, operands[3]);
11862 ix86_expand_clear (operands[3]);
11866 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11867 (match_operand 4)])
11868 (set (match_operand:QI 1 "register_operand")
11869 (match_operator:QI 2 "ix86_comparison_operator"
11870 [(reg FLAGS_REG) (const_int 0)]))
11871 (set (match_operand 3 "any_QIreg_operand")
11872 (zero_extend (match_dup 1)))]
11873 "(peep2_reg_dead_p (3, operands[1])
11874 || operands_match_p (operands[1], operands[3]))
11875 && ! reg_overlap_mentioned_p (operands[3], operands[0])
11876 && ! reg_set_p (operands[3], operands[4])"
11877 [(parallel [(set (match_dup 5) (match_dup 0))
11879 (set (strict_low_part (match_dup 6))
11882 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11883 operands[6] = gen_lowpart (QImode, operands[3]);
11884 ix86_expand_clear (operands[3]);
11887 ;; Similar, but match zero extend with andsi3.
11890 [(set (reg FLAGS_REG) (match_operand 0))
11891 (set (match_operand:QI 1 "register_operand")
11892 (match_operator:QI 2 "ix86_comparison_operator"
11893 [(reg FLAGS_REG) (const_int 0)]))
11894 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
11895 (and:SI (match_dup 3) (const_int 255)))
11896 (clobber (reg:CC FLAGS_REG))])]
11897 "REGNO (operands[1]) == REGNO (operands[3])
11898 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11899 [(set (match_dup 4) (match_dup 0))
11900 (set (strict_low_part (match_dup 5))
11903 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11904 operands[5] = gen_lowpart (QImode, operands[3]);
11905 ix86_expand_clear (operands[3]);
11909 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11910 (match_operand 4)])
11911 (set (match_operand:QI 1 "register_operand")
11912 (match_operator:QI 2 "ix86_comparison_operator"
11913 [(reg FLAGS_REG) (const_int 0)]))
11914 (parallel [(set (match_operand 3 "any_QIreg_operand")
11915 (zero_extend (match_dup 1)))
11916 (clobber (reg:CC FLAGS_REG))])]
11917 "(peep2_reg_dead_p (3, operands[1])
11918 || operands_match_p (operands[1], operands[3]))
11919 && ! reg_overlap_mentioned_p (operands[3], operands[0])
11920 && ! reg_set_p (operands[3], operands[4])"
11921 [(parallel [(set (match_dup 5) (match_dup 0))
11923 (set (strict_low_part (match_dup 6))
11926 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11927 operands[6] = gen_lowpart (QImode, operands[3]);
11928 ix86_expand_clear (operands[3]);
11931 ;; Call instructions.
11933 ;; The predicates normally associated with named expanders are not properly
11934 ;; checked for calls. This is a bug in the generic code, but it isn't that
11935 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11937 ;; P6 processors will jump to the address after the decrement when %esp
11938 ;; is used as a call operand, so they will execute return address as a code.
11939 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11941 ;; Register constraint for call instruction.
11942 (define_mode_attr c [(SI "l") (DI "r")])
11944 ;; Call subroutine returning no value.
11946 (define_expand "call"
11947 [(call (match_operand:QI 0)
11949 (use (match_operand 2))]
11952 ix86_expand_call (NULL, operands[0], operands[1],
11953 operands[2], NULL, false);
11957 (define_expand "sibcall"
11958 [(call (match_operand:QI 0)
11960 (use (match_operand 2))]
11963 ix86_expand_call (NULL, operands[0], operands[1],
11964 operands[2], NULL, true);
11968 (define_insn "*call"
11969 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11970 (match_operand 1))]
11971 "!SIBLING_CALL_P (insn)"
11972 "* return ix86_output_call_insn (insn, operands[0]);"
11973 [(set_attr "type" "call")])
11975 ;; This covers both call and sibcall since only GOT slot is allowed.
11976 (define_insn "*call_got_x32"
11977 [(call (mem:QI (zero_extend:DI
11978 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
11979 (match_operand 1))]
11981 "* return ix86_output_call_insn (insn, operands[0]);"
11982 [(set_attr "type" "call")])
11984 ;; Since sibcall never returns, we can only use call-clobbered register
11986 (define_insn "*sibcall_GOT_32"
11989 (match_operand:SI 0 "register_no_elim_operand" "U")
11990 (match_operand:SI 1 "GOT32_symbol_operand"))))
11991 (match_operand 2))]
11992 "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11994 rtx fnaddr = gen_rtx_PLUS (Pmode, operands[0], operands[1]);
11995 fnaddr = gen_const_mem (Pmode, fnaddr);
11996 return ix86_output_call_insn (insn, fnaddr);
11998 [(set_attr "type" "call")])
12000 (define_insn "*sibcall"
12001 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
12002 (match_operand 1))]
12003 "SIBLING_CALL_P (insn)"
12004 "* return ix86_output_call_insn (insn, operands[0]);"
12005 [(set_attr "type" "call")])
12007 (define_insn "*sibcall_memory"
12008 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
12010 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12012 "* return ix86_output_call_insn (insn, operands[0]);"
12013 [(set_attr "type" "call")])
12016 [(set (match_operand:W 0 "register_operand")
12017 (match_operand:W 1 "memory_operand"))
12018 (call (mem:QI (match_dup 0))
12019 (match_operand 3))]
12020 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
12021 && !reg_mentioned_p (operands[0],
12022 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12023 [(parallel [(call (mem:QI (match_dup 1))
12025 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12028 [(set (match_operand:W 0 "register_operand")
12029 (match_operand:W 1 "memory_operand"))
12030 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12031 (call (mem:QI (match_dup 0))
12032 (match_operand 3))]
12033 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
12034 && !reg_mentioned_p (operands[0],
12035 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12036 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12037 (parallel [(call (mem:QI (match_dup 1))
12039 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12041 (define_expand "call_pop"
12042 [(parallel [(call (match_operand:QI 0)
12043 (match_operand:SI 1))
12044 (set (reg:SI SP_REG)
12045 (plus:SI (reg:SI SP_REG)
12046 (match_operand:SI 3)))])]
12049 ix86_expand_call (NULL, operands[0], operands[1],
12050 operands[2], operands[3], false);
12054 (define_insn "*call_pop"
12055 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
12057 (set (reg:SI SP_REG)
12058 (plus:SI (reg:SI SP_REG)
12059 (match_operand:SI 2 "immediate_operand" "i")))]
12060 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12061 "* return ix86_output_call_insn (insn, operands[0]);"
12062 [(set_attr "type" "call")])
12064 (define_insn "*sibcall_pop"
12065 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
12067 (set (reg:SI SP_REG)
12068 (plus:SI (reg:SI SP_REG)
12069 (match_operand:SI 2 "immediate_operand" "i")))]
12070 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12071 "* return ix86_output_call_insn (insn, operands[0]);"
12072 [(set_attr "type" "call")])
12074 (define_insn "*sibcall_pop_memory"
12075 [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
12077 (set (reg:SI SP_REG)
12078 (plus:SI (reg:SI SP_REG)
12079 (match_operand:SI 2 "immediate_operand" "i")))
12080 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12082 "* return ix86_output_call_insn (insn, operands[0]);"
12083 [(set_attr "type" "call")])
12086 [(set (match_operand:SI 0 "register_operand")
12087 (match_operand:SI 1 "memory_operand"))
12088 (parallel [(call (mem:QI (match_dup 0))
12090 (set (reg:SI SP_REG)
12091 (plus:SI (reg:SI SP_REG)
12092 (match_operand:SI 4 "immediate_operand")))])]
12093 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12094 && !reg_mentioned_p (operands[0],
12095 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12096 [(parallel [(call (mem:QI (match_dup 1))
12098 (set (reg:SI SP_REG)
12099 (plus:SI (reg:SI SP_REG)
12101 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12104 [(set (match_operand:SI 0 "register_operand")
12105 (match_operand:SI 1 "memory_operand"))
12106 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12107 (parallel [(call (mem:QI (match_dup 0))
12109 (set (reg:SI SP_REG)
12110 (plus:SI (reg:SI SP_REG)
12111 (match_operand:SI 4 "immediate_operand")))])]
12112 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12113 && !reg_mentioned_p (operands[0],
12114 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12115 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12116 (parallel [(call (mem:QI (match_dup 1))
12118 (set (reg:SI SP_REG)
12119 (plus:SI (reg:SI SP_REG)
12121 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12123 ;; Combining simple memory jump instruction
12126 [(set (match_operand:W 0 "register_operand")
12127 (match_operand:W 1 "memory_operand"))
12128 (set (pc) (match_dup 0))]
12129 "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
12130 [(set (pc) (match_dup 1))])
12132 ;; Call subroutine, returning value in operand 0
12134 (define_expand "call_value"
12135 [(set (match_operand 0)
12136 (call (match_operand:QI 1)
12137 (match_operand 2)))
12138 (use (match_operand 3))]
12141 ix86_expand_call (operands[0], operands[1], operands[2],
12142 operands[3], NULL, false);
12146 (define_expand "sibcall_value"
12147 [(set (match_operand 0)
12148 (call (match_operand:QI 1)
12149 (match_operand 2)))
12150 (use (match_operand 3))]
12153 ix86_expand_call (operands[0], operands[1], operands[2],
12154 operands[3], NULL, true);
12158 (define_insn "*call_value"
12159 [(set (match_operand 0)
12160 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
12161 (match_operand 2)))]
12162 "!SIBLING_CALL_P (insn)"
12163 "* return ix86_output_call_insn (insn, operands[1]);"
12164 [(set_attr "type" "callv")])
12166 ;; This covers both call and sibcall since only GOT slot is allowed.
12167 (define_insn "*call_value_got_x32"
12168 [(set (match_operand 0)
12171 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
12172 (match_operand 2)))]
12174 "* return ix86_output_call_insn (insn, operands[1]);"
12175 [(set_attr "type" "callv")])
12177 ;; Since sibcall never returns, we can only use call-clobbered register
12179 (define_insn "*sibcall_value_GOT_32"
12180 [(set (match_operand 0)
12183 (match_operand:SI 1 "register_no_elim_operand" "U")
12184 (match_operand:SI 2 "GOT32_symbol_operand"))))
12185 (match_operand 3)))]
12186 "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
12188 rtx fnaddr = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
12189 fnaddr = gen_const_mem (Pmode, fnaddr);
12190 return ix86_output_call_insn (insn, fnaddr);
12192 [(set_attr "type" "callv")])
12194 (define_insn "*sibcall_value"
12195 [(set (match_operand 0)
12196 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
12197 (match_operand 2)))]
12198 "SIBLING_CALL_P (insn)"
12199 "* return ix86_output_call_insn (insn, operands[1]);"
12200 [(set_attr "type" "callv")])
12202 (define_insn "*sibcall_value_memory"
12203 [(set (match_operand 0)
12204 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
12205 (match_operand 2)))
12206 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12208 "* return ix86_output_call_insn (insn, operands[1]);"
12209 [(set_attr "type" "callv")])
12212 [(set (match_operand:W 0 "register_operand")
12213 (match_operand:W 1 "memory_operand"))
12214 (set (match_operand 2)
12215 (call (mem:QI (match_dup 0))
12216 (match_operand 3)))]
12217 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
12218 && !reg_mentioned_p (operands[0],
12219 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12220 [(parallel [(set (match_dup 2)
12221 (call (mem:QI (match_dup 1))
12223 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12226 [(set (match_operand:W 0 "register_operand")
12227 (match_operand:W 1 "memory_operand"))
12228 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12229 (set (match_operand 2)
12230 (call (mem:QI (match_dup 0))
12231 (match_operand 3)))]
12232 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
12233 && !reg_mentioned_p (operands[0],
12234 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12235 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12236 (parallel [(set (match_dup 2)
12237 (call (mem:QI (match_dup 1))
12239 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12241 (define_expand "call_value_pop"
12242 [(parallel [(set (match_operand 0)
12243 (call (match_operand:QI 1)
12244 (match_operand:SI 2)))
12245 (set (reg:SI SP_REG)
12246 (plus:SI (reg:SI SP_REG)
12247 (match_operand:SI 4)))])]
12250 ix86_expand_call (operands[0], operands[1], operands[2],
12251 operands[3], operands[4], false);
12255 (define_insn "*call_value_pop"
12256 [(set (match_operand 0)
12257 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
12258 (match_operand 2)))
12259 (set (reg:SI SP_REG)
12260 (plus:SI (reg:SI SP_REG)
12261 (match_operand:SI 3 "immediate_operand" "i")))]
12262 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12263 "* return ix86_output_call_insn (insn, operands[1]);"
12264 [(set_attr "type" "callv")])
12266 (define_insn "*sibcall_value_pop"
12267 [(set (match_operand 0)
12268 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
12269 (match_operand 2)))
12270 (set (reg:SI SP_REG)
12271 (plus:SI (reg:SI SP_REG)
12272 (match_operand:SI 3 "immediate_operand" "i")))]
12273 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12274 "* return ix86_output_call_insn (insn, operands[1]);"
12275 [(set_attr "type" "callv")])
12277 (define_insn "*sibcall_value_pop_memory"
12278 [(set (match_operand 0)
12279 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
12280 (match_operand 2)))
12281 (set (reg:SI SP_REG)
12282 (plus:SI (reg:SI SP_REG)
12283 (match_operand:SI 3 "immediate_operand" "i")))
12284 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12286 "* return ix86_output_call_insn (insn, operands[1]);"
12287 [(set_attr "type" "callv")])
12290 [(set (match_operand:SI 0 "register_operand")
12291 (match_operand:SI 1 "memory_operand"))
12292 (parallel [(set (match_operand 2)
12293 (call (mem:QI (match_dup 0))
12294 (match_operand 3)))
12295 (set (reg:SI SP_REG)
12296 (plus:SI (reg:SI SP_REG)
12297 (match_operand:SI 4 "immediate_operand")))])]
12298 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12299 && !reg_mentioned_p (operands[0],
12300 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12301 [(parallel [(set (match_dup 2)
12302 (call (mem:QI (match_dup 1))
12304 (set (reg:SI SP_REG)
12305 (plus:SI (reg:SI SP_REG)
12307 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12310 [(set (match_operand:SI 0 "register_operand")
12311 (match_operand:SI 1 "memory_operand"))
12312 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12313 (parallel [(set (match_operand 2)
12314 (call (mem:QI (match_dup 0))
12315 (match_operand 3)))
12316 (set (reg:SI SP_REG)
12317 (plus:SI (reg:SI SP_REG)
12318 (match_operand:SI 4 "immediate_operand")))])]
12319 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12320 && !reg_mentioned_p (operands[0],
12321 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12322 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12323 (parallel [(set (match_dup 2)
12324 (call (mem:QI (match_dup 1))
12326 (set (reg:SI SP_REG)
12327 (plus:SI (reg:SI SP_REG)
12329 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12331 ;; Call subroutine returning any type.
12333 (define_expand "untyped_call"
12334 [(parallel [(call (match_operand 0)
12337 (match_operand 2)])]
12342 /* In order to give reg-stack an easier job in validating two
12343 coprocessor registers as containing a possible return value,
12344 simply pretend the untyped call returns a complex long double
12347 We can't use SSE_REGPARM_MAX here since callee is unprototyped
12348 and should have the default ABI. */
12350 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12351 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12352 operands[0], const0_rtx,
12353 GEN_INT ((TARGET_64BIT
12354 ? (ix86_abi == SYSV_ABI
12355 ? X86_64_SSE_REGPARM_MAX
12356 : X86_64_MS_SSE_REGPARM_MAX)
12357 : X86_32_SSE_REGPARM_MAX)
12361 for (i = 0; i < XVECLEN (operands[2], 0); i++)
12363 rtx set = XVECEXP (operands[2], 0, i);
12364 emit_move_insn (SET_DEST (set), SET_SRC (set));
12367 /* The optimizer does not know that the call sets the function value
12368 registers we stored in the result block. We avoid problems by
12369 claiming that all hard registers are used and clobbered at this
12371 emit_insn (gen_blockage ());
12376 ;; Prologue and epilogue instructions
12378 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12379 ;; all of memory. This blocks insns from being moved across this point.
12381 (define_insn "blockage"
12382 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12385 [(set_attr "length" "0")])
12387 ;; Do not schedule instructions accessing memory across this point.
12389 (define_expand "memory_blockage"
12390 [(set (match_dup 0)
12391 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12394 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12395 MEM_VOLATILE_P (operands[0]) = 1;
12398 (define_insn "*memory_blockage"
12399 [(set (match_operand:BLK 0)
12400 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12403 [(set_attr "length" "0")])
12405 ;; As USE insns aren't meaningful after reload, this is used instead
12406 ;; to prevent deleting instructions setting registers for PIC code
12407 (define_insn "prologue_use"
12408 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12411 [(set_attr "length" "0")])
12413 ;; Insn emitted into the body of a function to return from a function.
12414 ;; This is only done if the function's epilogue is known to be simple.
12415 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12417 (define_expand "return"
12419 "ix86_can_use_return_insn_p ()"
12421 if (crtl->args.pops_args)
12423 rtx popc = GEN_INT (crtl->args.pops_args);
12424 emit_jump_insn (gen_simple_return_pop_internal (popc));
12429 ;; We need to disable this for TARGET_SEH, as otherwise
12430 ;; shrink-wrapped prologue gets enabled too. This might exceed
12431 ;; the maximum size of prologue in unwind information.
12432 ;; Also disallow shrink-wrapping if using stack slot to pass the
12433 ;; static chain pointer - the first instruction has to be pushl %esi
12434 ;; and it can't be moved around, as we use alternate entry points
12437 (define_expand "simple_return"
12439 "!TARGET_SEH && !ix86_static_chain_on_stack"
12441 if (crtl->args.pops_args)
12443 rtx popc = GEN_INT (crtl->args.pops_args);
12444 emit_jump_insn (gen_simple_return_pop_internal (popc));
12449 (define_insn "simple_return_internal"
12453 [(set_attr "length" "1")
12454 (set_attr "atom_unit" "jeu")
12455 (set_attr "length_immediate" "0")
12456 (set_attr "modrm" "0")
12457 (set_attr "maybe_prefix_bnd" "1")])
12459 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12460 ;; instruction Athlon and K8 have.
12462 (define_insn "simple_return_internal_long"
12464 (unspec [(const_int 0)] UNSPEC_REP)]
12467 if (ix86_bnd_prefixed_insn_p (insn))
12470 return "rep%; ret";
12472 [(set_attr "length" "2")
12473 (set_attr "atom_unit" "jeu")
12474 (set_attr "length_immediate" "0")
12475 (set_attr "prefix_rep" "1")
12476 (set_attr "modrm" "0")])
12478 (define_insn "simple_return_pop_internal"
12480 (use (match_operand:SI 0 "const_int_operand"))]
12483 [(set_attr "length" "3")
12484 (set_attr "atom_unit" "jeu")
12485 (set_attr "length_immediate" "2")
12486 (set_attr "modrm" "0")
12487 (set_attr "maybe_prefix_bnd" "1")])
12489 (define_insn "simple_return_indirect_internal"
12491 (use (match_operand:SI 0 "register_operand" "r"))]
12494 [(set_attr "type" "ibr")
12495 (set_attr "length_immediate" "0")
12496 (set_attr "maybe_prefix_bnd" "1")])
12502 [(set_attr "length" "1")
12503 (set_attr "length_immediate" "0")
12504 (set_attr "modrm" "0")])
12506 ;; Generate nops. Operand 0 is the number of nops, up to 8.
12507 (define_insn "nops"
12508 [(unspec_volatile [(match_operand 0 "const_int_operand")]
12512 int num = INTVAL (operands[0]);
12514 gcc_assert (IN_RANGE (num, 1, 8));
12517 fputs ("\tnop\n", asm_out_file);
12521 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12522 (set_attr "length_immediate" "0")
12523 (set_attr "modrm" "0")])
12525 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12526 ;; branch prediction penalty for the third jump in a 16-byte
12530 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12533 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12534 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12536 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12537 The align insn is used to avoid 3 jump instructions in the row to improve
12538 branch prediction and the benefits hardly outweigh the cost of extra 8
12539 nops on the average inserted by full alignment pseudo operation. */
12543 [(set_attr "length" "16")])
12545 (define_expand "prologue"
12548 "ix86_expand_prologue (); DONE;")
12550 (define_expand "set_got"
12552 [(set (match_operand:SI 0 "register_operand" "=r")
12553 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12554 (clobber (reg:CC FLAGS_REG))])]
12557 if (flag_pic && !TARGET_VXWORKS_RTP)
12558 ix86_pc_thunk_call_expanded = true;
12561 (define_insn "*set_got"
12562 [(set (match_operand:SI 0 "register_operand" "=r")
12563 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12564 (clobber (reg:CC FLAGS_REG))]
12566 "* return output_set_got (operands[0], NULL_RTX);"
12567 [(set_attr "type" "multi")
12568 (set_attr "length" "12")])
12570 (define_expand "set_got_labelled"
12572 [(set (match_operand:SI 0 "register_operand" "=r")
12573 (unspec:SI [(label_ref (match_operand 1))]
12575 (clobber (reg:CC FLAGS_REG))])]
12578 if (flag_pic && !TARGET_VXWORKS_RTP)
12579 ix86_pc_thunk_call_expanded = true;
12582 (define_insn "*set_got_labelled"
12583 [(set (match_operand:SI 0 "register_operand" "=r")
12584 (unspec:SI [(label_ref (match_operand 1))]
12586 (clobber (reg:CC FLAGS_REG))]
12588 "* return output_set_got (operands[0], operands[1]);"
12589 [(set_attr "type" "multi")
12590 (set_attr "length" "12")])
12592 (define_insn "set_got_rex64"
12593 [(set (match_operand:DI 0 "register_operand" "=r")
12594 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12596 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12597 [(set_attr "type" "lea")
12598 (set_attr "length_address" "4")
12599 (set_attr "modrm_class" "unknown")
12600 (set_attr "mode" "DI")])
12602 (define_insn "set_rip_rex64"
12603 [(set (match_operand:DI 0 "register_operand" "=r")
12604 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12606 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12607 [(set_attr "type" "lea")
12608 (set_attr "length_address" "4")
12609 (set_attr "mode" "DI")])
12611 (define_insn "set_got_offset_rex64"
12612 [(set (match_operand:DI 0 "register_operand" "=r")
12614 [(label_ref (match_operand 1))]
12615 UNSPEC_SET_GOT_OFFSET))]
12617 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12618 [(set_attr "type" "imov")
12619 (set_attr "length_immediate" "0")
12620 (set_attr "length_address" "8")
12621 (set_attr "mode" "DI")])
12623 (define_expand "epilogue"
12626 "ix86_expand_epilogue (1); DONE;")
12628 (define_expand "sibcall_epilogue"
12631 "ix86_expand_epilogue (0); DONE;")
12633 (define_expand "eh_return"
12634 [(use (match_operand 0 "register_operand"))]
12637 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12639 /* Tricky bit: we write the address of the handler to which we will
12640 be returning into someone else's stack frame, one word below the
12641 stack address we wish to restore. */
12642 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12643 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12644 tmp = gen_rtx_MEM (Pmode, tmp);
12645 emit_move_insn (tmp, ra);
12647 emit_jump_insn (gen_eh_return_internal ());
12652 (define_insn_and_split "eh_return_internal"
12656 "epilogue_completed"
12658 "ix86_expand_epilogue (2); DONE;")
12660 (define_insn "leave"
12661 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12662 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12663 (clobber (mem:BLK (scratch)))]
12666 [(set_attr "type" "leave")])
12668 (define_insn "leave_rex64"
12669 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12670 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12671 (clobber (mem:BLK (scratch)))]
12674 [(set_attr "type" "leave")])
12676 ;; Handle -fsplit-stack.
12678 (define_expand "split_stack_prologue"
12682 ix86_expand_split_stack_prologue ();
12686 ;; In order to support the call/return predictor, we use a return
12687 ;; instruction which the middle-end doesn't see.
12688 (define_insn "split_stack_return"
12689 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12690 UNSPECV_SPLIT_STACK_RETURN)]
12693 if (operands[0] == const0_rtx)
12698 [(set_attr "atom_unit" "jeu")
12699 (set_attr "modrm" "0")
12700 (set (attr "length")
12701 (if_then_else (match_operand:SI 0 "const0_operand")
12704 (set (attr "length_immediate")
12705 (if_then_else (match_operand:SI 0 "const0_operand")
12709 ;; If there are operand 0 bytes available on the stack, jump to
12712 (define_expand "split_stack_space_check"
12713 [(set (pc) (if_then_else
12714 (ltu (minus (reg SP_REG)
12715 (match_operand 0 "register_operand"))
12716 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12717 (label_ref (match_operand 1))
12721 rtx reg, size, limit;
12723 reg = gen_reg_rtx (Pmode);
12724 size = force_reg (Pmode, operands[0]);
12725 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12726 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12727 UNSPEC_STACK_CHECK);
12728 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12729 ix86_expand_branch (GEU, reg, limit, operands[1]);
12734 ;; Bit manipulation instructions.
12736 (define_expand "ffs<mode>2"
12737 [(set (match_dup 2) (const_int -1))
12738 (parallel [(set (match_dup 3) (match_dup 4))
12739 (set (match_operand:SWI48 0 "register_operand")
12741 (match_operand:SWI48 1 "nonimmediate_operand")))])
12742 (set (match_dup 0) (if_then_else:SWI48
12743 (eq (match_dup 3) (const_int 0))
12746 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12747 (clobber (reg:CC FLAGS_REG))])]
12750 machine_mode flags_mode;
12752 if (<MODE>mode == SImode && !TARGET_CMOVE)
12754 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12759 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12761 operands[2] = gen_reg_rtx (<MODE>mode);
12762 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12763 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12766 (define_insn_and_split "ffssi2_no_cmove"
12767 [(set (match_operand:SI 0 "register_operand" "=r")
12768 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12769 (clobber (match_scratch:SI 2 "=&q"))
12770 (clobber (reg:CC FLAGS_REG))]
12773 "&& reload_completed"
12774 [(parallel [(set (match_dup 4) (match_dup 5))
12775 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12776 (set (strict_low_part (match_dup 3))
12777 (eq:QI (match_dup 4) (const_int 0)))
12778 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12779 (clobber (reg:CC FLAGS_REG))])
12780 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12781 (clobber (reg:CC FLAGS_REG))])
12782 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12783 (clobber (reg:CC FLAGS_REG))])]
12785 machine_mode flags_mode
12786 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12788 operands[3] = gen_lowpart (QImode, operands[2]);
12789 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12790 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12792 ix86_expand_clear (operands[2]);
12795 (define_insn "*tzcnt<mode>_1"
12796 [(set (reg:CCC FLAGS_REG)
12797 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12799 (set (match_operand:SWI48 0 "register_operand" "=r")
12800 (ctz:SWI48 (match_dup 1)))]
12801 "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
12802 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12803 [(set_attr "type" "alu1")
12804 (set_attr "prefix_0f" "1")
12805 (set_attr "prefix_rep" "1")
12806 (set_attr "btver2_decode" "double")
12807 (set_attr "mode" "<MODE>")])
12809 (define_insn "*bsf<mode>_1"
12810 [(set (reg:CCZ FLAGS_REG)
12811 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12813 (set (match_operand:SWI48 0 "register_operand" "=r")
12814 (ctz:SWI48 (match_dup 1)))]
12816 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12817 [(set_attr "type" "alu1")
12818 (set_attr "prefix_0f" "1")
12819 (set_attr "btver2_decode" "double")
12820 (set_attr "znver1_decode" "vector")
12821 (set_attr "mode" "<MODE>")])
12823 (define_expand "ctz<mode>2"
12825 [(set (match_operand:SWI48 0 "register_operand")
12827 (match_operand:SWI48 1 "nonimmediate_operand")))
12828 (clobber (reg:CC FLAGS_REG))])])
12830 ; False dependency happens when destination is only updated by tzcnt,
12831 ; lzcnt or popcnt. There is no false dependency when destination is
12832 ; also used in source.
12833 (define_insn_and_split "*ctz<mode>2_falsedep_1"
12834 [(set (match_operand:SWI48 0 "register_operand" "=r")
12836 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12837 (clobber (reg:CC FLAGS_REG))]
12838 "(TARGET_BMI || TARGET_GENERIC)
12839 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12841 "&& reload_completed"
12843 [(set (match_dup 0)
12844 (ctz:SWI48 (match_dup 1)))
12845 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12846 (clobber (reg:CC FLAGS_REG))])]
12848 if (!reg_mentioned_p (operands[0], operands[1]))
12849 ix86_expand_clear (operands[0]);
12852 (define_insn "*ctz<mode>2_falsedep"
12853 [(set (match_operand:SWI48 0 "register_operand" "=r")
12855 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12856 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12857 UNSPEC_INSN_FALSE_DEP)
12858 (clobber (reg:CC FLAGS_REG))]
12862 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12863 else if (TARGET_GENERIC)
12864 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12865 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12867 gcc_unreachable ();
12869 [(set_attr "type" "alu1")
12870 (set_attr "prefix_0f" "1")
12871 (set_attr "prefix_rep" "1")
12872 (set_attr "mode" "<MODE>")])
12874 (define_insn "*ctz<mode>2"
12875 [(set (match_operand:SWI48 0 "register_operand" "=r")
12876 (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12877 (clobber (reg:CC FLAGS_REG))]
12881 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12882 else if (optimize_function_for_size_p (cfun))
12884 else if (TARGET_GENERIC)
12885 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12886 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12888 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12890 [(set_attr "type" "alu1")
12891 (set_attr "prefix_0f" "1")
12892 (set (attr "prefix_rep")
12894 (ior (match_test "TARGET_BMI")
12895 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12896 (match_test "TARGET_GENERIC")))
12898 (const_string "0")))
12899 (set_attr "mode" "<MODE>")])
12901 ;; Version of tzcnt that is expanded from intrinsics. This version provides
12902 ;; operand size as output when source operand is zero.
12904 (define_expand "bmi_tzcnt_<mode>"
12906 [(set (match_operand:SWI248 0 "register_operand")
12908 [(match_operand:SWI248 1 "nonimmediate_operand")]
12910 (clobber (reg:CC FLAGS_REG))])]
12913 ; False dependency happens when destination is only updated by tzcnt,
12914 ; lzcnt or popcnt. There is no false dependency when destination is
12915 ; also used in source.
12916 (define_insn_and_split "*bmi_tzcnt_<mode>_falsedep_1"
12917 [(set (match_operand:SWI48 0 "register_operand" "=r")
12919 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")]
12921 (clobber (reg:CC FLAGS_REG))]
12923 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12925 "&& reload_completed"
12927 [(set (match_dup 0)
12928 (unspec:SWI48 [(match_dup 1)] UNSPEC_TZCNT))
12929 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12930 (clobber (reg:CC FLAGS_REG))])]
12932 if (!reg_mentioned_p (operands[0], operands[1]))
12933 ix86_expand_clear (operands[0]);
12936 (define_insn "*bmi_tzcnt_<mode>_falsedep"
12937 [(set (match_operand:SWI48 0 "register_operand" "=r")
12939 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")]
12941 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12942 UNSPEC_INSN_FALSE_DEP)
12943 (clobber (reg:CC FLAGS_REG))]
12945 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12946 [(set_attr "type" "alu1")
12947 (set_attr "prefix_0f" "1")
12948 (set_attr "prefix_rep" "1")
12949 (set_attr "mode" "<MODE>")])
12951 (define_insn "*bmi_tzcnt_<mode>"
12952 [(set (match_operand:SWI248 0 "register_operand" "=r")
12954 [(match_operand:SWI248 1 "nonimmediate_operand" "rm")]
12956 (clobber (reg:CC FLAGS_REG))]
12958 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12959 [(set_attr "type" "alu1")
12960 (set_attr "prefix_0f" "1")
12961 (set_attr "prefix_rep" "1")
12962 (set_attr "mode" "<MODE>")])
12964 (define_expand "clz<mode>2"
12966 [(set (match_operand:SWI48 0 "register_operand")
12969 (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
12970 (clobber (reg:CC FLAGS_REG))])
12972 [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
12973 (clobber (reg:CC FLAGS_REG))])]
12978 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12981 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12984 (define_expand "clz<mode>2_lzcnt"
12986 [(set (match_operand:SWI48 0 "register_operand")
12988 (match_operand:SWI48 1 "nonimmediate_operand")))
12989 (clobber (reg:CC FLAGS_REG))])]
12992 (define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
12993 [(set (match_operand:SWI48 0 "register_operand" "=r")
12995 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12996 (clobber (reg:CC FLAGS_REG))]
12998 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
13000 "&& reload_completed"
13002 [(set (match_dup 0)
13003 (clz:SWI48 (match_dup 1)))
13004 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13005 (clobber (reg:CC FLAGS_REG))])]
13007 if (!reg_mentioned_p (operands[0], operands[1]))
13008 ix86_expand_clear (operands[0]);
13011 (define_insn "*clz<mode>2_lzcnt_falsedep"
13012 [(set (match_operand:SWI48 0 "register_operand" "=r")
13014 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13015 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13016 UNSPEC_INSN_FALSE_DEP)
13017 (clobber (reg:CC FLAGS_REG))]
13019 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13020 [(set_attr "prefix_rep" "1")
13021 (set_attr "type" "bitmanip")
13022 (set_attr "mode" "<MODE>")])
13024 (define_insn "*clz<mode>2_lzcnt"
13025 [(set (match_operand:SWI48 0 "register_operand" "=r")
13026 (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13027 (clobber (reg:CC FLAGS_REG))]
13029 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13030 [(set_attr "prefix_rep" "1")
13031 (set_attr "type" "bitmanip")
13032 (set_attr "mode" "<MODE>")])
13034 ;; Version of lzcnt that is expanded from intrinsics. This version provides
13035 ;; operand size as output when source operand is zero.
13037 (define_expand "lzcnt_<mode>"
13039 [(set (match_operand:SWI248 0 "register_operand")
13041 [(match_operand:SWI248 1 "nonimmediate_operand")]
13043 (clobber (reg:CC FLAGS_REG))])]
13046 ; False dependency happens when destination is only updated by tzcnt,
13047 ; lzcnt or popcnt. There is no false dependency when destination is
13048 ; also used in source.
13049 (define_insn_and_split "*lzcnt_<mode>_falsedep_1"
13050 [(set (match_operand:SWI48 0 "register_operand" "=r")
13052 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")]
13054 (clobber (reg:CC FLAGS_REG))]
13056 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
13058 "&& reload_completed"
13060 [(set (match_dup 0)
13061 (unspec:SWI48 [(match_dup 1)] UNSPEC_LZCNT))
13062 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13063 (clobber (reg:CC FLAGS_REG))])]
13065 if (!reg_mentioned_p (operands[0], operands[1]))
13066 ix86_expand_clear (operands[0]);
13069 (define_insn "*lzcnt_<mode>_falsedep"
13070 [(set (match_operand:SWI48 0 "register_operand" "=r")
13072 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")]
13074 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13075 UNSPEC_INSN_FALSE_DEP)
13076 (clobber (reg:CC FLAGS_REG))]
13078 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13079 [(set_attr "type" "alu1")
13080 (set_attr "prefix_0f" "1")
13081 (set_attr "prefix_rep" "1")
13082 (set_attr "mode" "<MODE>")])
13084 (define_insn "*lzcnt_<mode>"
13085 [(set (match_operand:SWI248 0 "register_operand" "=r")
13087 [(match_operand:SWI248 1 "nonimmediate_operand" "rm")]
13089 (clobber (reg:CC FLAGS_REG))]
13091 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13092 [(set_attr "type" "alu1")
13093 (set_attr "prefix_0f" "1")
13094 (set_attr "prefix_rep" "1")
13095 (set_attr "mode" "<MODE>")])
13097 ;; BMI instructions.
13098 (define_insn "*bmi_andn_<mode>"
13099 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
13101 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
13102 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
13103 (clobber (reg:CC FLAGS_REG))]
13105 "andn\t{%2, %1, %0|%0, %1, %2}"
13106 [(set_attr "type" "bitmanip")
13107 (set_attr "btver2_decode" "direct, double")
13108 (set_attr "mode" "<MODE>")])
13110 (define_insn "*bmi_andn_<mode>_ccno"
13111 [(set (reg FLAGS_REG)
13114 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
13115 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
13117 (clobber (match_scratch:SWI48 0 "=r,r"))]
13118 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
13119 "andn\t{%2, %1, %0|%0, %1, %2}"
13120 [(set_attr "type" "bitmanip")
13121 (set_attr "btver2_decode" "direct, double")
13122 (set_attr "mode" "<MODE>")])
13124 (define_insn "bmi_bextr_<mode>"
13125 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
13126 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13127 (match_operand:SWI48 2 "register_operand" "r,r")]
13129 (clobber (reg:CC FLAGS_REG))]
13131 "bextr\t{%2, %1, %0|%0, %1, %2}"
13132 [(set_attr "type" "bitmanip")
13133 (set_attr "btver2_decode" "direct, double")
13134 (set_attr "mode" "<MODE>")])
13136 (define_insn "*bmi_bextr_<mode>_ccz"
13137 [(set (reg:CCZ FLAGS_REG)
13139 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13140 (match_operand:SWI48 2 "register_operand" "r,r")]
13143 (clobber (match_scratch:SWI48 0 "=r,r"))]
13145 "bextr\t{%2, %1, %0|%0, %1, %2}"
13146 [(set_attr "type" "bitmanip")
13147 (set_attr "btver2_decode" "direct, double")
13148 (set_attr "mode" "<MODE>")])
13150 (define_insn "*bmi_blsi_<mode>"
13151 [(set (match_operand:SWI48 0 "register_operand" "=r")
13154 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
13156 (clobber (reg:CC FLAGS_REG))]
13158 "blsi\t{%1, %0|%0, %1}"
13159 [(set_attr "type" "bitmanip")
13160 (set_attr "btver2_decode" "double")
13161 (set_attr "mode" "<MODE>")])
13163 (define_insn "*bmi_blsmsk_<mode>"
13164 [(set (match_operand:SWI48 0 "register_operand" "=r")
13167 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13170 (clobber (reg:CC FLAGS_REG))]
13172 "blsmsk\t{%1, %0|%0, %1}"
13173 [(set_attr "type" "bitmanip")
13174 (set_attr "btver2_decode" "double")
13175 (set_attr "mode" "<MODE>")])
13177 (define_insn "*bmi_blsr_<mode>"
13178 [(set (match_operand:SWI48 0 "register_operand" "=r")
13181 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13184 (clobber (reg:CC FLAGS_REG))]
13186 "blsr\t{%1, %0|%0, %1}"
13187 [(set_attr "type" "bitmanip")
13188 (set_attr "btver2_decode" "double")
13189 (set_attr "mode" "<MODE>")])
13191 ;; BMI2 instructions.
13192 (define_expand "bmi2_bzhi_<mode>3"
13194 [(set (match_operand:SWI48 0 "register_operand")
13195 (zero_extract:SWI48
13196 (match_operand:SWI48 1 "nonimmediate_operand")
13198 (and:SWI48 (match_operand:SWI48 2 "register_operand")
13202 (clobber (reg:CC FLAGS_REG))])]
13204 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
13206 (define_insn "*bmi2_bzhi_<mode>3"
13207 [(set (match_operand:SWI48 0 "register_operand" "=r")
13208 (zero_extract:SWI48
13209 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13211 (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
13213 (match_operand:SWI48 3 "const_int_operand" "n"))
13215 (clobber (reg:CC FLAGS_REG))]
13216 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13217 "bzhi\t{%2, %1, %0|%0, %1, %2}"
13218 [(set_attr "type" "bitmanip")
13219 (set_attr "prefix" "vex")
13220 (set_attr "mode" "<MODE>")])
13222 (define_mode_attr k [(SI "k") (DI "q")])
13224 (define_insn "*bmi2_bzhi_<mode>3_1"
13225 [(set (match_operand:SWI48 0 "register_operand" "=r")
13226 (zero_extract:SWI48
13227 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13229 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13230 (match_operand:SWI48 3 "const_int_operand" "n"))
13232 (clobber (reg:CC FLAGS_REG))]
13233 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13234 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13235 [(set_attr "type" "bitmanip")
13236 (set_attr "prefix" "vex")
13237 (set_attr "mode" "<MODE>")])
13239 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
13240 [(set (reg:CCZ FLAGS_REG)
13242 (zero_extract:SWI48
13243 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13245 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13246 (match_operand:SWI48 3 "const_int_operand" "n"))
13249 (clobber (match_scratch:SWI48 0 "=r"))]
13250 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13251 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13252 [(set_attr "type" "bitmanip")
13253 (set_attr "prefix" "vex")
13254 (set_attr "mode" "<MODE>")])
13256 (define_insn "bmi2_pdep_<mode>3"
13257 [(set (match_operand:SWI48 0 "register_operand" "=r")
13258 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13259 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13262 "pdep\t{%2, %1, %0|%0, %1, %2}"
13263 [(set_attr "type" "bitmanip")
13264 (set_attr "prefix" "vex")
13265 (set_attr "mode" "<MODE>")])
13267 (define_insn "bmi2_pext_<mode>3"
13268 [(set (match_operand:SWI48 0 "register_operand" "=r")
13269 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13270 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13273 "pext\t{%2, %1, %0|%0, %1, %2}"
13274 [(set_attr "type" "bitmanip")
13275 (set_attr "prefix" "vex")
13276 (set_attr "mode" "<MODE>")])
13278 ;; TBM instructions.
13279 (define_insn "tbm_bextri_<mode>"
13280 [(set (match_operand:SWI48 0 "register_operand" "=r")
13281 (zero_extract:SWI48
13282 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13283 (match_operand 2 "const_0_to_255_operand" "N")
13284 (match_operand 3 "const_0_to_255_operand" "N")))
13285 (clobber (reg:CC FLAGS_REG))]
13288 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
13289 return "bextr\t{%2, %1, %0|%0, %1, %2}";
13291 [(set_attr "type" "bitmanip")
13292 (set_attr "mode" "<MODE>")])
13294 (define_insn "*tbm_blcfill_<mode>"
13295 [(set (match_operand:SWI48 0 "register_operand" "=r")
13298 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13301 (clobber (reg:CC FLAGS_REG))]
13303 "blcfill\t{%1, %0|%0, %1}"
13304 [(set_attr "type" "bitmanip")
13305 (set_attr "mode" "<MODE>")])
13307 (define_insn "*tbm_blci_<mode>"
13308 [(set (match_operand:SWI48 0 "register_operand" "=r")
13312 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13315 (clobber (reg:CC FLAGS_REG))]
13317 "blci\t{%1, %0|%0, %1}"
13318 [(set_attr "type" "bitmanip")
13319 (set_attr "mode" "<MODE>")])
13321 (define_insn "*tbm_blcic_<mode>"
13322 [(set (match_operand:SWI48 0 "register_operand" "=r")
13325 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13329 (clobber (reg:CC FLAGS_REG))]
13331 "blcic\t{%1, %0|%0, %1}"
13332 [(set_attr "type" "bitmanip")
13333 (set_attr "mode" "<MODE>")])
13335 (define_insn "*tbm_blcmsk_<mode>"
13336 [(set (match_operand:SWI48 0 "register_operand" "=r")
13339 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13342 (clobber (reg:CC FLAGS_REG))]
13344 "blcmsk\t{%1, %0|%0, %1}"
13345 [(set_attr "type" "bitmanip")
13346 (set_attr "mode" "<MODE>")])
13348 (define_insn "*tbm_blcs_<mode>"
13349 [(set (match_operand:SWI48 0 "register_operand" "=r")
13352 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13355 (clobber (reg:CC FLAGS_REG))]
13357 "blcs\t{%1, %0|%0, %1}"
13358 [(set_attr "type" "bitmanip")
13359 (set_attr "mode" "<MODE>")])
13361 (define_insn "*tbm_blsfill_<mode>"
13362 [(set (match_operand:SWI48 0 "register_operand" "=r")
13365 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13368 (clobber (reg:CC FLAGS_REG))]
13370 "blsfill\t{%1, %0|%0, %1}"
13371 [(set_attr "type" "bitmanip")
13372 (set_attr "mode" "<MODE>")])
13374 (define_insn "*tbm_blsic_<mode>"
13375 [(set (match_operand:SWI48 0 "register_operand" "=r")
13378 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13382 (clobber (reg:CC FLAGS_REG))]
13384 "blsic\t{%1, %0|%0, %1}"
13385 [(set_attr "type" "bitmanip")
13386 (set_attr "mode" "<MODE>")])
13388 (define_insn "*tbm_t1mskc_<mode>"
13389 [(set (match_operand:SWI48 0 "register_operand" "=r")
13392 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13396 (clobber (reg:CC FLAGS_REG))]
13398 "t1mskc\t{%1, %0|%0, %1}"
13399 [(set_attr "type" "bitmanip")
13400 (set_attr "mode" "<MODE>")])
13402 (define_insn "*tbm_tzmsk_<mode>"
13403 [(set (match_operand:SWI48 0 "register_operand" "=r")
13406 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13410 (clobber (reg:CC FLAGS_REG))]
13412 "tzmsk\t{%1, %0|%0, %1}"
13413 [(set_attr "type" "bitmanip")
13414 (set_attr "mode" "<MODE>")])
13416 (define_insn "bsr_rex64"
13417 [(set (match_operand:DI 0 "register_operand" "=r")
13418 (minus:DI (const_int 63)
13419 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13420 (clobber (reg:CC FLAGS_REG))]
13422 "bsr{q}\t{%1, %0|%0, %1}"
13423 [(set_attr "type" "alu1")
13424 (set_attr "prefix_0f" "1")
13425 (set_attr "znver1_decode" "vector")
13426 (set_attr "mode" "DI")])
13429 [(set (match_operand:SI 0 "register_operand" "=r")
13430 (minus:SI (const_int 31)
13431 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13432 (clobber (reg:CC FLAGS_REG))]
13434 "bsr{l}\t{%1, %0|%0, %1}"
13435 [(set_attr "type" "alu1")
13436 (set_attr "prefix_0f" "1")
13437 (set_attr "znver1_decode" "vector")
13438 (set_attr "mode" "SI")])
13440 (define_insn "*bsrhi"
13441 [(set (match_operand:HI 0 "register_operand" "=r")
13442 (minus:HI (const_int 15)
13443 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13444 (clobber (reg:CC FLAGS_REG))]
13446 "bsr{w}\t{%1, %0|%0, %1}"
13447 [(set_attr "type" "alu1")
13448 (set_attr "prefix_0f" "1")
13449 (set_attr "znver1_decode" "vector")
13450 (set_attr "mode" "HI")])
13452 (define_expand "popcount<mode>2"
13454 [(set (match_operand:SWI248 0 "register_operand")
13456 (match_operand:SWI248 1 "nonimmediate_operand")))
13457 (clobber (reg:CC FLAGS_REG))])]
13460 (define_insn_and_split "*popcount<mode>2_falsedep_1"
13461 [(set (match_operand:SWI48 0 "register_operand" "=r")
13463 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13464 (clobber (reg:CC FLAGS_REG))]
13466 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
13468 "&& reload_completed"
13470 [(set (match_dup 0)
13471 (popcount:SWI48 (match_dup 1)))
13472 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13473 (clobber (reg:CC FLAGS_REG))])]
13475 if (!reg_mentioned_p (operands[0], operands[1]))
13476 ix86_expand_clear (operands[0]);
13479 (define_insn "*popcount<mode>2_falsedep"
13480 [(set (match_operand:SWI48 0 "register_operand" "=r")
13482 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13483 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13484 UNSPEC_INSN_FALSE_DEP)
13485 (clobber (reg:CC FLAGS_REG))]
13489 return "popcnt\t{%1, %0|%0, %1}";
13491 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13494 [(set_attr "prefix_rep" "1")
13495 (set_attr "type" "bitmanip")
13496 (set_attr "mode" "<MODE>")])
13498 (define_insn "*popcount<mode>2"
13499 [(set (match_operand:SWI248 0 "register_operand" "=r")
13501 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
13502 (clobber (reg:CC FLAGS_REG))]
13506 return "popcnt\t{%1, %0|%0, %1}";
13508 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13511 [(set_attr "prefix_rep" "1")
13512 (set_attr "type" "bitmanip")
13513 (set_attr "mode" "<MODE>")])
13515 (define_expand "bswapdi2"
13516 [(set (match_operand:DI 0 "register_operand")
13517 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
13521 operands[1] = force_reg (DImode, operands[1]);
13524 (define_expand "bswapsi2"
13525 [(set (match_operand:SI 0 "register_operand")
13526 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
13531 else if (TARGET_BSWAP)
13532 operands[1] = force_reg (SImode, operands[1]);
13535 rtx x = operands[0];
13537 emit_move_insn (x, operands[1]);
13538 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13539 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
13540 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13545 (define_insn "*bswap<mode>2_movbe"
13546 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
13547 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
13549 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13552 movbe\t{%1, %0|%0, %1}
13553 movbe\t{%1, %0|%0, %1}"
13554 [(set_attr "type" "bitmanip,imov,imov")
13555 (set_attr "modrm" "0,1,1")
13556 (set_attr "prefix_0f" "*,1,1")
13557 (set_attr "prefix_extra" "*,1,1")
13558 (set_attr "mode" "<MODE>")])
13560 (define_insn "*bswap<mode>2"
13561 [(set (match_operand:SWI48 0 "register_operand" "=r")
13562 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
13565 [(set_attr "type" "bitmanip")
13566 (set_attr "modrm" "0")
13567 (set_attr "mode" "<MODE>")])
13569 (define_insn "*bswaphi_lowpart_1"
13570 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
13571 (bswap:HI (match_dup 0)))
13572 (clobber (reg:CC FLAGS_REG))]
13573 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
13575 xchg{b}\t{%h0, %b0|%b0, %h0}
13576 rol{w}\t{$8, %0|%0, 8}"
13577 [(set_attr "length" "2,4")
13578 (set_attr "mode" "QI,HI")])
13580 (define_insn "bswaphi_lowpart"
13581 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
13582 (bswap:HI (match_dup 0)))
13583 (clobber (reg:CC FLAGS_REG))]
13585 "rol{w}\t{$8, %0|%0, 8}"
13586 [(set_attr "length" "4")
13587 (set_attr "mode" "HI")])
13589 (define_expand "paritydi2"
13590 [(set (match_operand:DI 0 "register_operand")
13591 (parity:DI (match_operand:DI 1 "register_operand")))]
13594 rtx scratch = gen_reg_rtx (QImode);
13597 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
13598 NULL_RTX, operands[1]));
13600 cond = gen_rtx_fmt_ee (ORDERED, QImode,
13601 gen_rtx_REG (CCmode, FLAGS_REG),
13603 emit_insn (gen_rtx_SET (scratch, cond));
13606 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
13609 rtx tmp = gen_reg_rtx (SImode);
13611 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
13612 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
13617 (define_expand "paritysi2"
13618 [(set (match_operand:SI 0 "register_operand")
13619 (parity:SI (match_operand:SI 1 "register_operand")))]
13622 rtx scratch = gen_reg_rtx (QImode);
13625 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
13627 cond = gen_rtx_fmt_ee (ORDERED, QImode,
13628 gen_rtx_REG (CCmode, FLAGS_REG),
13630 emit_insn (gen_rtx_SET (scratch, cond));
13632 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
13636 (define_insn_and_split "paritydi2_cmp"
13637 [(set (reg:CC FLAGS_REG)
13638 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
13640 (clobber (match_scratch:DI 0 "=r"))
13641 (clobber (match_scratch:SI 1 "=&r"))
13642 (clobber (match_scratch:HI 2 "=Q"))]
13645 "&& reload_completed"
13647 [(set (match_dup 1)
13648 (xor:SI (match_dup 1) (match_dup 4)))
13649 (clobber (reg:CC FLAGS_REG))])
13651 [(set (reg:CC FLAGS_REG)
13652 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13653 (clobber (match_dup 1))
13654 (clobber (match_dup 2))])]
13656 operands[4] = gen_lowpart (SImode, operands[3]);
13660 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
13661 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
13664 operands[1] = gen_highpart (SImode, operands[3]);
13667 (define_insn_and_split "paritysi2_cmp"
13668 [(set (reg:CC FLAGS_REG)
13669 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
13671 (clobber (match_scratch:SI 0 "=r"))
13672 (clobber (match_scratch:HI 1 "=&Q"))]
13675 "&& reload_completed"
13677 [(set (match_dup 1)
13678 (xor:HI (match_dup 1) (match_dup 3)))
13679 (clobber (reg:CC FLAGS_REG))])
13681 [(set (reg:CC FLAGS_REG)
13682 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13683 (clobber (match_dup 1))])]
13685 operands[3] = gen_lowpart (HImode, operands[2]);
13687 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
13688 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
13691 (define_insn "*parityhi2_cmp"
13692 [(set (reg:CC FLAGS_REG)
13693 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
13695 (clobber (match_scratch:HI 0 "=Q"))]
13697 "xor{b}\t{%h0, %b0|%b0, %h0}"
13698 [(set_attr "length" "2")
13699 (set_attr "mode" "HI")])
13702 ;; Thread-local storage patterns for ELF.
13704 ;; Note that these code sequences must appear exactly as shown
13705 ;; in order to allow linker relaxation.
13707 (define_insn "*tls_global_dynamic_32_gnu"
13708 [(set (match_operand:SI 0 "register_operand" "=a")
13710 [(match_operand:SI 1 "register_operand" "b")
13711 (match_operand 2 "tls_symbolic_operand")
13712 (match_operand 3 "constant_call_address_operand" "Bz")
13715 (clobber (match_scratch:SI 4 "=d"))
13716 (clobber (match_scratch:SI 5 "=c"))
13717 (clobber (reg:CC FLAGS_REG))]
13718 "!TARGET_64BIT && TARGET_GNU_TLS"
13721 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
13722 if (TARGET_SUN_TLS)
13723 #ifdef HAVE_AS_IX86_TLSGDPLT
13724 return "call\t%a2@tlsgdplt";
13726 return "call\t%p3@plt";
13728 return "call\t%P3";
13730 [(set_attr "type" "multi")
13731 (set_attr "length" "12")])
13733 (define_expand "tls_global_dynamic_32"
13735 [(set (match_operand:SI 0 "register_operand")
13736 (unspec:SI [(match_operand:SI 2 "register_operand")
13737 (match_operand 1 "tls_symbolic_operand")
13738 (match_operand 3 "constant_call_address_operand")
13741 (clobber (match_scratch:SI 4))
13742 (clobber (match_scratch:SI 5))
13743 (clobber (reg:CC FLAGS_REG))])]
13745 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13747 (define_insn "*tls_global_dynamic_64_<mode>"
13748 [(set (match_operand:P 0 "register_operand" "=a")
13750 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
13751 (match_operand 3)))
13752 (unspec:P [(match_operand 1 "tls_symbolic_operand")
13758 fputs (ASM_BYTE "0x66\n", asm_out_file);
13760 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13761 fputs (ASM_SHORT "0x6666\n", asm_out_file);
13762 fputs ("\trex64\n", asm_out_file);
13763 if (TARGET_SUN_TLS)
13764 return "call\t%p2@plt";
13765 return "call\t%P2";
13767 [(set_attr "type" "multi")
13768 (set (attr "length")
13769 (symbol_ref "TARGET_X32 ? 15 : 16"))])
13771 (define_insn "*tls_global_dynamic_64_largepic"
13772 [(set (match_operand:DI 0 "register_operand" "=a")
13774 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
13775 (match_operand:DI 3 "immediate_operand" "i")))
13776 (match_operand 4)))
13777 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13780 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13781 && GET_CODE (operands[3]) == CONST
13782 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13783 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13786 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13787 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13788 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13789 return "call\t{*%%rax|rax}";
13791 [(set_attr "type" "multi")
13792 (set_attr "length" "22")])
13794 (define_expand "tls_global_dynamic_64_<mode>"
13796 [(set (match_operand:P 0 "register_operand")
13798 (mem:QI (match_operand 2))
13800 (unspec:P [(match_operand 1 "tls_symbolic_operand")
13804 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13806 (define_insn "*tls_local_dynamic_base_32_gnu"
13807 [(set (match_operand:SI 0 "register_operand" "=a")
13809 [(match_operand:SI 1 "register_operand" "b")
13810 (match_operand 2 "constant_call_address_operand" "Bz")
13812 UNSPEC_TLS_LD_BASE))
13813 (clobber (match_scratch:SI 3 "=d"))
13814 (clobber (match_scratch:SI 4 "=c"))
13815 (clobber (reg:CC FLAGS_REG))]
13816 "!TARGET_64BIT && TARGET_GNU_TLS"
13819 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13820 if (TARGET_SUN_TLS)
13822 if (HAVE_AS_IX86_TLSLDMPLT)
13823 return "call\t%&@tlsldmplt";
13825 return "call\t%p2@plt";
13827 return "call\t%P2";
13829 [(set_attr "type" "multi")
13830 (set_attr "length" "11")])
13832 (define_expand "tls_local_dynamic_base_32"
13834 [(set (match_operand:SI 0 "register_operand")
13836 [(match_operand:SI 1 "register_operand")
13837 (match_operand 2 "constant_call_address_operand")
13839 UNSPEC_TLS_LD_BASE))
13840 (clobber (match_scratch:SI 3))
13841 (clobber (match_scratch:SI 4))
13842 (clobber (reg:CC FLAGS_REG))])]
13844 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13846 (define_insn "*tls_local_dynamic_base_64_<mode>"
13847 [(set (match_operand:P 0 "register_operand" "=a")
13849 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13850 (match_operand 2)))
13851 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
13855 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13856 if (TARGET_SUN_TLS)
13857 return "call\t%p1@plt";
13858 return "call\t%P1";
13860 [(set_attr "type" "multi")
13861 (set_attr "length" "12")])
13863 (define_insn "*tls_local_dynamic_base_64_largepic"
13864 [(set (match_operand:DI 0 "register_operand" "=a")
13866 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13867 (match_operand:DI 2 "immediate_operand" "i")))
13868 (match_operand 3)))
13869 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
13870 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13871 && GET_CODE (operands[2]) == CONST
13872 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13873 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13876 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13877 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13878 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13879 return "call\t{*%%rax|rax}";
13881 [(set_attr "type" "multi")
13882 (set_attr "length" "22")])
13884 (define_expand "tls_local_dynamic_base_64_<mode>"
13886 [(set (match_operand:P 0 "register_operand")
13888 (mem:QI (match_operand 1))
13890 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
13892 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13894 ;; Local dynamic of a single variable is a lose. Show combine how
13895 ;; to convert that back to global dynamic.
13897 (define_insn_and_split "*tls_local_dynamic_32_once"
13898 [(set (match_operand:SI 0 "register_operand" "=a")
13900 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13901 (match_operand 2 "constant_call_address_operand" "Bz")
13903 UNSPEC_TLS_LD_BASE)
13904 (const:SI (unspec:SI
13905 [(match_operand 3 "tls_symbolic_operand")]
13907 (clobber (match_scratch:SI 4 "=d"))
13908 (clobber (match_scratch:SI 5 "=c"))
13909 (clobber (reg:CC FLAGS_REG))]
13914 [(set (match_dup 0)
13915 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13918 (clobber (match_dup 4))
13919 (clobber (match_dup 5))
13920 (clobber (reg:CC FLAGS_REG))])])
13922 ;; Segment register for the thread base ptr load
13923 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13925 ;; Load and add the thread base pointer from %<tp_seg>:0.
13926 (define_insn "*load_tp_x32"
13927 [(set (match_operand:SI 0 "register_operand" "=r")
13928 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13930 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13931 [(set_attr "type" "imov")
13932 (set_attr "modrm" "0")
13933 (set_attr "length" "7")
13934 (set_attr "memory" "load")
13935 (set_attr "imm_disp" "false")])
13937 (define_insn "*load_tp_x32_zext"
13938 [(set (match_operand:DI 0 "register_operand" "=r")
13939 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13941 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13942 [(set_attr "type" "imov")
13943 (set_attr "modrm" "0")
13944 (set_attr "length" "7")
13945 (set_attr "memory" "load")
13946 (set_attr "imm_disp" "false")])
13948 (define_insn "*load_tp_<mode>"
13949 [(set (match_operand:P 0 "register_operand" "=r")
13950 (unspec:P [(const_int 0)] UNSPEC_TP))]
13952 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13953 [(set_attr "type" "imov")
13954 (set_attr "modrm" "0")
13955 (set_attr "length" "7")
13956 (set_attr "memory" "load")
13957 (set_attr "imm_disp" "false")])
13959 (define_insn "*add_tp_x32"
13960 [(set (match_operand:SI 0 "register_operand" "=r")
13961 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13962 (match_operand:SI 1 "register_operand" "0")))
13963 (clobber (reg:CC FLAGS_REG))]
13965 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13966 [(set_attr "type" "alu")
13967 (set_attr "modrm" "0")
13968 (set_attr "length" "7")
13969 (set_attr "memory" "load")
13970 (set_attr "imm_disp" "false")])
13972 (define_insn "*add_tp_x32_zext"
13973 [(set (match_operand:DI 0 "register_operand" "=r")
13975 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13976 (match_operand:SI 1 "register_operand" "0"))))
13977 (clobber (reg:CC FLAGS_REG))]
13979 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13980 [(set_attr "type" "alu")
13981 (set_attr "modrm" "0")
13982 (set_attr "length" "7")
13983 (set_attr "memory" "load")
13984 (set_attr "imm_disp" "false")])
13986 (define_insn "*add_tp_<mode>"
13987 [(set (match_operand:P 0 "register_operand" "=r")
13988 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13989 (match_operand:P 1 "register_operand" "0")))
13990 (clobber (reg:CC FLAGS_REG))]
13992 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13993 [(set_attr "type" "alu")
13994 (set_attr "modrm" "0")
13995 (set_attr "length" "7")
13996 (set_attr "memory" "load")
13997 (set_attr "imm_disp" "false")])
13999 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
14000 ;; %rax as destination of the initial executable code sequence.
14001 (define_insn "tls_initial_exec_64_sun"
14002 [(set (match_operand:DI 0 "register_operand" "=a")
14004 [(match_operand 1 "tls_symbolic_operand")]
14005 UNSPEC_TLS_IE_SUN))
14006 (clobber (reg:CC FLAGS_REG))]
14007 "TARGET_64BIT && TARGET_SUN_TLS"
14010 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
14011 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
14013 [(set_attr "type" "multi")])
14015 ;; GNU2 TLS patterns can be split.
14017 (define_expand "tls_dynamic_gnu2_32"
14018 [(set (match_dup 3)
14019 (plus:SI (match_operand:SI 2 "register_operand")
14021 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
14024 [(set (match_operand:SI 0 "register_operand")
14025 (unspec:SI [(match_dup 1) (match_dup 3)
14026 (match_dup 2) (reg:SI SP_REG)]
14028 (clobber (reg:CC FLAGS_REG))])]
14029 "!TARGET_64BIT && TARGET_GNU2_TLS"
14031 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14032 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14035 (define_insn "*tls_dynamic_gnu2_lea_32"
14036 [(set (match_operand:SI 0 "register_operand" "=r")
14037 (plus:SI (match_operand:SI 1 "register_operand" "b")
14039 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
14040 UNSPEC_TLSDESC))))]
14041 "!TARGET_64BIT && TARGET_GNU2_TLS"
14042 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
14043 [(set_attr "type" "lea")
14044 (set_attr "mode" "SI")
14045 (set_attr "length" "6")
14046 (set_attr "length_address" "4")])
14048 (define_insn "*tls_dynamic_gnu2_call_32"
14049 [(set (match_operand:SI 0 "register_operand" "=a")
14050 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
14051 (match_operand:SI 2 "register_operand" "0")
14052 ;; we have to make sure %ebx still points to the GOT
14053 (match_operand:SI 3 "register_operand" "b")
14056 (clobber (reg:CC FLAGS_REG))]
14057 "!TARGET_64BIT && TARGET_GNU2_TLS"
14058 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14059 [(set_attr "type" "call")
14060 (set_attr "length" "2")
14061 (set_attr "length_address" "0")])
14063 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14064 [(set (match_operand:SI 0 "register_operand" "=&a")
14066 (unspec:SI [(match_operand 3 "tls_modbase_operand")
14067 (match_operand:SI 4)
14068 (match_operand:SI 2 "register_operand" "b")
14071 (const:SI (unspec:SI
14072 [(match_operand 1 "tls_symbolic_operand")]
14074 (clobber (reg:CC FLAGS_REG))]
14075 "!TARGET_64BIT && TARGET_GNU2_TLS"
14078 [(set (match_dup 0) (match_dup 5))]
14080 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14081 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14084 (define_expand "tls_dynamic_gnu2_64"
14085 [(set (match_dup 2)
14086 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14089 [(set (match_operand:DI 0 "register_operand")
14090 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14092 (clobber (reg:CC FLAGS_REG))])]
14093 "TARGET_64BIT && TARGET_GNU2_TLS"
14095 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14096 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14099 (define_insn "*tls_dynamic_gnu2_lea_64"
14100 [(set (match_operand:DI 0 "register_operand" "=r")
14101 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14103 "TARGET_64BIT && TARGET_GNU2_TLS"
14104 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
14105 [(set_attr "type" "lea")
14106 (set_attr "mode" "DI")
14107 (set_attr "length" "7")
14108 (set_attr "length_address" "4")])
14110 (define_insn "*tls_dynamic_gnu2_call_64"
14111 [(set (match_operand:DI 0 "register_operand" "=a")
14112 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14113 (match_operand:DI 2 "register_operand" "0")
14116 (clobber (reg:CC FLAGS_REG))]
14117 "TARGET_64BIT && TARGET_GNU2_TLS"
14118 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14119 [(set_attr "type" "call")
14120 (set_attr "length" "2")
14121 (set_attr "length_address" "0")])
14123 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14124 [(set (match_operand:DI 0 "register_operand" "=&a")
14126 (unspec:DI [(match_operand 2 "tls_modbase_operand")
14127 (match_operand:DI 3)
14130 (const:DI (unspec:DI
14131 [(match_operand 1 "tls_symbolic_operand")]
14133 (clobber (reg:CC FLAGS_REG))]
14134 "TARGET_64BIT && TARGET_GNU2_TLS"
14137 [(set (match_dup 0) (match_dup 4))]
14139 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14140 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14143 ;; These patterns match the binary 387 instructions for addM3, subM3,
14144 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14145 ;; SFmode. The first is the normal insn, the second the same insn but
14146 ;; with one operand a conversion, and the third the same insn but with
14147 ;; the other operand a conversion. The conversion may be SFmode or
14148 ;; SImode if the target mode DFmode, but only SImode if the target mode
14151 ;; Gcc is slightly more smart about handling normal two address instructions
14152 ;; so use special patterns for add and mull.
14154 (define_insn "*fop_<mode>_comm_mixed"
14155 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
14156 (match_operator:MODEF 3 "binary_fp_operator"
14157 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
14158 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
14159 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14160 && COMMUTATIVE_ARITH_P (operands[3])
14161 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14162 "* return output_387_binary_op (insn, operands);"
14163 [(set (attr "type")
14164 (if_then_else (eq_attr "alternative" "1,2")
14165 (if_then_else (match_operand:MODEF 3 "mult_operator")
14166 (const_string "ssemul")
14167 (const_string "sseadd"))
14168 (if_then_else (match_operand:MODEF 3 "mult_operator")
14169 (const_string "fmul")
14170 (const_string "fop"))))
14171 (set_attr "isa" "*,noavx,avx")
14172 (set_attr "prefix" "orig,orig,vex")
14173 (set_attr "mode" "<MODE>")
14174 (set (attr "enabled")
14175 (cond [(eq_attr "alternative" "0")
14176 (symbol_ref "TARGET_MIX_SSE_I387")
14178 (const_string "*")))])
14180 (define_insn "*fop_<mode>_comm_i387"
14181 [(set (match_operand:MODEF 0 "register_operand" "=f")
14182 (match_operator:MODEF 3 "binary_fp_operator"
14183 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
14184 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
14185 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
14186 && COMMUTATIVE_ARITH_P (operands[3])
14187 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14188 "* return output_387_binary_op (insn, operands);"
14189 [(set (attr "type")
14190 (if_then_else (match_operand:MODEF 3 "mult_operator")
14191 (const_string "fmul")
14192 (const_string "fop")))
14193 (set_attr "mode" "<MODE>")])
14195 (define_insn "*rcpsf2_sse"
14196 [(set (match_operand:SF 0 "register_operand" "=x")
14197 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14200 "%vrcpss\t{%1, %d0|%d0, %1}"
14201 [(set_attr "type" "sse")
14202 (set_attr "atom_sse_attr" "rcp")
14203 (set_attr "btver2_sse_attr" "rcp")
14204 (set_attr "prefix" "maybe_vex")
14205 (set_attr "mode" "SF")])
14207 (define_insn "*fop_<mode>_1_mixed"
14208 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
14209 (match_operator:MODEF 3 "binary_fp_operator"
14210 [(match_operand:MODEF 1
14211 "register_mixssei387nonimm_operand" "0,fm,0,v")
14212 (match_operand:MODEF 2
14213 "nonimmediate_operand" "fm,0,xm,vm")]))]
14214 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14215 && !COMMUTATIVE_ARITH_P (operands[3])
14216 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14217 "* return output_387_binary_op (insn, operands);"
14218 [(set (attr "type")
14219 (cond [(and (eq_attr "alternative" "2,3")
14220 (match_operand:MODEF 3 "mult_operator"))
14221 (const_string "ssemul")
14222 (and (eq_attr "alternative" "2,3")
14223 (match_operand:MODEF 3 "div_operator"))
14224 (const_string "ssediv")
14225 (eq_attr "alternative" "2,3")
14226 (const_string "sseadd")
14227 (match_operand:MODEF 3 "mult_operator")
14228 (const_string "fmul")
14229 (match_operand:MODEF 3 "div_operator")
14230 (const_string "fdiv")
14232 (const_string "fop")))
14233 (set_attr "isa" "*,*,noavx,avx")
14234 (set_attr "prefix" "orig,orig,orig,vex")
14235 (set_attr "mode" "<MODE>")
14236 (set (attr "enabled")
14237 (cond [(eq_attr "alternative" "0,1")
14238 (symbol_ref "TARGET_MIX_SSE_I387")
14240 (const_string "*")))])
14242 ;; This pattern is not fully shadowed by the pattern above.
14243 (define_insn "*fop_<mode>_1_i387"
14244 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
14245 (match_operator:MODEF 3 "binary_fp_operator"
14246 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
14247 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
14248 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
14249 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14250 && !COMMUTATIVE_ARITH_P (operands[3])
14251 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14252 "* return output_387_binary_op (insn, operands);"
14253 [(set (attr "type")
14254 (cond [(match_operand:MODEF 3 "mult_operator")
14255 (const_string "fmul")
14256 (match_operand:MODEF 3 "div_operator")
14257 (const_string "fdiv")
14259 (const_string "fop")))
14260 (set_attr "mode" "<MODE>")])
14262 ;; ??? Add SSE splitters for these!
14263 (define_insn "*fop_<MODEF:mode>_2_i387"
14264 [(set (match_operand:MODEF 0 "register_operand" "=f")
14265 (match_operator:MODEF 3 "binary_fp_operator"
14267 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14268 (match_operand:MODEF 2 "register_operand" "0")]))]
14269 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14270 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14271 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14272 || optimize_function_for_size_p (cfun))"
14273 { return output_387_binary_op (insn, operands); }
14274 [(set (attr "type")
14275 (cond [(match_operand:MODEF 3 "mult_operator")
14276 (const_string "fmul")
14277 (match_operand:MODEF 3 "div_operator")
14278 (const_string "fdiv")
14280 (const_string "fop")))
14281 (set_attr "fp_int_src" "true")
14282 (set_attr "mode" "<SWI24:MODE>")])
14284 (define_insn "*fop_<MODEF:mode>_3_i387"
14285 [(set (match_operand:MODEF 0 "register_operand" "=f")
14286 (match_operator:MODEF 3 "binary_fp_operator"
14287 [(match_operand:MODEF 1 "register_operand" "0")
14289 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14290 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14291 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14292 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14293 || optimize_function_for_size_p (cfun))"
14294 { return output_387_binary_op (insn, operands); }
14295 [(set (attr "type")
14296 (cond [(match_operand:MODEF 3 "mult_operator")
14297 (const_string "fmul")
14298 (match_operand:MODEF 3 "div_operator")
14299 (const_string "fdiv")
14301 (const_string "fop")))
14302 (set_attr "fp_int_src" "true")
14303 (set_attr "mode" "<MODE>")])
14305 (define_insn "*fop_df_4_i387"
14306 [(set (match_operand:DF 0 "register_operand" "=f,f")
14307 (match_operator:DF 3 "binary_fp_operator"
14309 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14310 (match_operand:DF 2 "register_operand" "0,f")]))]
14311 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14312 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14313 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14314 "* return output_387_binary_op (insn, operands);"
14315 [(set (attr "type")
14316 (cond [(match_operand:DF 3 "mult_operator")
14317 (const_string "fmul")
14318 (match_operand:DF 3 "div_operator")
14319 (const_string "fdiv")
14321 (const_string "fop")))
14322 (set_attr "mode" "SF")])
14324 (define_insn "*fop_df_5_i387"
14325 [(set (match_operand:DF 0 "register_operand" "=f,f")
14326 (match_operator:DF 3 "binary_fp_operator"
14327 [(match_operand:DF 1 "register_operand" "0,f")
14329 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14330 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14331 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14332 "* return output_387_binary_op (insn, operands);"
14333 [(set (attr "type")
14334 (cond [(match_operand:DF 3 "mult_operator")
14335 (const_string "fmul")
14336 (match_operand:DF 3 "div_operator")
14337 (const_string "fdiv")
14339 (const_string "fop")))
14340 (set_attr "mode" "SF")])
14342 (define_insn "*fop_df_6_i387"
14343 [(set (match_operand:DF 0 "register_operand" "=f,f")
14344 (match_operator:DF 3 "binary_fp_operator"
14346 (match_operand:SF 1 "register_operand" "0,f"))
14348 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14349 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14350 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14351 "* return output_387_binary_op (insn, operands);"
14352 [(set (attr "type")
14353 (cond [(match_operand:DF 3 "mult_operator")
14354 (const_string "fmul")
14355 (match_operand:DF 3 "div_operator")
14356 (const_string "fdiv")
14358 (const_string "fop")))
14359 (set_attr "mode" "SF")])
14361 (define_insn "*fop_xf_comm_i387"
14362 [(set (match_operand:XF 0 "register_operand" "=f")
14363 (match_operator:XF 3 "binary_fp_operator"
14364 [(match_operand:XF 1 "register_operand" "%0")
14365 (match_operand:XF 2 "register_operand" "f")]))]
14367 && COMMUTATIVE_ARITH_P (operands[3])"
14368 "* return output_387_binary_op (insn, operands);"
14369 [(set (attr "type")
14370 (if_then_else (match_operand:XF 3 "mult_operator")
14371 (const_string "fmul")
14372 (const_string "fop")))
14373 (set_attr "mode" "XF")])
14375 (define_insn "*fop_xf_1_i387"
14376 [(set (match_operand:XF 0 "register_operand" "=f,f")
14377 (match_operator:XF 3 "binary_fp_operator"
14378 [(match_operand:XF 1 "register_operand" "0,f")
14379 (match_operand:XF 2 "register_operand" "f,0")]))]
14381 && !COMMUTATIVE_ARITH_P (operands[3])"
14382 "* return output_387_binary_op (insn, operands);"
14383 [(set (attr "type")
14384 (cond [(match_operand:XF 3 "mult_operator")
14385 (const_string "fmul")
14386 (match_operand:XF 3 "div_operator")
14387 (const_string "fdiv")
14389 (const_string "fop")))
14390 (set_attr "mode" "XF")])
14392 (define_insn "*fop_xf_2_i387"
14393 [(set (match_operand:XF 0 "register_operand" "=f")
14394 (match_operator:XF 3 "binary_fp_operator"
14396 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14397 (match_operand:XF 2 "register_operand" "0")]))]
14399 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14400 { return output_387_binary_op (insn, operands); }
14401 [(set (attr "type")
14402 (cond [(match_operand:XF 3 "mult_operator")
14403 (const_string "fmul")
14404 (match_operand:XF 3 "div_operator")
14405 (const_string "fdiv")
14407 (const_string "fop")))
14408 (set_attr "fp_int_src" "true")
14409 (set_attr "mode" "<MODE>")])
14411 (define_insn "*fop_xf_3_i387"
14412 [(set (match_operand:XF 0 "register_operand" "=f")
14413 (match_operator:XF 3 "binary_fp_operator"
14414 [(match_operand:XF 1 "register_operand" "0")
14416 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14418 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14419 { return output_387_binary_op (insn, operands); }
14420 [(set (attr "type")
14421 (cond [(match_operand:XF 3 "mult_operator")
14422 (const_string "fmul")
14423 (match_operand:XF 3 "div_operator")
14424 (const_string "fdiv")
14426 (const_string "fop")))
14427 (set_attr "fp_int_src" "true")
14428 (set_attr "mode" "<MODE>")])
14430 (define_insn "*fop_xf_4_i387"
14431 [(set (match_operand:XF 0 "register_operand" "=f,f")
14432 (match_operator:XF 3 "binary_fp_operator"
14434 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
14435 (match_operand:XF 2 "register_operand" "0,f")]))]
14437 "* return output_387_binary_op (insn, operands);"
14438 [(set (attr "type")
14439 (cond [(match_operand:XF 3 "mult_operator")
14440 (const_string "fmul")
14441 (match_operand:XF 3 "div_operator")
14442 (const_string "fdiv")
14444 (const_string "fop")))
14445 (set_attr "mode" "<MODE>")])
14447 (define_insn "*fop_xf_5_i387"
14448 [(set (match_operand:XF 0 "register_operand" "=f,f")
14449 (match_operator:XF 3 "binary_fp_operator"
14450 [(match_operand:XF 1 "register_operand" "0,f")
14452 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14454 "* return output_387_binary_op (insn, operands);"
14455 [(set (attr "type")
14456 (cond [(match_operand:XF 3 "mult_operator")
14457 (const_string "fmul")
14458 (match_operand:XF 3 "div_operator")
14459 (const_string "fdiv")
14461 (const_string "fop")))
14462 (set_attr "mode" "<MODE>")])
14464 (define_insn "*fop_xf_6_i387"
14465 [(set (match_operand:XF 0 "register_operand" "=f,f")
14466 (match_operator:XF 3 "binary_fp_operator"
14468 (match_operand:MODEF 1 "register_operand" "0,f"))
14470 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14472 "* return output_387_binary_op (insn, operands);"
14473 [(set (attr "type")
14474 (cond [(match_operand:XF 3 "mult_operator")
14475 (const_string "fmul")
14476 (match_operand:XF 3 "div_operator")
14477 (const_string "fdiv")
14479 (const_string "fop")))
14480 (set_attr "mode" "<MODE>")])
14482 ;; FPU special functions.
14484 ;; This pattern implements a no-op XFmode truncation for
14485 ;; all fancy i386 XFmode math functions.
14487 (define_insn "truncxf<mode>2_i387_noop_unspec"
14488 [(set (match_operand:MODEF 0 "register_operand" "=f")
14489 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
14490 UNSPEC_TRUNC_NOOP))]
14491 "TARGET_USE_FANCY_MATH_387"
14492 "* return output_387_reg_move (insn, operands);"
14493 [(set_attr "type" "fmov")
14494 (set_attr "mode" "<MODE>")])
14496 (define_insn "sqrtxf2"
14497 [(set (match_operand:XF 0 "register_operand" "=f")
14498 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14499 "TARGET_USE_FANCY_MATH_387"
14501 [(set_attr "type" "fpspc")
14502 (set_attr "mode" "XF")
14503 (set_attr "athlon_decode" "direct")
14504 (set_attr "amdfam10_decode" "direct")
14505 (set_attr "bdver1_decode" "direct")])
14507 (define_insn "sqrt_extend<mode>xf2_i387"
14508 [(set (match_operand:XF 0 "register_operand" "=f")
14511 (match_operand:MODEF 1 "register_operand" "0"))))]
14512 "TARGET_USE_FANCY_MATH_387"
14514 [(set_attr "type" "fpspc")
14515 (set_attr "mode" "XF")
14516 (set_attr "athlon_decode" "direct")
14517 (set_attr "amdfam10_decode" "direct")
14518 (set_attr "bdver1_decode" "direct")])
14520 (define_insn "*rsqrtsf2_sse"
14521 [(set (match_operand:SF 0 "register_operand" "=x")
14522 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14525 "%vrsqrtss\t{%1, %d0|%d0, %1}"
14526 [(set_attr "type" "sse")
14527 (set_attr "atom_sse_attr" "rcp")
14528 (set_attr "btver2_sse_attr" "rcp")
14529 (set_attr "prefix" "maybe_vex")
14530 (set_attr "mode" "SF")])
14532 (define_expand "rsqrtsf2"
14533 [(set (match_operand:SF 0 "register_operand")
14534 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
14538 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
14542 (define_insn "*sqrt<mode>2_sse"
14543 [(set (match_operand:MODEF 0 "register_operand" "=v")
14545 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
14546 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14547 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
14548 [(set_attr "type" "sse")
14549 (set_attr "atom_sse_attr" "sqrt")
14550 (set_attr "btver2_sse_attr" "sqrt")
14551 (set_attr "prefix" "maybe_vex")
14552 (set_attr "mode" "<MODE>")
14553 (set_attr "athlon_decode" "*")
14554 (set_attr "amdfam10_decode" "*")
14555 (set_attr "bdver1_decode" "*")])
14557 (define_expand "sqrt<mode>2"
14558 [(set (match_operand:MODEF 0 "register_operand")
14560 (match_operand:MODEF 1 "nonimmediate_operand")))]
14561 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
14562 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14564 if (<MODE>mode == SFmode
14566 && TARGET_RECIP_SQRT
14567 && !optimize_function_for_size_p (cfun)
14568 && flag_finite_math_only && !flag_trapping_math
14569 && flag_unsafe_math_optimizations)
14571 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
14575 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
14577 rtx op0 = gen_reg_rtx (XFmode);
14578 rtx op1 = force_reg (<MODE>mode, operands[1]);
14580 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
14581 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
14586 (define_insn "fpremxf4_i387"
14587 [(set (match_operand:XF 0 "register_operand" "=f")
14588 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14589 (match_operand:XF 3 "register_operand" "1")]
14591 (set (match_operand:XF 1 "register_operand" "=u")
14592 (unspec:XF [(match_dup 2) (match_dup 3)]
14594 (set (reg:CCFP FPSR_REG)
14595 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14597 "TARGET_USE_FANCY_MATH_387
14598 && flag_finite_math_only"
14600 [(set_attr "type" "fpspc")
14601 (set_attr "znver1_decode" "vector")
14602 (set_attr "mode" "XF")])
14604 (define_expand "fmodxf3"
14605 [(use (match_operand:XF 0 "register_operand"))
14606 (use (match_operand:XF 1 "general_operand"))
14607 (use (match_operand:XF 2 "general_operand"))]
14608 "TARGET_USE_FANCY_MATH_387
14609 && flag_finite_math_only"
14611 rtx_code_label *label = gen_label_rtx ();
14613 rtx op1 = gen_reg_rtx (XFmode);
14614 rtx op2 = gen_reg_rtx (XFmode);
14616 emit_move_insn (op2, operands[2]);
14617 emit_move_insn (op1, operands[1]);
14619 emit_label (label);
14620 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14621 ix86_emit_fp_unordered_jump (label);
14622 LABEL_NUSES (label) = 1;
14624 emit_move_insn (operands[0], op1);
14628 (define_expand "fmod<mode>3"
14629 [(use (match_operand:MODEF 0 "register_operand"))
14630 (use (match_operand:MODEF 1 "general_operand"))
14631 (use (match_operand:MODEF 2 "general_operand"))]
14632 "TARGET_USE_FANCY_MATH_387
14633 && flag_finite_math_only"
14635 rtx (*gen_truncxf) (rtx, rtx);
14637 rtx_code_label *label = gen_label_rtx ();
14639 rtx op1 = gen_reg_rtx (XFmode);
14640 rtx op2 = gen_reg_rtx (XFmode);
14642 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14643 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14645 emit_label (label);
14646 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14647 ix86_emit_fp_unordered_jump (label);
14648 LABEL_NUSES (label) = 1;
14650 /* Truncate the result properly for strict SSE math. */
14651 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14652 && !TARGET_MIX_SSE_I387)
14653 gen_truncxf = gen_truncxf<mode>2;
14655 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14657 emit_insn (gen_truncxf (operands[0], op1));
14661 (define_insn "fprem1xf4_i387"
14662 [(set (match_operand:XF 0 "register_operand" "=f")
14663 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14664 (match_operand:XF 3 "register_operand" "1")]
14666 (set (match_operand:XF 1 "register_operand" "=u")
14667 (unspec:XF [(match_dup 2) (match_dup 3)]
14669 (set (reg:CCFP FPSR_REG)
14670 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14672 "TARGET_USE_FANCY_MATH_387
14673 && flag_finite_math_only"
14675 [(set_attr "type" "fpspc")
14676 (set_attr "znver1_decode" "vector")
14677 (set_attr "mode" "XF")])
14679 (define_expand "remainderxf3"
14680 [(use (match_operand:XF 0 "register_operand"))
14681 (use (match_operand:XF 1 "general_operand"))
14682 (use (match_operand:XF 2 "general_operand"))]
14683 "TARGET_USE_FANCY_MATH_387
14684 && flag_finite_math_only"
14686 rtx_code_label *label = gen_label_rtx ();
14688 rtx op1 = gen_reg_rtx (XFmode);
14689 rtx op2 = gen_reg_rtx (XFmode);
14691 emit_move_insn (op2, operands[2]);
14692 emit_move_insn (op1, operands[1]);
14694 emit_label (label);
14695 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14696 ix86_emit_fp_unordered_jump (label);
14697 LABEL_NUSES (label) = 1;
14699 emit_move_insn (operands[0], op1);
14703 (define_expand "remainder<mode>3"
14704 [(use (match_operand:MODEF 0 "register_operand"))
14705 (use (match_operand:MODEF 1 "general_operand"))
14706 (use (match_operand:MODEF 2 "general_operand"))]
14707 "TARGET_USE_FANCY_MATH_387
14708 && flag_finite_math_only"
14710 rtx (*gen_truncxf) (rtx, rtx);
14712 rtx_code_label *label = gen_label_rtx ();
14714 rtx op1 = gen_reg_rtx (XFmode);
14715 rtx op2 = gen_reg_rtx (XFmode);
14717 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14718 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14720 emit_label (label);
14722 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14723 ix86_emit_fp_unordered_jump (label);
14724 LABEL_NUSES (label) = 1;
14726 /* Truncate the result properly for strict SSE math. */
14727 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14728 && !TARGET_MIX_SSE_I387)
14729 gen_truncxf = gen_truncxf<mode>2;
14731 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14733 emit_insn (gen_truncxf (operands[0], op1));
14737 (define_int_iterator SINCOS
14741 (define_int_attr sincos
14742 [(UNSPEC_SIN "sin")
14743 (UNSPEC_COS "cos")])
14745 (define_insn "*<sincos>xf2_i387"
14746 [(set (match_operand:XF 0 "register_operand" "=f")
14747 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14749 "TARGET_USE_FANCY_MATH_387
14750 && flag_unsafe_math_optimizations"
14752 [(set_attr "type" "fpspc")
14753 (set_attr "znver1_decode" "vector")
14754 (set_attr "mode" "XF")])
14756 (define_insn "*<sincos>_extend<mode>xf2_i387"
14757 [(set (match_operand:XF 0 "register_operand" "=f")
14758 (unspec:XF [(float_extend:XF
14759 (match_operand:MODEF 1 "register_operand" "0"))]
14761 "TARGET_USE_FANCY_MATH_387
14762 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14763 || TARGET_MIX_SSE_I387)
14764 && flag_unsafe_math_optimizations"
14766 [(set_attr "type" "fpspc")
14767 (set_attr "znver1_decode" "vector")
14768 (set_attr "mode" "XF")])
14770 ;; When sincos pattern is defined, sin and cos builtin functions will be
14771 ;; expanded to sincos pattern with one of its outputs left unused.
14772 ;; CSE pass will figure out if two sincos patterns can be combined,
14773 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14774 ;; depending on the unused output.
14776 (define_insn "sincosxf3"
14777 [(set (match_operand:XF 0 "register_operand" "=f")
14778 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14779 UNSPEC_SINCOS_COS))
14780 (set (match_operand:XF 1 "register_operand" "=u")
14781 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14782 "TARGET_USE_FANCY_MATH_387
14783 && flag_unsafe_math_optimizations"
14785 [(set_attr "type" "fpspc")
14786 (set_attr "znver1_decode" "vector")
14787 (set_attr "mode" "XF")])
14790 [(set (match_operand:XF 0 "register_operand")
14791 (unspec:XF [(match_operand:XF 2 "register_operand")]
14792 UNSPEC_SINCOS_COS))
14793 (set (match_operand:XF 1 "register_operand")
14794 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14795 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14796 && can_create_pseudo_p ()"
14797 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14800 [(set (match_operand:XF 0 "register_operand")
14801 (unspec:XF [(match_operand:XF 2 "register_operand")]
14802 UNSPEC_SINCOS_COS))
14803 (set (match_operand:XF 1 "register_operand")
14804 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14805 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14806 && can_create_pseudo_p ()"
14807 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14809 (define_insn "sincos_extend<mode>xf3_i387"
14810 [(set (match_operand:XF 0 "register_operand" "=f")
14811 (unspec:XF [(float_extend:XF
14812 (match_operand:MODEF 2 "register_operand" "0"))]
14813 UNSPEC_SINCOS_COS))
14814 (set (match_operand:XF 1 "register_operand" "=u")
14815 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14816 "TARGET_USE_FANCY_MATH_387
14817 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14818 || TARGET_MIX_SSE_I387)
14819 && flag_unsafe_math_optimizations"
14821 [(set_attr "type" "fpspc")
14822 (set_attr "znver1_decode" "vector")
14823 (set_attr "mode" "XF")])
14826 [(set (match_operand:XF 0 "register_operand")
14827 (unspec:XF [(float_extend:XF
14828 (match_operand:MODEF 2 "register_operand"))]
14829 UNSPEC_SINCOS_COS))
14830 (set (match_operand:XF 1 "register_operand")
14831 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14832 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14833 && can_create_pseudo_p ()"
14834 [(set (match_dup 1)
14835 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14838 [(set (match_operand:XF 0 "register_operand")
14839 (unspec:XF [(float_extend:XF
14840 (match_operand:MODEF 2 "register_operand"))]
14841 UNSPEC_SINCOS_COS))
14842 (set (match_operand:XF 1 "register_operand")
14843 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14844 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14845 && can_create_pseudo_p ()"
14846 [(set (match_dup 0)
14847 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14849 (define_expand "sincos<mode>3"
14850 [(use (match_operand:MODEF 0 "register_operand"))
14851 (use (match_operand:MODEF 1 "register_operand"))
14852 (use (match_operand:MODEF 2 "register_operand"))]
14853 "TARGET_USE_FANCY_MATH_387
14854 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14855 || TARGET_MIX_SSE_I387)
14856 && flag_unsafe_math_optimizations"
14858 rtx op0 = gen_reg_rtx (XFmode);
14859 rtx op1 = gen_reg_rtx (XFmode);
14861 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14862 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14863 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14867 (define_insn "fptanxf4_i387"
14868 [(set (match_operand:XF 0 "register_operand" "=f")
14869 (match_operand:XF 3 "const_double_operand" "F"))
14870 (set (match_operand:XF 1 "register_operand" "=u")
14871 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14873 "TARGET_USE_FANCY_MATH_387
14874 && flag_unsafe_math_optimizations
14875 && standard_80387_constant_p (operands[3]) == 2"
14877 [(set_attr "type" "fpspc")
14878 (set_attr "znver1_decode" "vector")
14879 (set_attr "mode" "XF")])
14881 (define_insn "fptan_extend<mode>xf4_i387"
14882 [(set (match_operand:MODEF 0 "register_operand" "=f")
14883 (match_operand:MODEF 3 "const_double_operand" "F"))
14884 (set (match_operand:XF 1 "register_operand" "=u")
14885 (unspec:XF [(float_extend:XF
14886 (match_operand:MODEF 2 "register_operand" "0"))]
14888 "TARGET_USE_FANCY_MATH_387
14889 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14890 || TARGET_MIX_SSE_I387)
14891 && flag_unsafe_math_optimizations
14892 && standard_80387_constant_p (operands[3]) == 2"
14894 [(set_attr "type" "fpspc")
14895 (set_attr "znver1_decode" "vector")
14896 (set_attr "mode" "XF")])
14898 (define_expand "tanxf2"
14899 [(use (match_operand:XF 0 "register_operand"))
14900 (use (match_operand:XF 1 "register_operand"))]
14901 "TARGET_USE_FANCY_MATH_387
14902 && flag_unsafe_math_optimizations"
14904 rtx one = gen_reg_rtx (XFmode);
14905 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14907 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14911 (define_expand "tan<mode>2"
14912 [(use (match_operand:MODEF 0 "register_operand"))
14913 (use (match_operand:MODEF 1 "register_operand"))]
14914 "TARGET_USE_FANCY_MATH_387
14915 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14916 || TARGET_MIX_SSE_I387)
14917 && flag_unsafe_math_optimizations"
14919 rtx op0 = gen_reg_rtx (XFmode);
14921 rtx one = gen_reg_rtx (<MODE>mode);
14922 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14924 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14925 operands[1], op2));
14926 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14930 (define_insn "*fpatanxf3_i387"
14931 [(set (match_operand:XF 0 "register_operand" "=f")
14932 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14933 (match_operand:XF 2 "register_operand" "u")]
14935 (clobber (match_scratch:XF 3 "=2"))]
14936 "TARGET_USE_FANCY_MATH_387
14937 && flag_unsafe_math_optimizations"
14939 [(set_attr "type" "fpspc")
14940 (set_attr "znver1_decode" "vector")
14941 (set_attr "mode" "XF")])
14943 (define_insn "fpatan_extend<mode>xf3_i387"
14944 [(set (match_operand:XF 0 "register_operand" "=f")
14945 (unspec:XF [(float_extend:XF
14946 (match_operand:MODEF 1 "register_operand" "0"))
14948 (match_operand:MODEF 2 "register_operand" "u"))]
14950 (clobber (match_scratch:XF 3 "=2"))]
14951 "TARGET_USE_FANCY_MATH_387
14952 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14953 || TARGET_MIX_SSE_I387)
14954 && flag_unsafe_math_optimizations"
14956 [(set_attr "type" "fpspc")
14957 (set_attr "znver1_decode" "vector")
14958 (set_attr "mode" "XF")])
14960 (define_expand "atan2xf3"
14961 [(parallel [(set (match_operand:XF 0 "register_operand")
14962 (unspec:XF [(match_operand:XF 2 "register_operand")
14963 (match_operand:XF 1 "register_operand")]
14965 (clobber (match_scratch:XF 3))])]
14966 "TARGET_USE_FANCY_MATH_387
14967 && flag_unsafe_math_optimizations")
14969 (define_expand "atan2<mode>3"
14970 [(use (match_operand:MODEF 0 "register_operand"))
14971 (use (match_operand:MODEF 1 "register_operand"))
14972 (use (match_operand:MODEF 2 "register_operand"))]
14973 "TARGET_USE_FANCY_MATH_387
14974 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14975 || TARGET_MIX_SSE_I387)
14976 && flag_unsafe_math_optimizations"
14978 rtx op0 = gen_reg_rtx (XFmode);
14980 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14981 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14985 (define_expand "atanxf2"
14986 [(parallel [(set (match_operand:XF 0 "register_operand")
14987 (unspec:XF [(match_dup 2)
14988 (match_operand:XF 1 "register_operand")]
14990 (clobber (match_scratch:XF 3))])]
14991 "TARGET_USE_FANCY_MATH_387
14992 && flag_unsafe_math_optimizations"
14994 operands[2] = gen_reg_rtx (XFmode);
14995 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14998 (define_expand "atan<mode>2"
14999 [(use (match_operand:MODEF 0 "register_operand"))
15000 (use (match_operand:MODEF 1 "register_operand"))]
15001 "TARGET_USE_FANCY_MATH_387
15002 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15003 || TARGET_MIX_SSE_I387)
15004 && flag_unsafe_math_optimizations"
15006 rtx op0 = gen_reg_rtx (XFmode);
15008 rtx op2 = gen_reg_rtx (<MODE>mode);
15009 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
15011 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
15012 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15016 (define_expand "asinxf2"
15017 [(set (match_dup 2)
15018 (mult:XF (match_operand:XF 1 "register_operand")
15020 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15021 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15022 (parallel [(set (match_operand:XF 0 "register_operand")
15023 (unspec:XF [(match_dup 5) (match_dup 1)]
15025 (clobber (match_scratch:XF 6))])]
15026 "TARGET_USE_FANCY_MATH_387
15027 && flag_unsafe_math_optimizations"
15031 for (i = 2; i < 6; i++)
15032 operands[i] = gen_reg_rtx (XFmode);
15034 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15037 (define_expand "asin<mode>2"
15038 [(use (match_operand:MODEF 0 "register_operand"))
15039 (use (match_operand:MODEF 1 "general_operand"))]
15040 "TARGET_USE_FANCY_MATH_387
15041 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15042 || TARGET_MIX_SSE_I387)
15043 && flag_unsafe_math_optimizations"
15045 rtx op0 = gen_reg_rtx (XFmode);
15046 rtx op1 = gen_reg_rtx (XFmode);
15048 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15049 emit_insn (gen_asinxf2 (op0, op1));
15050 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15054 (define_expand "acosxf2"
15055 [(set (match_dup 2)
15056 (mult:XF (match_operand:XF 1 "register_operand")
15058 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15059 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15060 (parallel [(set (match_operand:XF 0 "register_operand")
15061 (unspec:XF [(match_dup 1) (match_dup 5)]
15063 (clobber (match_scratch:XF 6))])]
15064 "TARGET_USE_FANCY_MATH_387
15065 && flag_unsafe_math_optimizations"
15069 for (i = 2; i < 6; i++)
15070 operands[i] = gen_reg_rtx (XFmode);
15072 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15075 (define_expand "acos<mode>2"
15076 [(use (match_operand:MODEF 0 "register_operand"))
15077 (use (match_operand:MODEF 1 "general_operand"))]
15078 "TARGET_USE_FANCY_MATH_387
15079 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15080 || TARGET_MIX_SSE_I387)
15081 && flag_unsafe_math_optimizations"
15083 rtx op0 = gen_reg_rtx (XFmode);
15084 rtx op1 = gen_reg_rtx (XFmode);
15086 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15087 emit_insn (gen_acosxf2 (op0, op1));
15088 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15092 (define_insn "fyl2xxf3_i387"
15093 [(set (match_operand:XF 0 "register_operand" "=f")
15094 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15095 (match_operand:XF 2 "register_operand" "u")]
15097 (clobber (match_scratch:XF 3 "=2"))]
15098 "TARGET_USE_FANCY_MATH_387
15099 && flag_unsafe_math_optimizations"
15101 [(set_attr "type" "fpspc")
15102 (set_attr "znver1_decode" "vector")
15103 (set_attr "mode" "XF")])
15105 (define_insn "fyl2x_extend<mode>xf3_i387"
15106 [(set (match_operand:XF 0 "register_operand" "=f")
15107 (unspec:XF [(float_extend:XF
15108 (match_operand:MODEF 1 "register_operand" "0"))
15109 (match_operand:XF 2 "register_operand" "u")]
15111 (clobber (match_scratch:XF 3 "=2"))]
15112 "TARGET_USE_FANCY_MATH_387
15113 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15114 || TARGET_MIX_SSE_I387)
15115 && flag_unsafe_math_optimizations"
15117 [(set_attr "type" "fpspc")
15118 (set_attr "znver1_decode" "vector")
15119 (set_attr "mode" "XF")])
15121 (define_expand "logxf2"
15122 [(parallel [(set (match_operand:XF 0 "register_operand")
15123 (unspec:XF [(match_operand:XF 1 "register_operand")
15124 (match_dup 2)] UNSPEC_FYL2X))
15125 (clobber (match_scratch:XF 3))])]
15126 "TARGET_USE_FANCY_MATH_387
15127 && flag_unsafe_math_optimizations"
15129 operands[2] = gen_reg_rtx (XFmode);
15130 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
15133 (define_expand "log<mode>2"
15134 [(use (match_operand:MODEF 0 "register_operand"))
15135 (use (match_operand:MODEF 1 "register_operand"))]
15136 "TARGET_USE_FANCY_MATH_387
15137 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15138 || TARGET_MIX_SSE_I387)
15139 && flag_unsafe_math_optimizations"
15141 rtx op0 = gen_reg_rtx (XFmode);
15143 rtx op2 = gen_reg_rtx (XFmode);
15144 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
15146 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15147 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15151 (define_expand "log10xf2"
15152 [(parallel [(set (match_operand:XF 0 "register_operand")
15153 (unspec:XF [(match_operand:XF 1 "register_operand")
15154 (match_dup 2)] UNSPEC_FYL2X))
15155 (clobber (match_scratch:XF 3))])]
15156 "TARGET_USE_FANCY_MATH_387
15157 && flag_unsafe_math_optimizations"
15159 operands[2] = gen_reg_rtx (XFmode);
15160 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
15163 (define_expand "log10<mode>2"
15164 [(use (match_operand:MODEF 0 "register_operand"))
15165 (use (match_operand:MODEF 1 "register_operand"))]
15166 "TARGET_USE_FANCY_MATH_387
15167 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15168 || TARGET_MIX_SSE_I387)
15169 && flag_unsafe_math_optimizations"
15171 rtx op0 = gen_reg_rtx (XFmode);
15173 rtx op2 = gen_reg_rtx (XFmode);
15174 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
15176 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15177 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15181 (define_expand "log2xf2"
15182 [(parallel [(set (match_operand:XF 0 "register_operand")
15183 (unspec:XF [(match_operand:XF 1 "register_operand")
15184 (match_dup 2)] UNSPEC_FYL2X))
15185 (clobber (match_scratch:XF 3))])]
15186 "TARGET_USE_FANCY_MATH_387
15187 && flag_unsafe_math_optimizations"
15189 operands[2] = gen_reg_rtx (XFmode);
15190 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15193 (define_expand "log2<mode>2"
15194 [(use (match_operand:MODEF 0 "register_operand"))
15195 (use (match_operand:MODEF 1 "register_operand"))]
15196 "TARGET_USE_FANCY_MATH_387
15197 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15198 || TARGET_MIX_SSE_I387)
15199 && flag_unsafe_math_optimizations"
15201 rtx op0 = gen_reg_rtx (XFmode);
15203 rtx op2 = gen_reg_rtx (XFmode);
15204 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15206 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15207 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15211 (define_insn "fyl2xp1xf3_i387"
15212 [(set (match_operand:XF 0 "register_operand" "=f")
15213 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15214 (match_operand:XF 2 "register_operand" "u")]
15216 (clobber (match_scratch:XF 3 "=2"))]
15217 "TARGET_USE_FANCY_MATH_387
15218 && flag_unsafe_math_optimizations"
15220 [(set_attr "type" "fpspc")
15221 (set_attr "znver1_decode" "vector")
15222 (set_attr "mode" "XF")])
15224 (define_insn "fyl2xp1_extend<mode>xf3_i387"
15225 [(set (match_operand:XF 0 "register_operand" "=f")
15226 (unspec:XF [(float_extend:XF
15227 (match_operand:MODEF 1 "register_operand" "0"))
15228 (match_operand:XF 2 "register_operand" "u")]
15230 (clobber (match_scratch:XF 3 "=2"))]
15231 "TARGET_USE_FANCY_MATH_387
15232 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15233 || TARGET_MIX_SSE_I387)
15234 && flag_unsafe_math_optimizations"
15236 [(set_attr "type" "fpspc")
15237 (set_attr "znver1_decode" "vector")
15238 (set_attr "mode" "XF")])
15240 (define_expand "log1pxf2"
15241 [(use (match_operand:XF 0 "register_operand"))
15242 (use (match_operand:XF 1 "register_operand"))]
15243 "TARGET_USE_FANCY_MATH_387
15244 && flag_unsafe_math_optimizations"
15246 ix86_emit_i387_log1p (operands[0], operands[1]);
15250 (define_expand "log1p<mode>2"
15251 [(use (match_operand:MODEF 0 "register_operand"))
15252 (use (match_operand:MODEF 1 "register_operand"))]
15253 "TARGET_USE_FANCY_MATH_387
15254 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15255 || TARGET_MIX_SSE_I387)
15256 && flag_unsafe_math_optimizations"
15260 op0 = gen_reg_rtx (XFmode);
15262 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
15264 ix86_emit_i387_log1p (op0, operands[1]);
15265 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15269 (define_insn "fxtractxf3_i387"
15270 [(set (match_operand:XF 0 "register_operand" "=f")
15271 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15272 UNSPEC_XTRACT_FRACT))
15273 (set (match_operand:XF 1 "register_operand" "=u")
15274 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15275 "TARGET_USE_FANCY_MATH_387
15276 && flag_unsafe_math_optimizations"
15278 [(set_attr "type" "fpspc")
15279 (set_attr "znver1_decode" "vector")
15280 (set_attr "mode" "XF")])
15282 (define_insn "fxtract_extend<mode>xf3_i387"
15283 [(set (match_operand:XF 0 "register_operand" "=f")
15284 (unspec:XF [(float_extend:XF
15285 (match_operand:MODEF 2 "register_operand" "0"))]
15286 UNSPEC_XTRACT_FRACT))
15287 (set (match_operand:XF 1 "register_operand" "=u")
15288 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
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"
15294 [(set_attr "type" "fpspc")
15295 (set_attr "znver1_decode" "vector")
15296 (set_attr "mode" "XF")])
15298 (define_expand "logbxf2"
15299 [(parallel [(set (match_dup 2)
15300 (unspec:XF [(match_operand:XF 1 "register_operand")]
15301 UNSPEC_XTRACT_FRACT))
15302 (set (match_operand:XF 0 "register_operand")
15303 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15304 "TARGET_USE_FANCY_MATH_387
15305 && flag_unsafe_math_optimizations"
15306 "operands[2] = gen_reg_rtx (XFmode);")
15308 (define_expand "logb<mode>2"
15309 [(use (match_operand:MODEF 0 "register_operand"))
15310 (use (match_operand:MODEF 1 "register_operand"))]
15311 "TARGET_USE_FANCY_MATH_387
15312 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15313 || TARGET_MIX_SSE_I387)
15314 && flag_unsafe_math_optimizations"
15316 rtx op0 = gen_reg_rtx (XFmode);
15317 rtx op1 = gen_reg_rtx (XFmode);
15319 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15320 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
15324 (define_expand "ilogbxf2"
15325 [(use (match_operand:SI 0 "register_operand"))
15326 (use (match_operand:XF 1 "register_operand"))]
15327 "TARGET_USE_FANCY_MATH_387
15328 && flag_unsafe_math_optimizations"
15332 if (optimize_insn_for_size_p ())
15335 op0 = gen_reg_rtx (XFmode);
15336 op1 = gen_reg_rtx (XFmode);
15338 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
15339 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15343 (define_expand "ilogb<mode>2"
15344 [(use (match_operand:SI 0 "register_operand"))
15345 (use (match_operand:MODEF 1 "register_operand"))]
15346 "TARGET_USE_FANCY_MATH_387
15347 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15348 || TARGET_MIX_SSE_I387)
15349 && flag_unsafe_math_optimizations"
15353 if (optimize_insn_for_size_p ())
15356 op0 = gen_reg_rtx (XFmode);
15357 op1 = gen_reg_rtx (XFmode);
15359 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15360 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15364 (define_insn "*f2xm1xf2_i387"
15365 [(set (match_operand:XF 0 "register_operand" "=f")
15366 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15368 "TARGET_USE_FANCY_MATH_387
15369 && flag_unsafe_math_optimizations"
15371 [(set_attr "type" "fpspc")
15372 (set_attr "znver1_decode" "vector")
15373 (set_attr "mode" "XF")])
15375 (define_insn "fscalexf4_i387"
15376 [(set (match_operand:XF 0 "register_operand" "=f")
15377 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15378 (match_operand:XF 3 "register_operand" "1")]
15379 UNSPEC_FSCALE_FRACT))
15380 (set (match_operand:XF 1 "register_operand" "=u")
15381 (unspec:XF [(match_dup 2) (match_dup 3)]
15382 UNSPEC_FSCALE_EXP))]
15383 "TARGET_USE_FANCY_MATH_387
15384 && flag_unsafe_math_optimizations"
15386 [(set_attr "type" "fpspc")
15387 (set_attr "znver1_decode" "vector")
15388 (set_attr "mode" "XF")])
15390 (define_expand "expNcorexf3"
15391 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15392 (match_operand:XF 2 "register_operand")))
15393 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15394 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15395 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15396 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15397 (parallel [(set (match_operand:XF 0 "register_operand")
15398 (unspec:XF [(match_dup 8) (match_dup 4)]
15399 UNSPEC_FSCALE_FRACT))
15401 (unspec:XF [(match_dup 8) (match_dup 4)]
15402 UNSPEC_FSCALE_EXP))])]
15403 "TARGET_USE_FANCY_MATH_387
15404 && flag_unsafe_math_optimizations"
15408 for (i = 3; i < 10; i++)
15409 operands[i] = gen_reg_rtx (XFmode);
15411 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15414 (define_expand "expxf2"
15415 [(use (match_operand:XF 0 "register_operand"))
15416 (use (match_operand:XF 1 "register_operand"))]
15417 "TARGET_USE_FANCY_MATH_387
15418 && flag_unsafe_math_optimizations"
15422 op2 = gen_reg_rtx (XFmode);
15423 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
15425 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15429 (define_expand "exp<mode>2"
15430 [(use (match_operand:MODEF 0 "register_operand"))
15431 (use (match_operand:MODEF 1 "general_operand"))]
15432 "TARGET_USE_FANCY_MATH_387
15433 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15434 || TARGET_MIX_SSE_I387)
15435 && flag_unsafe_math_optimizations"
15439 op0 = gen_reg_rtx (XFmode);
15440 op1 = gen_reg_rtx (XFmode);
15442 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15443 emit_insn (gen_expxf2 (op0, op1));
15444 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15448 (define_expand "exp10xf2"
15449 [(use (match_operand:XF 0 "register_operand"))
15450 (use (match_operand:XF 1 "register_operand"))]
15451 "TARGET_USE_FANCY_MATH_387
15452 && flag_unsafe_math_optimizations"
15456 op2 = gen_reg_rtx (XFmode);
15457 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
15459 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15463 (define_expand "exp10<mode>2"
15464 [(use (match_operand:MODEF 0 "register_operand"))
15465 (use (match_operand:MODEF 1 "general_operand"))]
15466 "TARGET_USE_FANCY_MATH_387
15467 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15468 || TARGET_MIX_SSE_I387)
15469 && flag_unsafe_math_optimizations"
15473 op0 = gen_reg_rtx (XFmode);
15474 op1 = gen_reg_rtx (XFmode);
15476 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15477 emit_insn (gen_exp10xf2 (op0, op1));
15478 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15482 (define_expand "exp2xf2"
15483 [(use (match_operand:XF 0 "register_operand"))
15484 (use (match_operand:XF 1 "register_operand"))]
15485 "TARGET_USE_FANCY_MATH_387
15486 && flag_unsafe_math_optimizations"
15490 op2 = gen_reg_rtx (XFmode);
15491 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15493 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15497 (define_expand "exp2<mode>2"
15498 [(use (match_operand:MODEF 0 "register_operand"))
15499 (use (match_operand:MODEF 1 "general_operand"))]
15500 "TARGET_USE_FANCY_MATH_387
15501 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15502 || TARGET_MIX_SSE_I387)
15503 && flag_unsafe_math_optimizations"
15507 op0 = gen_reg_rtx (XFmode);
15508 op1 = gen_reg_rtx (XFmode);
15510 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15511 emit_insn (gen_exp2xf2 (op0, op1));
15512 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15516 (define_expand "expm1xf2"
15517 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15519 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15520 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15521 (set (match_dup 9) (float_extend:XF (match_dup 13)))
15522 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15523 (parallel [(set (match_dup 7)
15524 (unspec:XF [(match_dup 6) (match_dup 4)]
15525 UNSPEC_FSCALE_FRACT))
15527 (unspec:XF [(match_dup 6) (match_dup 4)]
15528 UNSPEC_FSCALE_EXP))])
15529 (parallel [(set (match_dup 10)
15530 (unspec:XF [(match_dup 9) (match_dup 8)]
15531 UNSPEC_FSCALE_FRACT))
15532 (set (match_dup 11)
15533 (unspec:XF [(match_dup 9) (match_dup 8)]
15534 UNSPEC_FSCALE_EXP))])
15535 (set (match_dup 12) (minus:XF (match_dup 10)
15536 (float_extend:XF (match_dup 13))))
15537 (set (match_operand:XF 0 "register_operand")
15538 (plus:XF (match_dup 12) (match_dup 7)))]
15539 "TARGET_USE_FANCY_MATH_387
15540 && flag_unsafe_math_optimizations"
15544 for (i = 2; i < 13; i++)
15545 operands[i] = gen_reg_rtx (XFmode);
15548 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
15550 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
15553 (define_expand "expm1<mode>2"
15554 [(use (match_operand:MODEF 0 "register_operand"))
15555 (use (match_operand:MODEF 1 "general_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"
15563 op0 = gen_reg_rtx (XFmode);
15564 op1 = gen_reg_rtx (XFmode);
15566 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15567 emit_insn (gen_expm1xf2 (op0, op1));
15568 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15572 (define_expand "ldexpxf3"
15573 [(match_operand:XF 0 "register_operand")
15574 (match_operand:XF 1 "register_operand")
15575 (match_operand:SI 2 "register_operand")]
15576 "TARGET_USE_FANCY_MATH_387
15577 && flag_unsafe_math_optimizations"
15581 tmp1 = gen_reg_rtx (XFmode);
15582 tmp2 = gen_reg_rtx (XFmode);
15584 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
15585 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
15586 operands[1], tmp1));
15590 (define_expand "ldexp<mode>3"
15591 [(use (match_operand:MODEF 0 "register_operand"))
15592 (use (match_operand:MODEF 1 "general_operand"))
15593 (use (match_operand:SI 2 "register_operand"))]
15594 "TARGET_USE_FANCY_MATH_387
15595 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15596 || TARGET_MIX_SSE_I387)
15597 && flag_unsafe_math_optimizations"
15601 op0 = gen_reg_rtx (XFmode);
15602 op1 = gen_reg_rtx (XFmode);
15604 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15605 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15606 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15610 (define_expand "scalbxf3"
15611 [(parallel [(set (match_operand:XF 0 " register_operand")
15612 (unspec:XF [(match_operand:XF 1 "register_operand")
15613 (match_operand:XF 2 "register_operand")]
15614 UNSPEC_FSCALE_FRACT))
15616 (unspec:XF [(match_dup 1) (match_dup 2)]
15617 UNSPEC_FSCALE_EXP))])]
15618 "TARGET_USE_FANCY_MATH_387
15619 && flag_unsafe_math_optimizations"
15621 operands[3] = gen_reg_rtx (XFmode);
15624 (define_expand "scalb<mode>3"
15625 [(use (match_operand:MODEF 0 "register_operand"))
15626 (use (match_operand:MODEF 1 "general_operand"))
15627 (use (match_operand:MODEF 2 "general_operand"))]
15628 "TARGET_USE_FANCY_MATH_387
15629 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15630 || TARGET_MIX_SSE_I387)
15631 && flag_unsafe_math_optimizations"
15635 op0 = gen_reg_rtx (XFmode);
15636 op1 = gen_reg_rtx (XFmode);
15637 op2 = gen_reg_rtx (XFmode);
15639 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15640 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15641 emit_insn (gen_scalbxf3 (op0, op1, op2));
15642 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15646 (define_expand "significandxf2"
15647 [(parallel [(set (match_operand:XF 0 "register_operand")
15648 (unspec:XF [(match_operand:XF 1 "register_operand")]
15649 UNSPEC_XTRACT_FRACT))
15651 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15652 "TARGET_USE_FANCY_MATH_387
15653 && flag_unsafe_math_optimizations"
15654 "operands[2] = gen_reg_rtx (XFmode);")
15656 (define_expand "significand<mode>2"
15657 [(use (match_operand:MODEF 0 "register_operand"))
15658 (use (match_operand:MODEF 1 "register_operand"))]
15659 "TARGET_USE_FANCY_MATH_387
15660 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15661 || TARGET_MIX_SSE_I387)
15662 && flag_unsafe_math_optimizations"
15664 rtx op0 = gen_reg_rtx (XFmode);
15665 rtx op1 = gen_reg_rtx (XFmode);
15667 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15668 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15673 (define_insn "sse4_1_round<mode>2"
15674 [(set (match_operand:MODEF 0 "register_operand" "=x")
15675 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
15676 (match_operand:SI 2 "const_0_to_15_operand" "n")]
15679 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15680 [(set_attr "type" "ssecvt")
15681 (set_attr "prefix_extra" "1")
15682 (set_attr "prefix" "maybe_vex")
15683 (set_attr "mode" "<MODE>")])
15685 (define_insn "rintxf2"
15686 [(set (match_operand:XF 0 "register_operand" "=f")
15687 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15689 "TARGET_USE_FANCY_MATH_387
15690 && flag_unsafe_math_optimizations"
15692 [(set_attr "type" "fpspc")
15693 (set_attr "znver1_decode" "vector")
15694 (set_attr "mode" "XF")])
15696 (define_expand "rint<mode>2"
15697 [(use (match_operand:MODEF 0 "register_operand"))
15698 (use (match_operand:MODEF 1 "register_operand"))]
15699 "(TARGET_USE_FANCY_MATH_387
15700 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15701 || TARGET_MIX_SSE_I387)
15702 && flag_unsafe_math_optimizations)
15703 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15704 && !flag_trapping_math)"
15706 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15707 && !flag_trapping_math)
15710 emit_insn (gen_sse4_1_round<mode>2
15711 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
15713 ix86_expand_rint (operands[0], operands[1]);
15717 rtx op0 = gen_reg_rtx (XFmode);
15718 rtx op1 = gen_reg_rtx (XFmode);
15720 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15721 emit_insn (gen_rintxf2 (op0, op1));
15723 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15728 (define_expand "round<mode>2"
15729 [(match_operand:X87MODEF 0 "register_operand")
15730 (match_operand:X87MODEF 1 "nonimmediate_operand")]
15731 "(TARGET_USE_FANCY_MATH_387
15732 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15733 || TARGET_MIX_SSE_I387)
15734 && flag_unsafe_math_optimizations)
15735 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15736 && !flag_trapping_math && !flag_rounding_math)"
15738 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15739 && !flag_trapping_math && !flag_rounding_math)
15743 operands[1] = force_reg (<MODE>mode, operands[1]);
15744 ix86_expand_round_sse4 (operands[0], operands[1]);
15746 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15747 ix86_expand_round (operands[0], operands[1]);
15749 ix86_expand_rounddf_32 (operands[0], operands[1]);
15753 operands[1] = force_reg (<MODE>mode, operands[1]);
15754 ix86_emit_i387_round (operands[0], operands[1]);
15759 (define_insn_and_split "*fistdi2_1"
15760 [(set (match_operand:DI 0 "nonimmediate_operand")
15761 (unspec:DI [(match_operand:XF 1 "register_operand")]
15763 "TARGET_USE_FANCY_MATH_387
15764 && can_create_pseudo_p ()"
15769 if (memory_operand (operands[0], VOIDmode))
15770 emit_insn (gen_fistdi2 (operands[0], operands[1]));
15773 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15774 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15779 [(set_attr "type" "fpspc")
15780 (set_attr "mode" "DI")])
15782 (define_insn "fistdi2"
15783 [(set (match_operand:DI 0 "memory_operand" "=m")
15784 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15786 (clobber (match_scratch:XF 2 "=&1f"))]
15787 "TARGET_USE_FANCY_MATH_387"
15788 "* return output_fix_trunc (insn, operands, false);"
15789 [(set_attr "type" "fpspc")
15790 (set_attr "mode" "DI")])
15792 (define_insn "fistdi2_with_temp"
15793 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15794 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15796 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15797 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15798 "TARGET_USE_FANCY_MATH_387"
15800 [(set_attr "type" "fpspc")
15801 (set_attr "mode" "DI")])
15804 [(set (match_operand:DI 0 "register_operand")
15805 (unspec:DI [(match_operand:XF 1 "register_operand")]
15807 (clobber (match_operand:DI 2 "memory_operand"))
15808 (clobber (match_scratch 3))]
15810 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15811 (clobber (match_dup 3))])
15812 (set (match_dup 0) (match_dup 2))])
15815 [(set (match_operand:DI 0 "memory_operand")
15816 (unspec:DI [(match_operand:XF 1 "register_operand")]
15818 (clobber (match_operand:DI 2 "memory_operand"))
15819 (clobber (match_scratch 3))]
15821 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15822 (clobber (match_dup 3))])])
15824 (define_insn_and_split "*fist<mode>2_1"
15825 [(set (match_operand:SWI24 0 "register_operand")
15826 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15828 "TARGET_USE_FANCY_MATH_387
15829 && can_create_pseudo_p ()"
15834 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15835 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15839 [(set_attr "type" "fpspc")
15840 (set_attr "mode" "<MODE>")])
15842 (define_insn "fist<mode>2"
15843 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15844 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15846 "TARGET_USE_FANCY_MATH_387"
15847 "* return output_fix_trunc (insn, operands, false);"
15848 [(set_attr "type" "fpspc")
15849 (set_attr "mode" "<MODE>")])
15851 (define_insn "fist<mode>2_with_temp"
15852 [(set (match_operand:SWI24 0 "register_operand" "=r")
15853 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15855 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15856 "TARGET_USE_FANCY_MATH_387"
15858 [(set_attr "type" "fpspc")
15859 (set_attr "mode" "<MODE>")])
15862 [(set (match_operand:SWI24 0 "register_operand")
15863 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15865 (clobber (match_operand:SWI24 2 "memory_operand"))]
15867 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15868 (set (match_dup 0) (match_dup 2))])
15871 [(set (match_operand:SWI24 0 "memory_operand")
15872 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15874 (clobber (match_operand:SWI24 2 "memory_operand"))]
15876 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15878 (define_expand "lrintxf<mode>2"
15879 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15880 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15882 "TARGET_USE_FANCY_MATH_387")
15884 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15885 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15886 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15887 UNSPEC_FIX_NOTRUNC))]
15888 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15890 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15891 [(match_operand:SWI248x 0 "nonimmediate_operand")
15892 (match_operand:X87MODEF 1 "register_operand")]
15893 "(TARGET_USE_FANCY_MATH_387
15894 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15895 || TARGET_MIX_SSE_I387)
15896 && flag_unsafe_math_optimizations)
15897 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15898 && <SWI248x:MODE>mode != HImode
15899 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15900 && !flag_trapping_math && !flag_rounding_math)"
15902 if (optimize_insn_for_size_p ())
15905 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15906 && <SWI248x:MODE>mode != HImode
15907 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15908 && !flag_trapping_math && !flag_rounding_math)
15909 ix86_expand_lround (operands[0], operands[1]);
15911 ix86_emit_i387_round (operands[0], operands[1]);
15915 (define_int_iterator FRNDINT_ROUNDING
15916 [UNSPEC_FRNDINT_FLOOR
15917 UNSPEC_FRNDINT_CEIL
15918 UNSPEC_FRNDINT_TRUNC])
15920 (define_int_iterator FIST_ROUNDING
15924 ;; Base name for define_insn
15925 (define_int_attr rounding_insn
15926 [(UNSPEC_FRNDINT_FLOOR "floor")
15927 (UNSPEC_FRNDINT_CEIL "ceil")
15928 (UNSPEC_FRNDINT_TRUNC "btrunc")
15929 (UNSPEC_FIST_FLOOR "floor")
15930 (UNSPEC_FIST_CEIL "ceil")])
15932 (define_int_attr rounding
15933 [(UNSPEC_FRNDINT_FLOOR "floor")
15934 (UNSPEC_FRNDINT_CEIL "ceil")
15935 (UNSPEC_FRNDINT_TRUNC "trunc")
15936 (UNSPEC_FIST_FLOOR "floor")
15937 (UNSPEC_FIST_CEIL "ceil")])
15939 (define_int_attr ROUNDING
15940 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15941 (UNSPEC_FRNDINT_CEIL "CEIL")
15942 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15943 (UNSPEC_FIST_FLOOR "FLOOR")
15944 (UNSPEC_FIST_CEIL "CEIL")])
15946 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15947 (define_insn_and_split "frndintxf2_<rounding>"
15948 [(set (match_operand:XF 0 "register_operand")
15949 (unspec:XF [(match_operand:XF 1 "register_operand")]
15951 (clobber (reg:CC FLAGS_REG))]
15952 "TARGET_USE_FANCY_MATH_387
15953 && flag_unsafe_math_optimizations
15954 && can_create_pseudo_p ()"
15959 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15961 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15962 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15964 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15965 operands[2], operands[3]));
15968 [(set_attr "type" "frndint")
15969 (set_attr "i387_cw" "<rounding>")
15970 (set_attr "mode" "XF")])
15972 (define_insn "frndintxf2_<rounding>_i387"
15973 [(set (match_operand:XF 0 "register_operand" "=f")
15974 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15976 (use (match_operand:HI 2 "memory_operand" "m"))
15977 (use (match_operand:HI 3 "memory_operand" "m"))]
15978 "TARGET_USE_FANCY_MATH_387
15979 && flag_unsafe_math_optimizations"
15980 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15981 [(set_attr "type" "frndint")
15982 (set_attr "i387_cw" "<rounding>")
15983 (set_attr "mode" "XF")])
15985 (define_expand "<rounding_insn>xf2"
15986 [(parallel [(set (match_operand:XF 0 "register_operand")
15987 (unspec:XF [(match_operand:XF 1 "register_operand")]
15989 (clobber (reg:CC FLAGS_REG))])]
15990 "TARGET_USE_FANCY_MATH_387
15991 && flag_unsafe_math_optimizations")
15993 (define_expand "<rounding_insn><mode>2"
15994 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15995 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15997 (clobber (reg:CC FLAGS_REG))])]
15998 "(TARGET_USE_FANCY_MATH_387
15999 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16000 || TARGET_MIX_SSE_I387)
16001 && flag_unsafe_math_optimizations)
16002 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16003 && !flag_trapping_math)"
16005 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16006 && !flag_trapping_math)
16009 emit_insn (gen_sse4_1_round<mode>2
16010 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
16011 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16013 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16014 ix86_expand_floorceil (operands[0], operands[1], true);
16015 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16016 ix86_expand_floorceil (operands[0], operands[1], false);
16017 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16018 ix86_expand_trunc (operands[0], operands[1]);
16020 gcc_unreachable ();
16024 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16025 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
16026 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16027 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
16028 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16029 ix86_expand_truncdf_32 (operands[0], operands[1]);
16031 gcc_unreachable ();
16038 op0 = gen_reg_rtx (XFmode);
16039 op1 = gen_reg_rtx (XFmode);
16040 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16041 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
16043 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16048 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16049 (define_insn_and_split "frndintxf2_mask_pm"
16050 [(set (match_operand:XF 0 "register_operand")
16051 (unspec:XF [(match_operand:XF 1 "register_operand")]
16052 UNSPEC_FRNDINT_MASK_PM))
16053 (clobber (reg:CC FLAGS_REG))]
16054 "TARGET_USE_FANCY_MATH_387
16055 && flag_unsafe_math_optimizations
16056 && can_create_pseudo_p ()"
16061 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
16063 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16064 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
16066 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
16067 operands[2], operands[3]));
16070 [(set_attr "type" "frndint")
16071 (set_attr "i387_cw" "mask_pm")
16072 (set_attr "mode" "XF")])
16074 (define_insn "frndintxf2_mask_pm_i387"
16075 [(set (match_operand:XF 0 "register_operand" "=f")
16076 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16077 UNSPEC_FRNDINT_MASK_PM))
16078 (use (match_operand:HI 2 "memory_operand" "m"))
16079 (use (match_operand:HI 3 "memory_operand" "m"))]
16080 "TARGET_USE_FANCY_MATH_387
16081 && flag_unsafe_math_optimizations"
16082 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16083 [(set_attr "type" "frndint")
16084 (set_attr "i387_cw" "mask_pm")
16085 (set_attr "mode" "XF")])
16087 (define_expand "nearbyintxf2"
16088 [(parallel [(set (match_operand:XF 0 "register_operand")
16089 (unspec:XF [(match_operand:XF 1 "register_operand")]
16090 UNSPEC_FRNDINT_MASK_PM))
16091 (clobber (reg:CC FLAGS_REG))])]
16092 "TARGET_USE_FANCY_MATH_387
16093 && flag_unsafe_math_optimizations")
16095 (define_expand "nearbyint<mode>2"
16096 [(use (match_operand:MODEF 0 "register_operand"))
16097 (use (match_operand:MODEF 1 "register_operand"))]
16098 "TARGET_USE_FANCY_MATH_387
16099 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16100 || TARGET_MIX_SSE_I387)
16101 && flag_unsafe_math_optimizations"
16103 rtx op0 = gen_reg_rtx (XFmode);
16104 rtx op1 = gen_reg_rtx (XFmode);
16106 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16107 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16109 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16113 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16114 (define_insn_and_split "*fist<mode>2_<rounding>_1"
16115 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16116 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16118 (clobber (reg:CC FLAGS_REG))]
16119 "TARGET_USE_FANCY_MATH_387
16120 && flag_unsafe_math_optimizations
16121 && can_create_pseudo_p ()"
16126 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16128 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16129 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16130 if (memory_operand (operands[0], VOIDmode))
16131 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
16132 operands[2], operands[3]));
16135 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16136 emit_insn (gen_fist<mode>2_<rounding>_with_temp
16137 (operands[0], operands[1], operands[2],
16138 operands[3], operands[4]));
16142 [(set_attr "type" "fistp")
16143 (set_attr "i387_cw" "<rounding>")
16144 (set_attr "mode" "<MODE>")])
16146 (define_insn "fistdi2_<rounding>"
16147 [(set (match_operand:DI 0 "memory_operand" "=m")
16148 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16150 (use (match_operand:HI 2 "memory_operand" "m"))
16151 (use (match_operand:HI 3 "memory_operand" "m"))
16152 (clobber (match_scratch:XF 4 "=&1f"))]
16153 "TARGET_USE_FANCY_MATH_387
16154 && flag_unsafe_math_optimizations"
16155 "* return output_fix_trunc (insn, operands, false);"
16156 [(set_attr "type" "fistp")
16157 (set_attr "i387_cw" "<rounding>")
16158 (set_attr "mode" "DI")])
16160 (define_insn "fistdi2_<rounding>_with_temp"
16161 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16162 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16164 (use (match_operand:HI 2 "memory_operand" "m,m"))
16165 (use (match_operand:HI 3 "memory_operand" "m,m"))
16166 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
16167 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16168 "TARGET_USE_FANCY_MATH_387
16169 && flag_unsafe_math_optimizations"
16171 [(set_attr "type" "fistp")
16172 (set_attr "i387_cw" "<rounding>")
16173 (set_attr "mode" "DI")])
16176 [(set (match_operand:DI 0 "register_operand")
16177 (unspec:DI [(match_operand:XF 1 "register_operand")]
16179 (use (match_operand:HI 2 "memory_operand"))
16180 (use (match_operand:HI 3 "memory_operand"))
16181 (clobber (match_operand:DI 4 "memory_operand"))
16182 (clobber (match_scratch 5))]
16184 [(parallel [(set (match_dup 4)
16185 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16186 (use (match_dup 2))
16187 (use (match_dup 3))
16188 (clobber (match_dup 5))])
16189 (set (match_dup 0) (match_dup 4))])
16192 [(set (match_operand:DI 0 "memory_operand")
16193 (unspec:DI [(match_operand:XF 1 "register_operand")]
16195 (use (match_operand:HI 2 "memory_operand"))
16196 (use (match_operand:HI 3 "memory_operand"))
16197 (clobber (match_operand:DI 4 "memory_operand"))
16198 (clobber (match_scratch 5))]
16200 [(parallel [(set (match_dup 0)
16201 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16202 (use (match_dup 2))
16203 (use (match_dup 3))
16204 (clobber (match_dup 5))])])
16206 (define_insn "fist<mode>2_<rounding>"
16207 [(set (match_operand:SWI24 0 "memory_operand" "=m")
16208 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16210 (use (match_operand:HI 2 "memory_operand" "m"))
16211 (use (match_operand:HI 3 "memory_operand" "m"))]
16212 "TARGET_USE_FANCY_MATH_387
16213 && flag_unsafe_math_optimizations"
16214 "* return output_fix_trunc (insn, operands, false);"
16215 [(set_attr "type" "fistp")
16216 (set_attr "i387_cw" "<rounding>")
16217 (set_attr "mode" "<MODE>")])
16219 (define_insn "fist<mode>2_<rounding>_with_temp"
16220 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
16221 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
16223 (use (match_operand:HI 2 "memory_operand" "m,m"))
16224 (use (match_operand:HI 3 "memory_operand" "m,m"))
16225 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
16226 "TARGET_USE_FANCY_MATH_387
16227 && flag_unsafe_math_optimizations"
16229 [(set_attr "type" "fistp")
16230 (set_attr "i387_cw" "<rounding>")
16231 (set_attr "mode" "<MODE>")])
16234 [(set (match_operand:SWI24 0 "register_operand")
16235 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16237 (use (match_operand:HI 2 "memory_operand"))
16238 (use (match_operand:HI 3 "memory_operand"))
16239 (clobber (match_operand:SWI24 4 "memory_operand"))]
16241 [(parallel [(set (match_dup 4)
16242 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16243 (use (match_dup 2))
16244 (use (match_dup 3))])
16245 (set (match_dup 0) (match_dup 4))])
16248 [(set (match_operand:SWI24 0 "memory_operand")
16249 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16251 (use (match_operand:HI 2 "memory_operand"))
16252 (use (match_operand:HI 3 "memory_operand"))
16253 (clobber (match_operand:SWI24 4 "memory_operand"))]
16255 [(parallel [(set (match_dup 0)
16256 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16257 (use (match_dup 2))
16258 (use (match_dup 3))])])
16260 (define_expand "l<rounding_insn>xf<mode>2"
16261 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16262 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16264 (clobber (reg:CC FLAGS_REG))])]
16265 "TARGET_USE_FANCY_MATH_387
16266 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16267 && flag_unsafe_math_optimizations")
16269 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
16270 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
16271 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16273 (clobber (reg:CC FLAGS_REG))])]
16274 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16275 && !flag_trapping_math"
16277 if (TARGET_64BIT && optimize_insn_for_size_p ())
16280 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16281 ix86_expand_lfloorceil (operands[0], operands[1], true);
16282 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16283 ix86_expand_lfloorceil (operands[0], operands[1], false);
16285 gcc_unreachable ();
16290 (define_insn "fxam<mode>2_i387"
16291 [(set (match_operand:HI 0 "register_operand" "=a")
16293 [(match_operand:X87MODEF 1 "register_operand" "f")]
16295 "TARGET_USE_FANCY_MATH_387"
16296 "fxam\n\tfnstsw\t%0"
16297 [(set_attr "type" "multi")
16298 (set_attr "length" "4")
16299 (set_attr "unit" "i387")
16300 (set_attr "mode" "<MODE>")])
16302 (define_insn_and_split "fxam<mode>2_i387_with_temp"
16303 [(set (match_operand:HI 0 "register_operand")
16305 [(match_operand:MODEF 1 "memory_operand")]
16307 "TARGET_USE_FANCY_MATH_387
16308 && can_create_pseudo_p ()"
16311 [(set (match_dup 2)(match_dup 1))
16313 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
16315 operands[2] = gen_reg_rtx (<MODE>mode);
16317 MEM_VOLATILE_P (operands[1]) = 1;
16319 [(set_attr "type" "multi")
16320 (set_attr "unit" "i387")
16321 (set_attr "mode" "<MODE>")])
16323 (define_expand "isinfxf2"
16324 [(use (match_operand:SI 0 "register_operand"))
16325 (use (match_operand:XF 1 "register_operand"))]
16326 "TARGET_USE_FANCY_MATH_387
16327 && ix86_libc_has_function (function_c99_misc)"
16329 rtx mask = GEN_INT (0x45);
16330 rtx val = GEN_INT (0x05);
16334 rtx scratch = gen_reg_rtx (HImode);
16335 rtx res = gen_reg_rtx (QImode);
16337 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16339 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
16340 emit_insn (gen_cmpqi_ext_3 (scratch, val));
16341 cond = gen_rtx_fmt_ee (EQ, QImode,
16342 gen_rtx_REG (CCmode, FLAGS_REG),
16344 emit_insn (gen_rtx_SET (res, cond));
16345 emit_insn (gen_zero_extendqisi2 (operands[0], res));
16349 (define_expand "isinf<mode>2"
16350 [(use (match_operand:SI 0 "register_operand"))
16351 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
16352 "TARGET_USE_FANCY_MATH_387
16353 && ix86_libc_has_function (function_c99_misc)
16354 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16356 rtx mask = GEN_INT (0x45);
16357 rtx val = GEN_INT (0x05);
16361 rtx scratch = gen_reg_rtx (HImode);
16362 rtx res = gen_reg_rtx (QImode);
16364 /* Remove excess precision by forcing value through memory. */
16365 if (memory_operand (operands[1], VOIDmode))
16366 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
16369 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16371 emit_move_insn (temp, operands[1]);
16372 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
16375 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
16376 emit_insn (gen_cmpqi_ext_3 (scratch, val));
16377 cond = gen_rtx_fmt_ee (EQ, QImode,
16378 gen_rtx_REG (CCmode, FLAGS_REG),
16380 emit_insn (gen_rtx_SET (res, cond));
16381 emit_insn (gen_zero_extendqisi2 (operands[0], res));
16385 (define_expand "signbitxf2"
16386 [(use (match_operand:SI 0 "register_operand"))
16387 (use (match_operand:XF 1 "register_operand"))]
16388 "TARGET_USE_FANCY_MATH_387"
16390 rtx scratch = gen_reg_rtx (HImode);
16392 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16393 emit_insn (gen_andsi3 (operands[0],
16394 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16398 (define_insn "movmsk_df"
16399 [(set (match_operand:SI 0 "register_operand" "=r")
16401 [(match_operand:DF 1 "register_operand" "x")]
16403 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
16404 "%vmovmskpd\t{%1, %0|%0, %1}"
16405 [(set_attr "type" "ssemov")
16406 (set_attr "prefix" "maybe_vex")
16407 (set_attr "mode" "DF")])
16409 ;; Use movmskpd in SSE mode to avoid store forwarding stall
16410 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
16411 (define_expand "signbitdf2"
16412 [(use (match_operand:SI 0 "register_operand"))
16413 (use (match_operand:DF 1 "register_operand"))]
16414 "TARGET_USE_FANCY_MATH_387
16415 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
16417 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
16419 emit_insn (gen_movmsk_df (operands[0], operands[1]));
16420 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
16424 rtx scratch = gen_reg_rtx (HImode);
16426 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
16427 emit_insn (gen_andsi3 (operands[0],
16428 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16433 (define_expand "signbitsf2"
16434 [(use (match_operand:SI 0 "register_operand"))
16435 (use (match_operand:SF 1 "register_operand"))]
16436 "TARGET_USE_FANCY_MATH_387
16437 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
16439 rtx scratch = gen_reg_rtx (HImode);
16441 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
16442 emit_insn (gen_andsi3 (operands[0],
16443 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16447 ;; Block operation instructions
16450 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16453 [(set_attr "length" "1")
16454 (set_attr "length_immediate" "0")
16455 (set_attr "modrm" "0")])
16457 (define_expand "movmem<mode>"
16458 [(use (match_operand:BLK 0 "memory_operand"))
16459 (use (match_operand:BLK 1 "memory_operand"))
16460 (use (match_operand:SWI48 2 "nonmemory_operand"))
16461 (use (match_operand:SWI48 3 "const_int_operand"))
16462 (use (match_operand:SI 4 "const_int_operand"))
16463 (use (match_operand:SI 5 "const_int_operand"))
16464 (use (match_operand:SI 6 ""))
16465 (use (match_operand:SI 7 ""))
16466 (use (match_operand:SI 8 ""))]
16469 if (ix86_expand_set_or_movmem (operands[0], operands[1],
16470 operands[2], NULL, operands[3],
16471 operands[4], operands[5],
16472 operands[6], operands[7],
16473 operands[8], false))
16479 ;; Most CPUs don't like single string operations
16480 ;; Handle this case here to simplify previous expander.
16482 (define_expand "strmov"
16483 [(set (match_dup 4) (match_operand 3 "memory_operand"))
16484 (set (match_operand 1 "memory_operand") (match_dup 4))
16485 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
16486 (clobber (reg:CC FLAGS_REG))])
16487 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
16488 (clobber (reg:CC FLAGS_REG))])]
16491 /* Can't use this for non-default address spaces. */
16492 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
16495 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16497 /* If .md ever supports :P for Pmode, these can be directly
16498 in the pattern above. */
16499 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16500 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16502 /* Can't use this if the user has appropriated esi or edi. */
16503 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16504 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16506 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16507 operands[2], operands[3],
16508 operands[5], operands[6]));
16512 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16515 (define_expand "strmov_singleop"
16516 [(parallel [(set (match_operand 1 "memory_operand")
16517 (match_operand 3 "memory_operand"))
16518 (set (match_operand 0 "register_operand")
16520 (set (match_operand 2 "register_operand")
16521 (match_operand 5))])]
16523 "ix86_current_function_needs_cld = 1;")
16525 (define_insn "*strmovdi_rex_1"
16526 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16527 (mem:DI (match_operand:P 3 "register_operand" "1")))
16528 (set (match_operand:P 0 "register_operand" "=D")
16529 (plus:P (match_dup 2)
16531 (set (match_operand:P 1 "register_operand" "=S")
16532 (plus:P (match_dup 3)
16535 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16536 && ix86_check_no_addr_space (insn)"
16538 [(set_attr "type" "str")
16539 (set_attr "memory" "both")
16540 (set_attr "mode" "DI")])
16542 (define_insn "*strmovsi_1"
16543 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16544 (mem:SI (match_operand:P 3 "register_operand" "1")))
16545 (set (match_operand:P 0 "register_operand" "=D")
16546 (plus:P (match_dup 2)
16548 (set (match_operand:P 1 "register_operand" "=S")
16549 (plus:P (match_dup 3)
16551 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16552 && ix86_check_no_addr_space (insn)"
16554 [(set_attr "type" "str")
16555 (set_attr "memory" "both")
16556 (set_attr "mode" "SI")])
16558 (define_insn "*strmovhi_1"
16559 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16560 (mem:HI (match_operand:P 3 "register_operand" "1")))
16561 (set (match_operand:P 0 "register_operand" "=D")
16562 (plus:P (match_dup 2)
16564 (set (match_operand:P 1 "register_operand" "=S")
16565 (plus:P (match_dup 3)
16567 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16568 && ix86_check_no_addr_space (insn)"
16570 [(set_attr "type" "str")
16571 (set_attr "memory" "both")
16572 (set_attr "mode" "HI")])
16574 (define_insn "*strmovqi_1"
16575 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16576 (mem:QI (match_operand:P 3 "register_operand" "1")))
16577 (set (match_operand:P 0 "register_operand" "=D")
16578 (plus:P (match_dup 2)
16580 (set (match_operand:P 1 "register_operand" "=S")
16581 (plus:P (match_dup 3)
16583 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16584 && ix86_check_no_addr_space (insn)"
16586 [(set_attr "type" "str")
16587 (set_attr "memory" "both")
16588 (set (attr "prefix_rex")
16590 (match_test "<P:MODE>mode == DImode")
16592 (const_string "*")))
16593 (set_attr "mode" "QI")])
16595 (define_expand "rep_mov"
16596 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16597 (set (match_operand 0 "register_operand")
16599 (set (match_operand 2 "register_operand")
16601 (set (match_operand 1 "memory_operand")
16602 (match_operand 3 "memory_operand"))
16603 (use (match_dup 4))])]
16605 "ix86_current_function_needs_cld = 1;")
16607 (define_insn "*rep_movdi_rex64"
16608 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16609 (set (match_operand:P 0 "register_operand" "=D")
16610 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16612 (match_operand:P 3 "register_operand" "0")))
16613 (set (match_operand:P 1 "register_operand" "=S")
16614 (plus:P (ashift:P (match_dup 5) (const_int 3))
16615 (match_operand:P 4 "register_operand" "1")))
16616 (set (mem:BLK (match_dup 3))
16617 (mem:BLK (match_dup 4)))
16618 (use (match_dup 5))]
16620 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16621 && ix86_check_no_addr_space (insn)"
16623 [(set_attr "type" "str")
16624 (set_attr "prefix_rep" "1")
16625 (set_attr "memory" "both")
16626 (set_attr "mode" "DI")])
16628 (define_insn "*rep_movsi"
16629 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16630 (set (match_operand:P 0 "register_operand" "=D")
16631 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16633 (match_operand:P 3 "register_operand" "0")))
16634 (set (match_operand:P 1 "register_operand" "=S")
16635 (plus:P (ashift:P (match_dup 5) (const_int 2))
16636 (match_operand:P 4 "register_operand" "1")))
16637 (set (mem:BLK (match_dup 3))
16638 (mem:BLK (match_dup 4)))
16639 (use (match_dup 5))]
16640 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16641 && ix86_check_no_addr_space (insn)"
16642 "%^rep{%;} movs{l|d}"
16643 [(set_attr "type" "str")
16644 (set_attr "prefix_rep" "1")
16645 (set_attr "memory" "both")
16646 (set_attr "mode" "SI")])
16648 (define_insn "*rep_movqi"
16649 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16650 (set (match_operand:P 0 "register_operand" "=D")
16651 (plus:P (match_operand:P 3 "register_operand" "0")
16652 (match_operand:P 5 "register_operand" "2")))
16653 (set (match_operand:P 1 "register_operand" "=S")
16654 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16655 (set (mem:BLK (match_dup 3))
16656 (mem:BLK (match_dup 4)))
16657 (use (match_dup 5))]
16658 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16659 && ix86_check_no_addr_space (insn)"
16661 [(set_attr "type" "str")
16662 (set_attr "prefix_rep" "1")
16663 (set_attr "memory" "both")
16664 (set_attr "mode" "QI")])
16666 (define_expand "setmem<mode>"
16667 [(use (match_operand:BLK 0 "memory_operand"))
16668 (use (match_operand:SWI48 1 "nonmemory_operand"))
16669 (use (match_operand:QI 2 "nonmemory_operand"))
16670 (use (match_operand 3 "const_int_operand"))
16671 (use (match_operand:SI 4 "const_int_operand"))
16672 (use (match_operand:SI 5 "const_int_operand"))
16673 (use (match_operand:SI 6 ""))
16674 (use (match_operand:SI 7 ""))
16675 (use (match_operand:SI 8 ""))]
16678 if (ix86_expand_set_or_movmem (operands[0], NULL,
16679 operands[1], operands[2],
16680 operands[3], operands[4],
16681 operands[5], operands[6],
16682 operands[7], operands[8], true))
16688 ;; Most CPUs don't like single string operations
16689 ;; Handle this case here to simplify previous expander.
16691 (define_expand "strset"
16692 [(set (match_operand 1 "memory_operand")
16693 (match_operand 2 "register_operand"))
16694 (parallel [(set (match_operand 0 "register_operand")
16696 (clobber (reg:CC FLAGS_REG))])]
16699 /* Can't use this for non-default address spaces. */
16700 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
16703 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16704 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16706 /* If .md ever supports :P for Pmode, this can be directly
16707 in the pattern above. */
16708 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16709 GEN_INT (GET_MODE_SIZE (GET_MODE
16711 /* Can't use this if the user has appropriated eax or edi. */
16712 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16713 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16715 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16721 (define_expand "strset_singleop"
16722 [(parallel [(set (match_operand 1 "memory_operand")
16723 (match_operand 2 "register_operand"))
16724 (set (match_operand 0 "register_operand")
16726 (unspec [(const_int 0)] UNSPEC_STOS)])]
16728 "ix86_current_function_needs_cld = 1;")
16730 (define_insn "*strsetdi_rex_1"
16731 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16732 (match_operand:DI 2 "register_operand" "a"))
16733 (set (match_operand:P 0 "register_operand" "=D")
16734 (plus:P (match_dup 1)
16736 (unspec [(const_int 0)] UNSPEC_STOS)]
16738 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16739 && ix86_check_no_addr_space (insn)"
16741 [(set_attr "type" "str")
16742 (set_attr "memory" "store")
16743 (set_attr "mode" "DI")])
16745 (define_insn "*strsetsi_1"
16746 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16747 (match_operand:SI 2 "register_operand" "a"))
16748 (set (match_operand:P 0 "register_operand" "=D")
16749 (plus:P (match_dup 1)
16751 (unspec [(const_int 0)] UNSPEC_STOS)]
16752 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16753 && ix86_check_no_addr_space (insn)"
16755 [(set_attr "type" "str")
16756 (set_attr "memory" "store")
16757 (set_attr "mode" "SI")])
16759 (define_insn "*strsethi_1"
16760 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16761 (match_operand:HI 2 "register_operand" "a"))
16762 (set (match_operand:P 0 "register_operand" "=D")
16763 (plus:P (match_dup 1)
16765 (unspec [(const_int 0)] UNSPEC_STOS)]
16766 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16767 && ix86_check_no_addr_space (insn)"
16769 [(set_attr "type" "str")
16770 (set_attr "memory" "store")
16771 (set_attr "mode" "HI")])
16773 (define_insn "*strsetqi_1"
16774 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16775 (match_operand:QI 2 "register_operand" "a"))
16776 (set (match_operand:P 0 "register_operand" "=D")
16777 (plus:P (match_dup 1)
16779 (unspec [(const_int 0)] UNSPEC_STOS)]
16780 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16781 && ix86_check_no_addr_space (insn)"
16783 [(set_attr "type" "str")
16784 (set_attr "memory" "store")
16785 (set (attr "prefix_rex")
16787 (match_test "<P:MODE>mode == DImode")
16789 (const_string "*")))
16790 (set_attr "mode" "QI")])
16792 (define_expand "rep_stos"
16793 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16794 (set (match_operand 0 "register_operand")
16796 (set (match_operand 2 "memory_operand") (const_int 0))
16797 (use (match_operand 3 "register_operand"))
16798 (use (match_dup 1))])]
16800 "ix86_current_function_needs_cld = 1;")
16802 (define_insn "*rep_stosdi_rex64"
16803 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16804 (set (match_operand:P 0 "register_operand" "=D")
16805 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16807 (match_operand:P 3 "register_operand" "0")))
16808 (set (mem:BLK (match_dup 3))
16810 (use (match_operand:DI 2 "register_operand" "a"))
16811 (use (match_dup 4))]
16813 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16814 && ix86_check_no_addr_space (insn)"
16816 [(set_attr "type" "str")
16817 (set_attr "prefix_rep" "1")
16818 (set_attr "memory" "store")
16819 (set_attr "mode" "DI")])
16821 (define_insn "*rep_stossi"
16822 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16823 (set (match_operand:P 0 "register_operand" "=D")
16824 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16826 (match_operand:P 3 "register_operand" "0")))
16827 (set (mem:BLK (match_dup 3))
16829 (use (match_operand:SI 2 "register_operand" "a"))
16830 (use (match_dup 4))]
16831 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16832 && ix86_check_no_addr_space (insn)"
16833 "%^rep{%;} stos{l|d}"
16834 [(set_attr "type" "str")
16835 (set_attr "prefix_rep" "1")
16836 (set_attr "memory" "store")
16837 (set_attr "mode" "SI")])
16839 (define_insn "*rep_stosqi"
16840 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16841 (set (match_operand:P 0 "register_operand" "=D")
16842 (plus:P (match_operand:P 3 "register_operand" "0")
16843 (match_operand:P 4 "register_operand" "1")))
16844 (set (mem:BLK (match_dup 3))
16846 (use (match_operand:QI 2 "register_operand" "a"))
16847 (use (match_dup 4))]
16848 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16849 && ix86_check_no_addr_space (insn)"
16851 [(set_attr "type" "str")
16852 (set_attr "prefix_rep" "1")
16853 (set_attr "memory" "store")
16854 (set (attr "prefix_rex")
16856 (match_test "<P:MODE>mode == DImode")
16858 (const_string "*")))
16859 (set_attr "mode" "QI")])
16861 (define_expand "cmpstrnsi"
16862 [(set (match_operand:SI 0 "register_operand")
16863 (compare:SI (match_operand:BLK 1 "general_operand")
16864 (match_operand:BLK 2 "general_operand")))
16865 (use (match_operand 3 "general_operand"))
16866 (use (match_operand 4 "immediate_operand"))]
16869 rtx addr1, addr2, out, outlow, count, countreg, align;
16871 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16874 /* Can't use this if the user has appropriated ecx, esi or edi. */
16875 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16880 out = gen_reg_rtx (SImode);
16882 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16883 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16884 if (addr1 != XEXP (operands[1], 0))
16885 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16886 if (addr2 != XEXP (operands[2], 0))
16887 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16889 count = operands[3];
16890 countreg = ix86_zero_extend_to_Pmode (count);
16892 /* %%% Iff we are testing strict equality, we can use known alignment
16893 to good advantage. This may be possible with combine, particularly
16894 once cc0 is dead. */
16895 align = operands[4];
16897 if (CONST_INT_P (count))
16899 if (INTVAL (count) == 0)
16901 emit_move_insn (operands[0], const0_rtx);
16904 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16905 operands[1], operands[2]));
16909 rtx (*gen_cmp) (rtx, rtx);
16911 gen_cmp = (TARGET_64BIT
16912 ? gen_cmpdi_1 : gen_cmpsi_1);
16914 emit_insn (gen_cmp (countreg, countreg));
16915 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16916 operands[1], operands[2]));
16919 outlow = gen_lowpart (QImode, out);
16920 emit_insn (gen_cmpintqi (outlow));
16921 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16923 if (operands[0] != out)
16924 emit_move_insn (operands[0], out);
16929 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16931 (define_expand "cmpintqi"
16932 [(set (match_dup 1)
16933 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16935 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16936 (parallel [(set (match_operand:QI 0 "register_operand")
16937 (minus:QI (match_dup 1)
16939 (clobber (reg:CC FLAGS_REG))])]
16942 operands[1] = gen_reg_rtx (QImode);
16943 operands[2] = gen_reg_rtx (QImode);
16946 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16947 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16949 (define_expand "cmpstrnqi_nz_1"
16950 [(parallel [(set (reg:CC FLAGS_REG)
16951 (compare:CC (match_operand 4 "memory_operand")
16952 (match_operand 5 "memory_operand")))
16953 (use (match_operand 2 "register_operand"))
16954 (use (match_operand:SI 3 "immediate_operand"))
16955 (clobber (match_operand 0 "register_operand"))
16956 (clobber (match_operand 1 "register_operand"))
16957 (clobber (match_dup 2))])]
16959 "ix86_current_function_needs_cld = 1;")
16961 (define_insn "*cmpstrnqi_nz_1"
16962 [(set (reg:CC FLAGS_REG)
16963 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16964 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16965 (use (match_operand:P 6 "register_operand" "2"))
16966 (use (match_operand:SI 3 "immediate_operand" "i"))
16967 (clobber (match_operand:P 0 "register_operand" "=S"))
16968 (clobber (match_operand:P 1 "register_operand" "=D"))
16969 (clobber (match_operand:P 2 "register_operand" "=c"))]
16970 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16971 && ix86_check_no_addr_space (insn)"
16973 [(set_attr "type" "str")
16974 (set_attr "mode" "QI")
16975 (set (attr "prefix_rex")
16977 (match_test "<P:MODE>mode == DImode")
16979 (const_string "*")))
16980 (set_attr "prefix_rep" "1")])
16982 ;; The same, but the count is not known to not be zero.
16984 (define_expand "cmpstrnqi_1"
16985 [(parallel [(set (reg:CC FLAGS_REG)
16986 (if_then_else:CC (ne (match_operand 2 "register_operand")
16988 (compare:CC (match_operand 4 "memory_operand")
16989 (match_operand 5 "memory_operand"))
16991 (use (match_operand:SI 3 "immediate_operand"))
16992 (use (reg:CC FLAGS_REG))
16993 (clobber (match_operand 0 "register_operand"))
16994 (clobber (match_operand 1 "register_operand"))
16995 (clobber (match_dup 2))])]
16997 "ix86_current_function_needs_cld = 1;")
16999 (define_insn "*cmpstrnqi_1"
17000 [(set (reg:CC FLAGS_REG)
17001 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
17003 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17004 (mem:BLK (match_operand:P 5 "register_operand" "1")))
17006 (use (match_operand:SI 3 "immediate_operand" "i"))
17007 (use (reg:CC FLAGS_REG))
17008 (clobber (match_operand:P 0 "register_operand" "=S"))
17009 (clobber (match_operand:P 1 "register_operand" "=D"))
17010 (clobber (match_operand:P 2 "register_operand" "=c"))]
17011 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17012 && ix86_check_no_addr_space (insn)"
17014 [(set_attr "type" "str")
17015 (set_attr "mode" "QI")
17016 (set (attr "prefix_rex")
17018 (match_test "<P:MODE>mode == DImode")
17020 (const_string "*")))
17021 (set_attr "prefix_rep" "1")])
17023 (define_expand "strlen<mode>"
17024 [(set (match_operand:P 0 "register_operand")
17025 (unspec:P [(match_operand:BLK 1 "general_operand")
17026 (match_operand:QI 2 "immediate_operand")
17027 (match_operand 3 "immediate_operand")]
17031 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17037 (define_expand "strlenqi_1"
17038 [(parallel [(set (match_operand 0 "register_operand")
17040 (clobber (match_operand 1 "register_operand"))
17041 (clobber (reg:CC FLAGS_REG))])]
17043 "ix86_current_function_needs_cld = 1;")
17045 (define_insn "*strlenqi_1"
17046 [(set (match_operand:P 0 "register_operand" "=&c")
17047 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
17048 (match_operand:QI 2 "register_operand" "a")
17049 (match_operand:P 3 "immediate_operand" "i")
17050 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
17051 (clobber (match_operand:P 1 "register_operand" "=D"))
17052 (clobber (reg:CC FLAGS_REG))]
17053 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17054 && ix86_check_no_addr_space (insn)"
17055 "%^repnz{%;} scasb"
17056 [(set_attr "type" "str")
17057 (set_attr "mode" "QI")
17058 (set (attr "prefix_rex")
17060 (match_test "<P:MODE>mode == DImode")
17062 (const_string "*")))
17063 (set_attr "prefix_rep" "1")])
17065 ;; Peephole optimizations to clean up after cmpstrn*. This should be
17066 ;; handled in combine, but it is not currently up to the task.
17067 ;; When used for their truth value, the cmpstrn* expanders generate
17076 ;; The intermediate three instructions are unnecessary.
17078 ;; This one handles cmpstrn*_nz_1...
17081 (set (reg:CC FLAGS_REG)
17082 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17083 (mem:BLK (match_operand 5 "register_operand"))))
17084 (use (match_operand 6 "register_operand"))
17085 (use (match_operand:SI 3 "immediate_operand"))
17086 (clobber (match_operand 0 "register_operand"))
17087 (clobber (match_operand 1 "register_operand"))
17088 (clobber (match_operand 2 "register_operand"))])
17089 (set (match_operand:QI 7 "register_operand")
17090 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17091 (set (match_operand:QI 8 "register_operand")
17092 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17093 (set (reg FLAGS_REG)
17094 (compare (match_dup 7) (match_dup 8)))
17096 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17098 (set (reg:CC FLAGS_REG)
17099 (compare:CC (mem:BLK (match_dup 4))
17100 (mem:BLK (match_dup 5))))
17101 (use (match_dup 6))
17102 (use (match_dup 3))
17103 (clobber (match_dup 0))
17104 (clobber (match_dup 1))
17105 (clobber (match_dup 2))])])
17107 ;; ...and this one handles cmpstrn*_1.
17110 (set (reg:CC FLAGS_REG)
17111 (if_then_else:CC (ne (match_operand 6 "register_operand")
17113 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17114 (mem:BLK (match_operand 5 "register_operand")))
17116 (use (match_operand:SI 3 "immediate_operand"))
17117 (use (reg:CC FLAGS_REG))
17118 (clobber (match_operand 0 "register_operand"))
17119 (clobber (match_operand 1 "register_operand"))
17120 (clobber (match_operand 2 "register_operand"))])
17121 (set (match_operand:QI 7 "register_operand")
17122 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17123 (set (match_operand:QI 8 "register_operand")
17124 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17125 (set (reg FLAGS_REG)
17126 (compare (match_dup 7) (match_dup 8)))
17128 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17130 (set (reg:CC FLAGS_REG)
17131 (if_then_else:CC (ne (match_dup 6)
17133 (compare:CC (mem:BLK (match_dup 4))
17134 (mem:BLK (match_dup 5)))
17136 (use (match_dup 3))
17137 (use (reg:CC FLAGS_REG))
17138 (clobber (match_dup 0))
17139 (clobber (match_dup 1))
17140 (clobber (match_dup 2))])])
17142 ;; Conditional move instructions.
17144 (define_expand "mov<mode>cc"
17145 [(set (match_operand:SWIM 0 "register_operand")
17146 (if_then_else:SWIM (match_operand 1 "comparison_operator")
17147 (match_operand:SWIM 2 "<general_operand>")
17148 (match_operand:SWIM 3 "<general_operand>")))]
17150 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
17152 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17153 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17154 ;; So just document what we're doing explicitly.
17156 (define_expand "x86_mov<mode>cc_0_m1"
17158 [(set (match_operand:SWI48 0 "register_operand")
17159 (if_then_else:SWI48
17160 (match_operator:SWI48 2 "ix86_carry_flag_operator"
17161 [(match_operand 1 "flags_reg_operand")
17165 (clobber (reg:CC FLAGS_REG))])])
17167 (define_insn "*x86_mov<mode>cc_0_m1"
17168 [(set (match_operand:SWI48 0 "register_operand" "=r")
17169 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17170 [(reg FLAGS_REG) (const_int 0)])
17173 (clobber (reg:CC FLAGS_REG))]
17175 "sbb{<imodesuffix>}\t%0, %0"
17176 ; Since we don't have the proper number of operands for an alu insn,
17177 ; fill in all the blanks.
17178 [(set_attr "type" "alu")
17179 (set_attr "modrm_class" "op0")
17180 (set_attr "use_carry" "1")
17181 (set_attr "pent_pair" "pu")
17182 (set_attr "memory" "none")
17183 (set_attr "imm_disp" "false")
17184 (set_attr "mode" "<MODE>")
17185 (set_attr "length_immediate" "0")])
17187 (define_insn "*x86_mov<mode>cc_0_m1_se"
17188 [(set (match_operand:SWI48 0 "register_operand" "=r")
17189 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17190 [(reg FLAGS_REG) (const_int 0)])
17193 (clobber (reg:CC FLAGS_REG))]
17195 "sbb{<imodesuffix>}\t%0, %0"
17196 [(set_attr "type" "alu")
17197 (set_attr "modrm_class" "op0")
17198 (set_attr "use_carry" "1")
17199 (set_attr "pent_pair" "pu")
17200 (set_attr "memory" "none")
17201 (set_attr "imm_disp" "false")
17202 (set_attr "mode" "<MODE>")
17203 (set_attr "length_immediate" "0")])
17205 (define_insn "*x86_mov<mode>cc_0_m1_neg"
17206 [(set (match_operand:SWI48 0 "register_operand" "=r")
17207 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17208 [(reg FLAGS_REG) (const_int 0)])))
17209 (clobber (reg:CC FLAGS_REG))]
17211 "sbb{<imodesuffix>}\t%0, %0"
17212 [(set_attr "type" "alu")
17213 (set_attr "modrm_class" "op0")
17214 (set_attr "use_carry" "1")
17215 (set_attr "pent_pair" "pu")
17216 (set_attr "memory" "none")
17217 (set_attr "imm_disp" "false")
17218 (set_attr "mode" "<MODE>")
17219 (set_attr "length_immediate" "0")])
17221 (define_insn "*mov<mode>cc_noc"
17222 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
17223 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17224 [(reg FLAGS_REG) (const_int 0)])
17225 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
17226 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
17227 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17229 cmov%O2%C1\t{%2, %0|%0, %2}
17230 cmov%O2%c1\t{%3, %0|%0, %3}"
17231 [(set_attr "type" "icmov")
17232 (set_attr "mode" "<MODE>")])
17234 (define_insn "*movsicc_noc_zext"
17235 [(set (match_operand:DI 0 "register_operand" "=r,r")
17236 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17237 [(reg FLAGS_REG) (const_int 0)])
17239 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
17241 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
17243 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17245 cmov%O2%C1\t{%2, %k0|%k0, %2}
17246 cmov%O2%c1\t{%3, %k0|%k0, %3}"
17247 [(set_attr "type" "icmov")
17248 (set_attr "mode" "SI")])
17250 ;; Don't do conditional moves with memory inputs. This splitter helps
17251 ;; register starved x86_32 by forcing inputs into registers before reload.
17253 [(set (match_operand:SWI248 0 "register_operand")
17254 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17255 [(reg FLAGS_REG) (const_int 0)])
17256 (match_operand:SWI248 2 "nonimmediate_operand")
17257 (match_operand:SWI248 3 "nonimmediate_operand")))]
17258 "!TARGET_64BIT && TARGET_CMOVE
17259 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17260 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17261 && can_create_pseudo_p ()
17262 && optimize_insn_for_speed_p ()"
17263 [(set (match_dup 0)
17264 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17266 if (MEM_P (operands[2]))
17267 operands[2] = force_reg (<MODE>mode, operands[2]);
17268 if (MEM_P (operands[3]))
17269 operands[3] = force_reg (<MODE>mode, operands[3]);
17272 (define_insn "*movqicc_noc"
17273 [(set (match_operand:QI 0 "register_operand" "=r,r")
17274 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17275 [(reg FLAGS_REG) (const_int 0)])
17276 (match_operand:QI 2 "register_operand" "r,0")
17277 (match_operand:QI 3 "register_operand" "0,r")))]
17278 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17280 [(set_attr "type" "icmov")
17281 (set_attr "mode" "QI")])
17284 [(set (match_operand:SWI12 0 "register_operand")
17285 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
17286 [(reg FLAGS_REG) (const_int 0)])
17287 (match_operand:SWI12 2 "register_operand")
17288 (match_operand:SWI12 3 "register_operand")))]
17289 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
17290 && reload_completed"
17291 [(set (match_dup 0)
17292 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17294 operands[0] = gen_lowpart (SImode, operands[0]);
17295 operands[2] = gen_lowpart (SImode, operands[2]);
17296 operands[3] = gen_lowpart (SImode, operands[3]);
17299 ;; Don't do conditional moves with memory inputs
17301 [(match_scratch:SWI248 4 "r")
17302 (set (match_operand:SWI248 0 "register_operand")
17303 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17304 [(reg FLAGS_REG) (const_int 0)])
17305 (match_operand:SWI248 2 "nonimmediate_operand")
17306 (match_operand:SWI248 3 "nonimmediate_operand")))]
17307 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17308 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17309 && optimize_insn_for_speed_p ()"
17310 [(set (match_dup 4) (match_dup 5))
17312 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17314 if (MEM_P (operands[2]))
17316 operands[5] = operands[2];
17317 operands[2] = operands[4];
17319 else if (MEM_P (operands[3]))
17321 operands[5] = operands[3];
17322 operands[3] = operands[4];
17325 gcc_unreachable ();
17329 [(match_scratch:SI 4 "r")
17330 (set (match_operand:DI 0 "register_operand")
17331 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17332 [(reg FLAGS_REG) (const_int 0)])
17334 (match_operand:SI 2 "nonimmediate_operand"))
17336 (match_operand:SI 3 "nonimmediate_operand"))))]
17338 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17339 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17340 && optimize_insn_for_speed_p ()"
17341 [(set (match_dup 4) (match_dup 5))
17343 (if_then_else:DI (match_dup 1)
17344 (zero_extend:DI (match_dup 2))
17345 (zero_extend:DI (match_dup 3))))]
17347 if (MEM_P (operands[2]))
17349 operands[5] = operands[2];
17350 operands[2] = operands[4];
17352 else if (MEM_P (operands[3]))
17354 operands[5] = operands[3];
17355 operands[3] = operands[4];
17358 gcc_unreachable ();
17361 (define_expand "mov<mode>cc"
17362 [(set (match_operand:X87MODEF 0 "register_operand")
17363 (if_then_else:X87MODEF
17364 (match_operand 1 "comparison_operator")
17365 (match_operand:X87MODEF 2 "register_operand")
17366 (match_operand:X87MODEF 3 "register_operand")))]
17367 "(TARGET_80387 && TARGET_CMOVE)
17368 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17369 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
17371 (define_insn "*movxfcc_1"
17372 [(set (match_operand:XF 0 "register_operand" "=f,f")
17373 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17374 [(reg FLAGS_REG) (const_int 0)])
17375 (match_operand:XF 2 "register_operand" "f,0")
17376 (match_operand:XF 3 "register_operand" "0,f")))]
17377 "TARGET_80387 && TARGET_CMOVE"
17379 fcmov%F1\t{%2, %0|%0, %2}
17380 fcmov%f1\t{%3, %0|%0, %3}"
17381 [(set_attr "type" "fcmov")
17382 (set_attr "mode" "XF")])
17384 (define_insn "*movdfcc_1"
17385 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
17386 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17387 [(reg FLAGS_REG) (const_int 0)])
17388 (match_operand:DF 2 "nonimmediate_operand"
17390 (match_operand:DF 3 "nonimmediate_operand"
17391 "0 ,f,0 ,rm,0, rm")))]
17392 "TARGET_80387 && TARGET_CMOVE
17393 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17395 fcmov%F1\t{%2, %0|%0, %2}
17396 fcmov%f1\t{%3, %0|%0, %3}
17399 cmov%O2%C1\t{%2, %0|%0, %2}
17400 cmov%O2%c1\t{%3, %0|%0, %3}"
17401 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
17402 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
17403 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
17406 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
17407 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17408 [(reg FLAGS_REG) (const_int 0)])
17409 (match_operand:DF 2 "nonimmediate_operand")
17410 (match_operand:DF 3 "nonimmediate_operand")))]
17411 "!TARGET_64BIT && reload_completed"
17412 [(set (match_dup 2)
17413 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
17415 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
17417 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
17418 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
17421 (define_insn "*movsfcc_1_387"
17422 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
17423 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17424 [(reg FLAGS_REG) (const_int 0)])
17425 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
17426 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
17427 "TARGET_80387 && TARGET_CMOVE
17428 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17430 fcmov%F1\t{%2, %0|%0, %2}
17431 fcmov%f1\t{%3, %0|%0, %3}
17432 cmov%O2%C1\t{%2, %0|%0, %2}
17433 cmov%O2%c1\t{%3, %0|%0, %3}"
17434 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17435 (set_attr "mode" "SF,SF,SI,SI")])
17437 ;; Don't do conditional moves with memory inputs. This splitter helps
17438 ;; register starved x86_32 by forcing inputs into registers before reload.
17440 [(set (match_operand:MODEF 0 "register_operand")
17441 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
17442 [(reg FLAGS_REG) (const_int 0)])
17443 (match_operand:MODEF 2 "nonimmediate_operand")
17444 (match_operand:MODEF 3 "nonimmediate_operand")))]
17445 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17446 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17447 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17448 && can_create_pseudo_p ()
17449 && optimize_insn_for_speed_p ()"
17450 [(set (match_dup 0)
17451 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17453 if (MEM_P (operands[2]))
17454 operands[2] = force_reg (<MODE>mode, operands[2]);
17455 if (MEM_P (operands[3]))
17456 operands[3] = force_reg (<MODE>mode, operands[3]);
17459 ;; Don't do conditional moves with memory inputs
17461 [(match_scratch:MODEF 4 "r")
17462 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
17463 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
17464 [(reg FLAGS_REG) (const_int 0)])
17465 (match_operand:MODEF 2 "nonimmediate_operand")
17466 (match_operand:MODEF 3 "nonimmediate_operand")))]
17467 "(<MODE>mode != DFmode || TARGET_64BIT)
17468 && TARGET_80387 && TARGET_CMOVE
17469 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17470 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17471 && optimize_insn_for_speed_p ()"
17472 [(set (match_dup 4) (match_dup 5))
17474 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17476 if (MEM_P (operands[2]))
17478 operands[5] = operands[2];
17479 operands[2] = operands[4];
17481 else if (MEM_P (operands[3]))
17483 operands[5] = operands[3];
17484 operands[3] = operands[4];
17487 gcc_unreachable ();
17490 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
17491 ;; the scalar versions to have only XMM registers as operands.
17493 ;; XOP conditional move
17494 (define_insn "*xop_pcmov_<mode>"
17495 [(set (match_operand:MODEF 0 "register_operand" "=x")
17496 (if_then_else:MODEF
17497 (match_operand:MODEF 1 "register_operand" "x")
17498 (match_operand:MODEF 2 "register_operand" "x")
17499 (match_operand:MODEF 3 "register_operand" "x")))]
17501 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
17502 [(set_attr "type" "sse4arg")])
17504 ;; These versions of the min/max patterns are intentionally ignorant of
17505 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17506 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17507 ;; are undefined in this condition, we're certain this is correct.
17509 (define_insn "<code><mode>3"
17510 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17512 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
17513 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
17514 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17516 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
17517 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17518 [(set_attr "isa" "noavx,avx")
17519 (set_attr "prefix" "orig,vex")
17520 (set_attr "type" "sseadd")
17521 (set_attr "mode" "<MODE>")])
17523 ;; These versions of the min/max patterns implement exactly the operations
17524 ;; min = (op1 < op2 ? op1 : op2)
17525 ;; max = (!(op1 < op2) ? op1 : op2)
17526 ;; Their operands are not commutative, and thus they may be used in the
17527 ;; presence of -0.0 and NaN.
17529 (define_insn "*ieee_s<ieee_maxmin><mode>3"
17530 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17532 [(match_operand:MODEF 1 "register_operand" "0,v")
17533 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
17535 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17537 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
17538 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17539 [(set_attr "isa" "noavx,avx")
17540 (set_attr "prefix" "orig,maybe_evex")
17541 (set_attr "type" "sseadd")
17542 (set_attr "mode" "<MODE>")])
17544 ;; Make two stack loads independent:
17546 ;; fld %st(0) -> fld bb
17547 ;; fmul bb fmul %st(1), %st
17549 ;; Actually we only match the last two instructions for simplicity.
17551 [(set (match_operand 0 "fp_register_operand")
17552 (match_operand 1 "fp_register_operand"))
17554 (match_operator 2 "binary_fp_operator"
17556 (match_operand 3 "memory_operand")]))]
17557 "REGNO (operands[0]) != REGNO (operands[1])"
17558 [(set (match_dup 0) (match_dup 3))
17559 (set (match_dup 0) (match_dup 4))]
17561 ;; The % modifier is not operational anymore in peephole2's, so we have to
17562 ;; swap the operands manually in the case of addition and multiplication.
17566 if (COMMUTATIVE_ARITH_P (operands[2]))
17567 op0 = operands[0], op1 = operands[1];
17569 op0 = operands[1], op1 = operands[0];
17571 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
17572 GET_MODE (operands[2]),
17576 ;; Conditional addition patterns
17577 (define_expand "add<mode>cc"
17578 [(match_operand:SWI 0 "register_operand")
17579 (match_operand 1 "ordered_comparison_operator")
17580 (match_operand:SWI 2 "register_operand")
17581 (match_operand:SWI 3 "const_int_operand")]
17583 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17585 ;; Misc patterns (?)
17587 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17588 ;; Otherwise there will be nothing to keep
17590 ;; [(set (reg ebp) (reg esp))]
17591 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17592 ;; (clobber (eflags)]
17593 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17595 ;; in proper program order.
17597 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
17598 [(set (match_operand:P 0 "register_operand" "=r,r")
17599 (plus:P (match_operand:P 1 "register_operand" "0,r")
17600 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17601 (clobber (reg:CC FLAGS_REG))
17602 (clobber (mem:BLK (scratch)))]
17605 switch (get_attr_type (insn))
17608 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17611 gcc_assert (rtx_equal_p (operands[0], operands[1]));
17612 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17613 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17615 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17618 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17619 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17622 [(set (attr "type")
17623 (cond [(and (eq_attr "alternative" "0")
17624 (not (match_test "TARGET_OPT_AGU")))
17625 (const_string "alu")
17626 (match_operand:<MODE> 2 "const0_operand")
17627 (const_string "imov")
17629 (const_string "lea")))
17630 (set (attr "length_immediate")
17631 (cond [(eq_attr "type" "imov")
17633 (and (eq_attr "type" "alu")
17634 (match_operand 2 "const128_operand"))
17637 (const_string "*")))
17638 (set_attr "mode" "<MODE>")])
17640 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
17641 [(set (match_operand:P 0 "register_operand" "=r")
17642 (minus:P (match_operand:P 1 "register_operand" "0")
17643 (match_operand:P 2 "register_operand" "r")))
17644 (clobber (reg:CC FLAGS_REG))
17645 (clobber (mem:BLK (scratch)))]
17647 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17648 [(set_attr "type" "alu")
17649 (set_attr "mode" "<MODE>")])
17651 (define_insn "allocate_stack_worker_probe_<mode>"
17652 [(set (match_operand:P 0 "register_operand" "=a")
17653 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17654 UNSPECV_STACK_PROBE))
17655 (clobber (reg:CC FLAGS_REG))]
17656 "ix86_target_stack_probe ()"
17657 "call\t___chkstk_ms"
17658 [(set_attr "type" "multi")
17659 (set_attr "length" "5")])
17661 (define_expand "allocate_stack"
17662 [(match_operand 0 "register_operand")
17663 (match_operand 1 "general_operand")]
17664 "ix86_target_stack_probe ()"
17668 #ifndef CHECK_STACK_LIMIT
17669 #define CHECK_STACK_LIMIT 0
17672 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17673 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17677 rtx (*insn) (rtx, rtx);
17679 x = copy_to_mode_reg (Pmode, operands[1]);
17681 insn = (TARGET_64BIT
17682 ? gen_allocate_stack_worker_probe_di
17683 : gen_allocate_stack_worker_probe_si);
17685 emit_insn (insn (x, x));
17688 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17689 stack_pointer_rtx, 0, OPTAB_DIRECT);
17691 if (x != stack_pointer_rtx)
17692 emit_move_insn (stack_pointer_rtx, x);
17694 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17698 ;; Use IOR for stack probes, this is shorter.
17699 (define_expand "probe_stack"
17700 [(match_operand 0 "memory_operand")]
17703 rtx (*gen_ior3) (rtx, rtx, rtx);
17705 gen_ior3 = (GET_MODE (operands[0]) == DImode
17706 ? gen_iordi3 : gen_iorsi3);
17708 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
17712 (define_insn "adjust_stack_and_probe<mode>"
17713 [(set (match_operand:P 0 "register_operand" "=r")
17714 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17715 UNSPECV_PROBE_STACK_RANGE))
17716 (set (reg:P SP_REG)
17717 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17718 (clobber (reg:CC FLAGS_REG))
17719 (clobber (mem:BLK (scratch)))]
17721 "* return output_adjust_stack_and_probe (operands[0]);"
17722 [(set_attr "type" "multi")])
17724 (define_insn "probe_stack_range<mode>"
17725 [(set (match_operand:P 0 "register_operand" "=r")
17726 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17727 (match_operand:P 2 "const_int_operand" "n")]
17728 UNSPECV_PROBE_STACK_RANGE))
17729 (clobber (reg:CC FLAGS_REG))]
17731 "* return output_probe_stack_range (operands[0], operands[2]);"
17732 [(set_attr "type" "multi")])
17734 (define_expand "builtin_setjmp_receiver"
17735 [(label_ref (match_operand 0))]
17736 "!TARGET_64BIT && flag_pic"
17742 rtx_code_label *label_rtx = gen_label_rtx ();
17743 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17744 xops[0] = xops[1] = pic_offset_table_rtx;
17745 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17746 ix86_expand_binary_operator (MINUS, SImode, xops);
17750 emit_insn (gen_set_got (pic_offset_table_rtx));
17754 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17755 ;; Do not split instructions with mask registers.
17757 [(set (match_operand 0 "general_reg_operand")
17758 (match_operator 3 "promotable_binary_operator"
17759 [(match_operand 1 "general_reg_operand")
17760 (match_operand 2 "aligned_operand")]))
17761 (clobber (reg:CC FLAGS_REG))]
17762 "! TARGET_PARTIAL_REG_STALL && reload_completed
17763 && ((GET_MODE (operands[0]) == HImode
17764 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17765 /* ??? next two lines just !satisfies_constraint_K (...) */
17766 || !CONST_INT_P (operands[2])
17767 || satisfies_constraint_K (operands[2])))
17768 || (GET_MODE (operands[0]) == QImode
17769 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17770 [(parallel [(set (match_dup 0)
17771 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17772 (clobber (reg:CC FLAGS_REG))])]
17774 operands[0] = gen_lowpart (SImode, operands[0]);
17775 operands[1] = gen_lowpart (SImode, operands[1]);
17776 if (GET_CODE (operands[3]) != ASHIFT)
17777 operands[2] = gen_lowpart (SImode, operands[2]);
17778 operands[3] = shallow_copy_rtx (operands[3]);
17779 PUT_MODE (operands[3], SImode);
17782 ; Promote the QImode tests, as i386 has encoding of the AND
17783 ; instruction with 32-bit sign-extended immediate and thus the
17784 ; instruction size is unchanged, except in the %eax case for
17785 ; which it is increased by one byte, hence the ! optimize_size.
17787 [(set (match_operand 0 "flags_reg_operand")
17788 (match_operator 2 "compare_operator"
17789 [(and (match_operand 3 "aligned_operand")
17790 (match_operand 4 "const_int_operand"))
17792 (set (match_operand 1 "register_operand")
17793 (and (match_dup 3) (match_dup 4)))]
17794 "! TARGET_PARTIAL_REG_STALL && reload_completed
17795 && optimize_insn_for_speed_p ()
17796 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17797 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17798 /* Ensure that the operand will remain sign-extended immediate. */
17799 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17800 [(parallel [(set (match_dup 0)
17801 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17804 (and:SI (match_dup 3) (match_dup 4)))])]
17807 = gen_int_mode (INTVAL (operands[4])
17808 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17809 operands[1] = gen_lowpart (SImode, operands[1]);
17810 operands[3] = gen_lowpart (SImode, operands[3]);
17813 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17814 ; the TEST instruction with 32-bit sign-extended immediate and thus
17815 ; the instruction size would at least double, which is not what we
17816 ; want even with ! optimize_size.
17818 [(set (match_operand 0 "flags_reg_operand")
17819 (match_operator 1 "compare_operator"
17820 [(and (match_operand:HI 2 "aligned_operand")
17821 (match_operand:HI 3 "const_int_operand"))
17823 "! TARGET_PARTIAL_REG_STALL && reload_completed
17824 && ! TARGET_FAST_PREFIX
17825 && optimize_insn_for_speed_p ()
17826 /* Ensure that the operand will remain sign-extended immediate. */
17827 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17828 [(set (match_dup 0)
17829 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17833 = gen_int_mode (INTVAL (operands[3])
17834 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17835 operands[2] = gen_lowpart (SImode, operands[2]);
17839 [(set (match_operand 0 "register_operand")
17840 (neg (match_operand 1 "register_operand")))
17841 (clobber (reg:CC FLAGS_REG))]
17842 "! TARGET_PARTIAL_REG_STALL && reload_completed
17843 && (GET_MODE (operands[0]) == HImode
17844 || (GET_MODE (operands[0]) == QImode
17845 && (TARGET_PROMOTE_QImode
17846 || optimize_insn_for_size_p ())))"
17847 [(parallel [(set (match_dup 0)
17848 (neg:SI (match_dup 1)))
17849 (clobber (reg:CC FLAGS_REG))])]
17851 operands[0] = gen_lowpart (SImode, operands[0]);
17852 operands[1] = gen_lowpart (SImode, operands[1]);
17855 ;; Do not split instructions with mask regs.
17857 [(set (match_operand 0 "general_reg_operand")
17858 (not (match_operand 1 "general_reg_operand")))]
17859 "! TARGET_PARTIAL_REG_STALL && reload_completed
17860 && (GET_MODE (operands[0]) == HImode
17861 || (GET_MODE (operands[0]) == QImode
17862 && (TARGET_PROMOTE_QImode
17863 || optimize_insn_for_size_p ())))"
17864 [(set (match_dup 0)
17865 (not:SI (match_dup 1)))]
17867 operands[0] = gen_lowpart (SImode, operands[0]);
17868 operands[1] = gen_lowpart (SImode, operands[1]);
17871 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17872 ;; transform a complex memory operation into two memory to register operations.
17874 ;; Don't push memory operands
17876 [(set (match_operand:SWI 0 "push_operand")
17877 (match_operand:SWI 1 "memory_operand"))
17878 (match_scratch:SWI 2 "<r>")]
17879 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17880 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17881 [(set (match_dup 2) (match_dup 1))
17882 (set (match_dup 0) (match_dup 2))])
17884 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17887 [(set (match_operand:SF 0 "push_operand")
17888 (match_operand:SF 1 "memory_operand"))
17889 (match_scratch:SF 2 "r")]
17890 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17891 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17892 [(set (match_dup 2) (match_dup 1))
17893 (set (match_dup 0) (match_dup 2))])
17895 ;; Don't move an immediate directly to memory when the instruction
17896 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17898 [(match_scratch:SWI124 1 "<r>")
17899 (set (match_operand:SWI124 0 "memory_operand")
17901 "optimize_insn_for_speed_p ()
17902 && ((<MODE>mode == HImode
17903 && TARGET_LCP_STALL)
17904 || (!TARGET_USE_MOV0
17905 && TARGET_SPLIT_LONG_MOVES
17906 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17907 && peep2_regno_dead_p (0, FLAGS_REG)"
17908 [(parallel [(set (match_dup 2) (const_int 0))
17909 (clobber (reg:CC FLAGS_REG))])
17910 (set (match_dup 0) (match_dup 1))]
17911 "operands[2] = gen_lowpart (SImode, operands[1]);")
17914 [(match_scratch:SWI124 2 "<r>")
17915 (set (match_operand:SWI124 0 "memory_operand")
17916 (match_operand:SWI124 1 "immediate_operand"))]
17917 "optimize_insn_for_speed_p ()
17918 && ((<MODE>mode == HImode
17919 && TARGET_LCP_STALL)
17920 || (TARGET_SPLIT_LONG_MOVES
17921 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17922 [(set (match_dup 2) (match_dup 1))
17923 (set (match_dup 0) (match_dup 2))])
17925 ;; Don't compare memory with zero, load and use a test instead.
17927 [(set (match_operand 0 "flags_reg_operand")
17928 (match_operator 1 "compare_operator"
17929 [(match_operand:SI 2 "memory_operand")
17931 (match_scratch:SI 3 "r")]
17932 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17933 [(set (match_dup 3) (match_dup 2))
17934 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17936 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17937 ;; Don't split NOTs with a displacement operand, because resulting XOR
17938 ;; will not be pairable anyway.
17940 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17941 ;; represented using a modRM byte. The XOR replacement is long decoded,
17942 ;; so this split helps here as well.
17944 ;; Note: Can't do this as a regular split because we can't get proper
17945 ;; lifetime information then.
17948 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
17949 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
17950 "optimize_insn_for_speed_p ()
17951 && ((TARGET_NOT_UNPAIRABLE
17952 && (!MEM_P (operands[0])
17953 || !memory_displacement_operand (operands[0], <MODE>mode)))
17954 || (TARGET_NOT_VECTORMODE
17955 && long_memory_operand (operands[0], <MODE>mode)))
17956 && peep2_regno_dead_p (0, FLAGS_REG)"
17957 [(parallel [(set (match_dup 0)
17958 (xor:SWI124 (match_dup 1) (const_int -1)))
17959 (clobber (reg:CC FLAGS_REG))])])
17961 ;; Non pairable "test imm, reg" instructions can be translated to
17962 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17963 ;; byte opcode instead of two, have a short form for byte operands),
17964 ;; so do it for other CPUs as well. Given that the value was dead,
17965 ;; this should not create any new dependencies. Pass on the sub-word
17966 ;; versions if we're concerned about partial register stalls.
17969 [(set (match_operand 0 "flags_reg_operand")
17970 (match_operator 1 "compare_operator"
17971 [(and:SI (match_operand:SI 2 "register_operand")
17972 (match_operand:SI 3 "immediate_operand"))
17974 "ix86_match_ccmode (insn, CCNOmode)
17975 && (true_regnum (operands[2]) != AX_REG
17976 || satisfies_constraint_K (operands[3]))
17977 && peep2_reg_dead_p (1, operands[2])"
17979 [(set (match_dup 0)
17980 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17983 (and:SI (match_dup 2) (match_dup 3)))])])
17985 ;; We don't need to handle HImode case, because it will be promoted to SImode
17986 ;; on ! TARGET_PARTIAL_REG_STALL
17989 [(set (match_operand 0 "flags_reg_operand")
17990 (match_operator 1 "compare_operator"
17991 [(and:QI (match_operand:QI 2 "register_operand")
17992 (match_operand:QI 3 "immediate_operand"))
17994 "! TARGET_PARTIAL_REG_STALL
17995 && ix86_match_ccmode (insn, CCNOmode)
17996 && true_regnum (operands[2]) != AX_REG
17997 && peep2_reg_dead_p (1, operands[2])"
17999 [(set (match_dup 0)
18000 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18003 (and:QI (match_dup 2) (match_dup 3)))])])
18006 [(set (match_operand 0 "flags_reg_operand")
18007 (match_operator 1 "compare_operator"
18010 (match_operand 2 "QIreg_operand")
18013 (match_operand 3 "const_int_operand"))
18015 "! TARGET_PARTIAL_REG_STALL
18016 && ix86_match_ccmode (insn, CCNOmode)
18017 && true_regnum (operands[2]) != AX_REG
18018 && peep2_reg_dead_p (1, operands[2])"
18019 [(parallel [(set (match_dup 0)
18028 (set (zero_extract:SI (match_dup 2)
18036 (match_dup 3)))])])
18038 ;; Don't do logical operations with memory inputs.
18040 [(match_scratch:SI 2 "r")
18041 (parallel [(set (match_operand:SI 0 "register_operand")
18042 (match_operator:SI 3 "arith_or_logical_operator"
18044 (match_operand:SI 1 "memory_operand")]))
18045 (clobber (reg:CC FLAGS_REG))])]
18046 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18047 [(set (match_dup 2) (match_dup 1))
18048 (parallel [(set (match_dup 0)
18049 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18050 (clobber (reg:CC FLAGS_REG))])])
18053 [(match_scratch:SI 2 "r")
18054 (parallel [(set (match_operand:SI 0 "register_operand")
18055 (match_operator:SI 3 "arith_or_logical_operator"
18056 [(match_operand:SI 1 "memory_operand")
18058 (clobber (reg:CC FLAGS_REG))])]
18059 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18060 [(set (match_dup 2) (match_dup 1))
18061 (parallel [(set (match_dup 0)
18062 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18063 (clobber (reg:CC FLAGS_REG))])])
18065 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
18066 ;; refers to the destination of the load!
18069 [(set (match_operand:SI 0 "register_operand")
18070 (match_operand:SI 1 "register_operand"))
18071 (parallel [(set (match_dup 0)
18072 (match_operator:SI 3 "commutative_operator"
18074 (match_operand:SI 2 "memory_operand")]))
18075 (clobber (reg:CC FLAGS_REG))])]
18076 "REGNO (operands[0]) != REGNO (operands[1])
18077 && GENERAL_REGNO_P (REGNO (operands[0]))
18078 && GENERAL_REGNO_P (REGNO (operands[1]))"
18079 [(set (match_dup 0) (match_dup 4))
18080 (parallel [(set (match_dup 0)
18081 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
18082 (clobber (reg:CC FLAGS_REG))])]
18083 "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
18086 [(set (match_operand 0 "register_operand")
18087 (match_operand 1 "register_operand"))
18089 (match_operator 3 "commutative_operator"
18091 (match_operand 2 "memory_operand")]))]
18092 "REGNO (operands[0]) != REGNO (operands[1])
18093 && ((MMX_REGNO_P (REGNO (operands[0]))
18094 && MMX_REGNO_P (REGNO (operands[1])))
18095 || (SSE_REGNO_P (REGNO (operands[0]))
18096 && SSE_REGNO_P (REGNO (operands[1]))))"
18097 [(set (match_dup 0) (match_dup 2))
18099 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18101 ; Don't do logical operations with memory outputs
18103 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18104 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
18105 ; the same decoder scheduling characteristics as the original.
18108 [(match_scratch:SI 2 "r")
18109 (parallel [(set (match_operand:SI 0 "memory_operand")
18110 (match_operator:SI 3 "arith_or_logical_operator"
18112 (match_operand:SI 1 "nonmemory_operand")]))
18113 (clobber (reg:CC FLAGS_REG))])]
18114 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18115 /* Do not split stack checking probes. */
18116 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
18117 [(set (match_dup 2) (match_dup 0))
18118 (parallel [(set (match_dup 2)
18119 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18120 (clobber (reg:CC FLAGS_REG))])
18121 (set (match_dup 0) (match_dup 2))])
18124 [(match_scratch:SI 2 "r")
18125 (parallel [(set (match_operand:SI 0 "memory_operand")
18126 (match_operator:SI 3 "arith_or_logical_operator"
18127 [(match_operand:SI 1 "nonmemory_operand")
18129 (clobber (reg:CC FLAGS_REG))])]
18130 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18131 /* Do not split stack checking probes. */
18132 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
18133 [(set (match_dup 2) (match_dup 0))
18134 (parallel [(set (match_dup 2)
18135 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18136 (clobber (reg:CC FLAGS_REG))])
18137 (set (match_dup 0) (match_dup 2))])
18139 ;; Attempt to use arith or logical operations with memory outputs with
18140 ;; setting of flags.
18142 [(set (match_operand:SWI 0 "register_operand")
18143 (match_operand:SWI 1 "memory_operand"))
18144 (parallel [(set (match_dup 0)
18145 (match_operator:SWI 3 "plusminuslogic_operator"
18147 (match_operand:SWI 2 "<nonmemory_operand>")]))
18148 (clobber (reg:CC FLAGS_REG))])
18149 (set (match_dup 1) (match_dup 0))
18150 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18151 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18152 && peep2_reg_dead_p (4, operands[0])
18153 && !reg_overlap_mentioned_p (operands[0], operands[1])
18154 && !reg_overlap_mentioned_p (operands[0], operands[2])
18155 && (<MODE>mode != QImode
18156 || immediate_operand (operands[2], QImode)
18157 || any_QIreg_operand (operands[2], QImode))
18158 && ix86_match_ccmode (peep2_next_insn (3),
18159 (GET_CODE (operands[3]) == PLUS
18160 || GET_CODE (operands[3]) == MINUS)
18161 ? CCGOCmode : CCNOmode)"
18162 [(parallel [(set (match_dup 4) (match_dup 5))
18163 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
18164 (match_dup 2)]))])]
18166 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18167 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18168 copy_rtx (operands[1]),
18169 copy_rtx (operands[2]));
18170 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
18171 operands[5], const0_rtx);
18175 [(parallel [(set (match_operand:SWI 0 "register_operand")
18176 (match_operator:SWI 2 "plusminuslogic_operator"
18178 (match_operand:SWI 1 "memory_operand")]))
18179 (clobber (reg:CC FLAGS_REG))])
18180 (set (match_dup 1) (match_dup 0))
18181 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18182 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18183 && GET_CODE (operands[2]) != MINUS
18184 && peep2_reg_dead_p (3, operands[0])
18185 && !reg_overlap_mentioned_p (operands[0], operands[1])
18186 && ix86_match_ccmode (peep2_next_insn (2),
18187 GET_CODE (operands[2]) == PLUS
18188 ? CCGOCmode : CCNOmode)"
18189 [(parallel [(set (match_dup 3) (match_dup 4))
18190 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
18191 (match_dup 0)]))])]
18193 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
18194 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
18195 copy_rtx (operands[1]),
18196 copy_rtx (operands[0]));
18197 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
18198 operands[4], const0_rtx);
18202 [(set (match_operand:SWI12 0 "register_operand")
18203 (match_operand:SWI12 1 "memory_operand"))
18204 (parallel [(set (match_operand:SI 4 "register_operand")
18205 (match_operator:SI 3 "plusminuslogic_operator"
18207 (match_operand:SI 2 "nonmemory_operand")]))
18208 (clobber (reg:CC FLAGS_REG))])
18209 (set (match_dup 1) (match_dup 0))
18210 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18211 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18212 && REG_P (operands[0]) && REG_P (operands[4])
18213 && REGNO (operands[0]) == REGNO (operands[4])
18214 && peep2_reg_dead_p (4, operands[0])
18215 && (<MODE>mode != QImode
18216 || immediate_operand (operands[2], SImode)
18217 || any_QIreg_operand (operands[2], SImode))
18218 && !reg_overlap_mentioned_p (operands[0], operands[1])
18219 && !reg_overlap_mentioned_p (operands[0], operands[2])
18220 && ix86_match_ccmode (peep2_next_insn (3),
18221 (GET_CODE (operands[3]) == PLUS
18222 || GET_CODE (operands[3]) == MINUS)
18223 ? CCGOCmode : CCNOmode)"
18224 [(parallel [(set (match_dup 4) (match_dup 5))
18225 (set (match_dup 1) (match_dup 6))])]
18227 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
18228 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18229 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18230 copy_rtx (operands[1]), operands[2]);
18231 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
18232 operands[5], const0_rtx);
18233 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18234 copy_rtx (operands[1]),
18235 copy_rtx (operands[2]));
18238 ;; Attempt to always use XOR for zeroing registers.
18240 [(set (match_operand 0 "register_operand")
18241 (match_operand 1 "const0_operand"))]
18242 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18243 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18244 && GENERAL_REGNO_P (REGNO (operands[0]))
18245 && peep2_regno_dead_p (0, FLAGS_REG)"
18246 [(parallel [(set (match_dup 0) (const_int 0))
18247 (clobber (reg:CC FLAGS_REG))])]
18248 "operands[0] = gen_lowpart (word_mode, operands[0]);")
18251 [(set (strict_low_part (match_operand 0 "register_operand"))
18253 "(GET_MODE (operands[0]) == QImode
18254 || GET_MODE (operands[0]) == HImode)
18255 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18256 && peep2_regno_dead_p (0, FLAGS_REG)"
18257 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18258 (clobber (reg:CC FLAGS_REG))])])
18260 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
18262 [(set (match_operand:SWI248 0 "register_operand")
18264 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
18265 && GENERAL_REGNO_P (REGNO (operands[0]))
18266 && peep2_regno_dead_p (0, FLAGS_REG)"
18267 [(parallel [(set (match_dup 0) (const_int -1))
18268 (clobber (reg:CC FLAGS_REG))])]
18270 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
18271 operands[0] = gen_lowpart (SImode, operands[0]);
18274 ;; Attempt to convert simple lea to add/shift.
18275 ;; These can be created by move expanders.
18276 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
18277 ;; relevant lea instructions were already split.
18280 [(set (match_operand:SWI48 0 "register_operand")
18281 (plus:SWI48 (match_dup 0)
18282 (match_operand:SWI48 1 "<nonmemory_operand>")))]
18284 && peep2_regno_dead_p (0, FLAGS_REG)"
18285 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18286 (clobber (reg:CC FLAGS_REG))])])
18289 [(set (match_operand:SWI48 0 "register_operand")
18290 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
18293 && peep2_regno_dead_p (0, FLAGS_REG)"
18294 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18295 (clobber (reg:CC FLAGS_REG))])])
18298 [(set (match_operand:DI 0 "register_operand")
18300 (plus:SI (match_operand:SI 1 "register_operand")
18301 (match_operand:SI 2 "nonmemory_operand"))))]
18302 "TARGET_64BIT && !TARGET_OPT_AGU
18303 && REGNO (operands[0]) == REGNO (operands[1])
18304 && peep2_regno_dead_p (0, FLAGS_REG)"
18305 [(parallel [(set (match_dup 0)
18306 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
18307 (clobber (reg:CC FLAGS_REG))])])
18310 [(set (match_operand:DI 0 "register_operand")
18312 (plus:SI (match_operand:SI 1 "nonmemory_operand")
18313 (match_operand:SI 2 "register_operand"))))]
18314 "TARGET_64BIT && !TARGET_OPT_AGU
18315 && REGNO (operands[0]) == REGNO (operands[2])
18316 && peep2_regno_dead_p (0, FLAGS_REG)"
18317 [(parallel [(set (match_dup 0)
18318 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
18319 (clobber (reg:CC FLAGS_REG))])])
18322 [(set (match_operand:SWI48 0 "register_operand")
18323 (mult:SWI48 (match_dup 0)
18324 (match_operand:SWI48 1 "const_int_operand")))]
18325 "exact_log2 (INTVAL (operands[1])) >= 0
18326 && peep2_regno_dead_p (0, FLAGS_REG)"
18327 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
18328 (clobber (reg:CC FLAGS_REG))])]
18329 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18332 [(set (match_operand:DI 0 "register_operand")
18334 (mult:SI (match_operand:SI 1 "register_operand")
18335 (match_operand:SI 2 "const_int_operand"))))]
18337 && exact_log2 (INTVAL (operands[2])) >= 0
18338 && REGNO (operands[0]) == REGNO (operands[1])
18339 && peep2_regno_dead_p (0, FLAGS_REG)"
18340 [(parallel [(set (match_dup 0)
18341 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
18342 (clobber (reg:CC FLAGS_REG))])]
18343 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18345 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18346 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
18347 ;; On many CPUs it is also faster, since special hardware to avoid esp
18348 ;; dependencies is present.
18350 ;; While some of these conversions may be done using splitters, we use
18351 ;; peepholes in order to allow combine_stack_adjustments pass to see
18352 ;; nonobfuscated RTL.
18354 ;; Convert prologue esp subtractions to push.
18355 ;; We need register to push. In order to keep verify_flow_info happy we have
18357 ;; - use scratch and clobber it in order to avoid dependencies
18358 ;; - use already live register
18359 ;; We can't use the second way right now, since there is no reliable way how to
18360 ;; verify that given register is live. First choice will also most likely in
18361 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18362 ;; call clobbered registers are dead. We may want to use base pointer as an
18363 ;; alternative when no register is available later.
18366 [(match_scratch:W 1 "r")
18367 (parallel [(set (reg:P SP_REG)
18368 (plus:P (reg:P SP_REG)
18369 (match_operand:P 0 "const_int_operand")))
18370 (clobber (reg:CC FLAGS_REG))
18371 (clobber (mem:BLK (scratch)))])]
18372 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18373 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
18374 && !ix86_using_red_zone ()"
18375 [(clobber (match_dup 1))
18376 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18377 (clobber (mem:BLK (scratch)))])])
18380 [(match_scratch:W 1 "r")
18381 (parallel [(set (reg:P SP_REG)
18382 (plus:P (reg:P SP_REG)
18383 (match_operand:P 0 "const_int_operand")))
18384 (clobber (reg:CC FLAGS_REG))
18385 (clobber (mem:BLK (scratch)))])]
18386 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
18387 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
18388 && !ix86_using_red_zone ()"
18389 [(clobber (match_dup 1))
18390 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18391 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18392 (clobber (mem:BLK (scratch)))])])
18394 ;; Convert esp subtractions to push.
18396 [(match_scratch:W 1 "r")
18397 (parallel [(set (reg:P SP_REG)
18398 (plus:P (reg:P SP_REG)
18399 (match_operand:P 0 "const_int_operand")))
18400 (clobber (reg:CC FLAGS_REG))])]
18401 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18402 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
18403 && !ix86_using_red_zone ()"
18404 [(clobber (match_dup 1))
18405 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
18408 [(match_scratch:W 1 "r")
18409 (parallel [(set (reg:P SP_REG)
18410 (plus:P (reg:P SP_REG)
18411 (match_operand:P 0 "const_int_operand")))
18412 (clobber (reg:CC FLAGS_REG))])]
18413 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
18414 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
18415 && !ix86_using_red_zone ()"
18416 [(clobber (match_dup 1))
18417 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18418 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
18420 ;; Convert epilogue deallocator to pop.
18422 [(match_scratch:W 1 "r")
18423 (parallel [(set (reg:P SP_REG)
18424 (plus:P (reg:P SP_REG)
18425 (match_operand:P 0 "const_int_operand")))
18426 (clobber (reg:CC FLAGS_REG))
18427 (clobber (mem:BLK (scratch)))])]
18428 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
18429 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
18430 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18431 (clobber (mem:BLK (scratch)))])])
18433 ;; Two pops case is tricky, since pop causes dependency
18434 ;; on destination register. We use two registers if available.
18436 [(match_scratch:W 1 "r")
18437 (match_scratch:W 2 "r")
18438 (parallel [(set (reg:P SP_REG)
18439 (plus:P (reg:P SP_REG)
18440 (match_operand:P 0 "const_int_operand")))
18441 (clobber (reg:CC FLAGS_REG))
18442 (clobber (mem:BLK (scratch)))])]
18443 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
18444 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18445 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18446 (clobber (mem:BLK (scratch)))])
18447 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
18450 [(match_scratch:W 1 "r")
18451 (parallel [(set (reg:P SP_REG)
18452 (plus:P (reg:P SP_REG)
18453 (match_operand:P 0 "const_int_operand")))
18454 (clobber (reg:CC FLAGS_REG))
18455 (clobber (mem:BLK (scratch)))])]
18456 "optimize_insn_for_size_p ()
18457 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18458 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18459 (clobber (mem:BLK (scratch)))])
18460 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18462 ;; Convert esp additions to pop.
18464 [(match_scratch:W 1 "r")
18465 (parallel [(set (reg:P SP_REG)
18466 (plus:P (reg:P SP_REG)
18467 (match_operand:P 0 "const_int_operand")))
18468 (clobber (reg:CC FLAGS_REG))])]
18469 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
18470 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18472 ;; Two pops case is tricky, since pop causes dependency
18473 ;; on destination register. We use two registers if available.
18475 [(match_scratch:W 1 "r")
18476 (match_scratch:W 2 "r")
18477 (parallel [(set (reg:P SP_REG)
18478 (plus:P (reg:P SP_REG)
18479 (match_operand:P 0 "const_int_operand")))
18480 (clobber (reg:CC FLAGS_REG))])]
18481 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18482 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18483 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
18486 [(match_scratch:W 1 "r")
18487 (parallel [(set (reg:P SP_REG)
18488 (plus:P (reg:P SP_REG)
18489 (match_operand:P 0 "const_int_operand")))
18490 (clobber (reg:CC FLAGS_REG))])]
18491 "optimize_insn_for_size_p ()
18492 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18493 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18494 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18496 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18497 ;; required and register dies. Similarly for 128 to -128.
18499 [(set (match_operand 0 "flags_reg_operand")
18500 (match_operator 1 "compare_operator"
18501 [(match_operand 2 "register_operand")
18502 (match_operand 3 "const_int_operand")]))]
18503 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
18504 && incdec_operand (operands[3], GET_MODE (operands[3])))
18505 || (!TARGET_FUSE_CMP_AND_BRANCH
18506 && INTVAL (operands[3]) == 128))
18507 && ix86_match_ccmode (insn, CCGCmode)
18508 && peep2_reg_dead_p (1, operands[2])"
18509 [(parallel [(set (match_dup 0)
18510 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18511 (clobber (match_dup 2))])])
18513 ;; Convert imul by three, five and nine into lea
18516 [(set (match_operand:SWI48 0 "register_operand")
18517 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
18518 (match_operand:SWI48 2 "const359_operand")))
18519 (clobber (reg:CC FLAGS_REG))])]
18520 "!TARGET_PARTIAL_REG_STALL
18521 || <MODE>mode == SImode
18522 || optimize_function_for_size_p (cfun)"
18523 [(set (match_dup 0)
18524 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
18526 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18530 [(set (match_operand:SWI48 0 "register_operand")
18531 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
18532 (match_operand:SWI48 2 "const359_operand")))
18533 (clobber (reg:CC FLAGS_REG))])]
18534 "optimize_insn_for_speed_p ()
18535 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
18536 [(set (match_dup 0) (match_dup 1))
18538 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
18540 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18542 ;; imul $32bit_imm, mem, reg is vector decoded, while
18543 ;; imul $32bit_imm, reg, reg is direct decoded.
18545 [(match_scratch:SWI48 3 "r")
18546 (parallel [(set (match_operand:SWI48 0 "register_operand")
18547 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
18548 (match_operand:SWI48 2 "immediate_operand")))
18549 (clobber (reg:CC FLAGS_REG))])]
18550 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18551 && !satisfies_constraint_K (operands[2])"
18552 [(set (match_dup 3) (match_dup 1))
18553 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
18554 (clobber (reg:CC FLAGS_REG))])])
18557 [(match_scratch:SI 3 "r")
18558 (parallel [(set (match_operand:DI 0 "register_operand")
18560 (mult:SI (match_operand:SI 1 "memory_operand")
18561 (match_operand:SI 2 "immediate_operand"))))
18562 (clobber (reg:CC FLAGS_REG))])]
18564 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18565 && !satisfies_constraint_K (operands[2])"
18566 [(set (match_dup 3) (match_dup 1))
18567 (parallel [(set (match_dup 0)
18568 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18569 (clobber (reg:CC FLAGS_REG))])])
18571 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18572 ;; Convert it into imul reg, reg
18573 ;; It would be better to force assembler to encode instruction using long
18574 ;; immediate, but there is apparently no way to do so.
18576 [(parallel [(set (match_operand:SWI248 0 "register_operand")
18578 (match_operand:SWI248 1 "nonimmediate_operand")
18579 (match_operand:SWI248 2 "const_int_operand")))
18580 (clobber (reg:CC FLAGS_REG))])
18581 (match_scratch:SWI248 3 "r")]
18582 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18583 && satisfies_constraint_K (operands[2])"
18584 [(set (match_dup 3) (match_dup 2))
18585 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
18586 (clobber (reg:CC FLAGS_REG))])]
18588 if (!rtx_equal_p (operands[0], operands[1]))
18589 emit_move_insn (operands[0], operands[1]);
18592 ;; After splitting up read-modify operations, array accesses with memory
18593 ;; operands might end up in form:
18595 ;; movl 4(%esp), %edx
18597 ;; instead of pre-splitting:
18599 ;; addl 4(%esp), %eax
18601 ;; movl 4(%esp), %edx
18602 ;; leal (%edx,%eax,4), %eax
18605 [(match_scratch:W 5 "r")
18606 (parallel [(set (match_operand 0 "register_operand")
18607 (ashift (match_operand 1 "register_operand")
18608 (match_operand 2 "const_int_operand")))
18609 (clobber (reg:CC FLAGS_REG))])
18610 (parallel [(set (match_operand 3 "register_operand")
18611 (plus (match_dup 0)
18612 (match_operand 4 "x86_64_general_operand")))
18613 (clobber (reg:CC FLAGS_REG))])]
18614 "IN_RANGE (INTVAL (operands[2]), 1, 3)
18615 /* Validate MODE for lea. */
18616 && ((!TARGET_PARTIAL_REG_STALL
18617 && (GET_MODE (operands[0]) == QImode
18618 || GET_MODE (operands[0]) == HImode))
18619 || GET_MODE (operands[0]) == SImode
18620 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18621 && (rtx_equal_p (operands[0], operands[3])
18622 || peep2_reg_dead_p (2, operands[0]))
18623 /* We reorder load and the shift. */
18624 && !reg_overlap_mentioned_p (operands[0], operands[4])"
18625 [(set (match_dup 5) (match_dup 4))
18626 (set (match_dup 0) (match_dup 1))]
18628 machine_mode op1mode = GET_MODE (operands[1]);
18629 machine_mode mode = op1mode == DImode ? DImode : SImode;
18630 int scale = 1 << INTVAL (operands[2]);
18631 rtx index = gen_lowpart (word_mode, operands[1]);
18632 rtx base = gen_lowpart (word_mode, operands[5]);
18633 rtx dest = gen_lowpart (mode, operands[3]);
18635 operands[1] = gen_rtx_PLUS (word_mode, base,
18636 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
18637 if (mode != word_mode)
18638 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18640 operands[5] = base;
18641 if (op1mode != word_mode)
18642 operands[5] = gen_lowpart (op1mode, operands[5]);
18644 operands[0] = dest;
18647 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18648 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18649 ;; caught for use by garbage collectors and the like. Using an insn that
18650 ;; maps to SIGILL makes it more likely the program will rightfully die.
18651 ;; Keeping with tradition, "6" is in honor of #UD.
18652 (define_insn "trap"
18653 [(trap_if (const_int 1) (const_int 6))]
18656 #ifdef HAVE_AS_IX86_UD2
18659 return ASM_SHORT "0x0b0f";
18662 [(set_attr "length" "2")])
18664 (define_expand "prefetch"
18665 [(prefetch (match_operand 0 "address_operand")
18666 (match_operand:SI 1 "const_int_operand")
18667 (match_operand:SI 2 "const_int_operand"))]
18668 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18670 bool write = INTVAL (operands[1]) != 0;
18671 int locality = INTVAL (operands[2]);
18673 gcc_assert (IN_RANGE (locality, 0, 3));
18675 /* Use 3dNOW prefetch in case we are asking for write prefetch not
18676 supported by SSE counterpart (non-SSE2 athlon machines) or the
18677 SSE prefetch is not available (K6 machines). Otherwise use SSE
18678 prefetch as it allows specifying of locality. */
18682 if (TARGET_PREFETCHWT1)
18683 operands[2] = GEN_INT (MAX (locality, 2));
18684 else if (TARGET_PRFCHW)
18685 operands[2] = GEN_INT (3);
18686 else if (TARGET_3DNOW && !TARGET_SSE2)
18687 operands[2] = GEN_INT (3);
18688 else if (TARGET_PREFETCH_SSE)
18689 operands[1] = const0_rtx;
18692 gcc_assert (TARGET_3DNOW);
18693 operands[2] = GEN_INT (3);
18698 if (TARGET_PREFETCH_SSE)
18702 gcc_assert (TARGET_3DNOW);
18703 operands[2] = GEN_INT (3);
18708 (define_insn "*prefetch_sse"
18709 [(prefetch (match_operand 0 "address_operand" "p")
18711 (match_operand:SI 1 "const_int_operand"))]
18712 "TARGET_PREFETCH_SSE"
18714 static const char * const patterns[4] = {
18715 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18718 int locality = INTVAL (operands[1]);
18719 gcc_assert (IN_RANGE (locality, 0, 3));
18721 return patterns[locality];
18723 [(set_attr "type" "sse")
18724 (set_attr "atom_sse_attr" "prefetch")
18725 (set (attr "length_address")
18726 (symbol_ref "memory_address_length (operands[0], false)"))
18727 (set_attr "memory" "none")])
18729 (define_insn "*prefetch_3dnow"
18730 [(prefetch (match_operand 0 "address_operand" "p")
18731 (match_operand:SI 1 "const_int_operand" "n")
18733 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18735 if (INTVAL (operands[1]) == 0)
18736 return "prefetch\t%a0";
18738 return "prefetchw\t%a0";
18740 [(set_attr "type" "mmx")
18741 (set (attr "length_address")
18742 (symbol_ref "memory_address_length (operands[0], false)"))
18743 (set_attr "memory" "none")])
18745 (define_insn "*prefetch_prefetchwt1"
18746 [(prefetch (match_operand 0 "address_operand" "p")
18749 "TARGET_PREFETCHWT1"
18750 "prefetchwt1\t%a0";
18751 [(set_attr "type" "sse")
18752 (set (attr "length_address")
18753 (symbol_ref "memory_address_length (operands[0], false)"))
18754 (set_attr "memory" "none")])
18756 (define_expand "stack_protect_set"
18757 [(match_operand 0 "memory_operand")
18758 (match_operand 1 "memory_operand")]
18759 "TARGET_SSP_TLS_GUARD"
18761 rtx (*insn)(rtx, rtx);
18763 #ifdef TARGET_THREAD_SSP_OFFSET
18764 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18765 insn = (TARGET_LP64
18766 ? gen_stack_tls_protect_set_di
18767 : gen_stack_tls_protect_set_si);
18769 insn = (TARGET_LP64
18770 ? gen_stack_protect_set_di
18771 : gen_stack_protect_set_si);
18774 emit_insn (insn (operands[0], operands[1]));
18778 (define_insn "stack_protect_set_<mode>"
18779 [(set (match_operand:PTR 0 "memory_operand" "=m")
18780 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18782 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18783 (clobber (reg:CC FLAGS_REG))]
18784 "TARGET_SSP_TLS_GUARD"
18785 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18786 [(set_attr "type" "multi")])
18788 (define_insn "stack_tls_protect_set_<mode>"
18789 [(set (match_operand:PTR 0 "memory_operand" "=m")
18790 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
18791 UNSPEC_SP_TLS_SET))
18792 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18793 (clobber (reg:CC FLAGS_REG))]
18795 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18796 [(set_attr "type" "multi")])
18798 (define_expand "stack_protect_test"
18799 [(match_operand 0 "memory_operand")
18800 (match_operand 1 "memory_operand")
18802 "TARGET_SSP_TLS_GUARD"
18804 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18806 rtx (*insn)(rtx, rtx, rtx);
18808 #ifdef TARGET_THREAD_SSP_OFFSET
18809 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18810 insn = (TARGET_LP64
18811 ? gen_stack_tls_protect_test_di
18812 : gen_stack_tls_protect_test_si);
18814 insn = (TARGET_LP64
18815 ? gen_stack_protect_test_di
18816 : gen_stack_protect_test_si);
18819 emit_insn (insn (flags, operands[0], operands[1]));
18821 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18822 flags, const0_rtx, operands[2]));
18826 (define_insn "stack_protect_test_<mode>"
18827 [(set (match_operand:CCZ 0 "flags_reg_operand")
18828 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18829 (match_operand:PTR 2 "memory_operand" "m")]
18831 (clobber (match_scratch:PTR 3 "=&r"))]
18832 "TARGET_SSP_TLS_GUARD"
18833 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18834 [(set_attr "type" "multi")])
18836 (define_insn "stack_tls_protect_test_<mode>"
18837 [(set (match_operand:CCZ 0 "flags_reg_operand")
18838 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18839 (match_operand:PTR 2 "const_int_operand" "i")]
18840 UNSPEC_SP_TLS_TEST))
18841 (clobber (match_scratch:PTR 3 "=r"))]
18843 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18844 [(set_attr "type" "multi")])
18846 (define_insn "sse4_2_crc32<mode>"
18847 [(set (match_operand:SI 0 "register_operand" "=r")
18849 [(match_operand:SI 1 "register_operand" "0")
18850 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18852 "TARGET_SSE4_2 || TARGET_CRC32"
18853 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18854 [(set_attr "type" "sselog1")
18855 (set_attr "prefix_rep" "1")
18856 (set_attr "prefix_extra" "1")
18857 (set (attr "prefix_data16")
18858 (if_then_else (match_operand:HI 2)
18860 (const_string "*")))
18861 (set (attr "prefix_rex")
18862 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18864 (const_string "*")))
18865 (set_attr "mode" "SI")])
18867 (define_insn "sse4_2_crc32di"
18868 [(set (match_operand:DI 0 "register_operand" "=r")
18870 [(match_operand:DI 1 "register_operand" "0")
18871 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18873 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18874 "crc32{q}\t{%2, %0|%0, %2}"
18875 [(set_attr "type" "sselog1")
18876 (set_attr "prefix_rep" "1")
18877 (set_attr "prefix_extra" "1")
18878 (set_attr "mode" "DI")])
18880 (define_insn "rdpmc"
18881 [(set (match_operand:DI 0 "register_operand" "=A")
18882 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18886 [(set_attr "type" "other")
18887 (set_attr "length" "2")])
18889 (define_insn "rdpmc_rex64"
18890 [(set (match_operand:DI 0 "register_operand" "=a")
18891 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18893 (set (match_operand:DI 1 "register_operand" "=d")
18894 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18897 [(set_attr "type" "other")
18898 (set_attr "length" "2")])
18900 (define_insn "rdtsc"
18901 [(set (match_operand:DI 0 "register_operand" "=A")
18902 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18905 [(set_attr "type" "other")
18906 (set_attr "length" "2")])
18908 (define_insn "rdtsc_rex64"
18909 [(set (match_operand:DI 0 "register_operand" "=a")
18910 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18911 (set (match_operand:DI 1 "register_operand" "=d")
18912 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18915 [(set_attr "type" "other")
18916 (set_attr "length" "2")])
18918 (define_insn "rdtscp"
18919 [(set (match_operand:DI 0 "register_operand" "=A")
18920 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18921 (set (match_operand:SI 1 "register_operand" "=c")
18922 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18925 [(set_attr "type" "other")
18926 (set_attr "length" "3")])
18928 (define_insn "rdtscp_rex64"
18929 [(set (match_operand:DI 0 "register_operand" "=a")
18930 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18931 (set (match_operand:DI 1 "register_operand" "=d")
18932 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18933 (set (match_operand:SI 2 "register_operand" "=c")
18934 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18937 [(set_attr "type" "other")
18938 (set_attr "length" "3")])
18940 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18942 ;; FXSR, XSAVE and XSAVEOPT instructions
18944 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18946 (define_insn "fxsave"
18947 [(set (match_operand:BLK 0 "memory_operand" "=m")
18948 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18951 [(set_attr "type" "other")
18952 (set_attr "memory" "store")
18953 (set (attr "length")
18954 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18956 (define_insn "fxsave64"
18957 [(set (match_operand:BLK 0 "memory_operand" "=m")
18958 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18959 "TARGET_64BIT && TARGET_FXSR"
18961 [(set_attr "type" "other")
18962 (set_attr "memory" "store")
18963 (set (attr "length")
18964 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18966 (define_insn "fxrstor"
18967 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18971 [(set_attr "type" "other")
18972 (set_attr "memory" "load")
18973 (set (attr "length")
18974 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18976 (define_insn "fxrstor64"
18977 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18978 UNSPECV_FXRSTOR64)]
18979 "TARGET_64BIT && TARGET_FXSR"
18981 [(set_attr "type" "other")
18982 (set_attr "memory" "load")
18983 (set (attr "length")
18984 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18986 (define_int_iterator ANY_XSAVE
18988 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18989 (UNSPECV_XSAVEC "TARGET_XSAVEC")
18990 (UNSPECV_XSAVES "TARGET_XSAVES")])
18992 (define_int_iterator ANY_XSAVE64
18994 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18995 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18996 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18998 (define_int_attr xsave
18999 [(UNSPECV_XSAVE "xsave")
19000 (UNSPECV_XSAVE64 "xsave64")
19001 (UNSPECV_XSAVEOPT "xsaveopt")
19002 (UNSPECV_XSAVEOPT64 "xsaveopt64")
19003 (UNSPECV_XSAVEC "xsavec")
19004 (UNSPECV_XSAVEC64 "xsavec64")
19005 (UNSPECV_XSAVES "xsaves")
19006 (UNSPECV_XSAVES64 "xsaves64")])
19008 (define_int_iterator ANY_XRSTOR
19010 (UNSPECV_XRSTORS "TARGET_XSAVES")])
19012 (define_int_iterator ANY_XRSTOR64
19014 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
19016 (define_int_attr xrstor
19017 [(UNSPECV_XRSTOR "xrstor")
19018 (UNSPECV_XRSTOR64 "xrstor")
19019 (UNSPECV_XRSTORS "xrstors")
19020 (UNSPECV_XRSTORS64 "xrstors")])
19022 (define_insn "<xsave>"
19023 [(set (match_operand:BLK 0 "memory_operand" "=m")
19024 (unspec_volatile:BLK
19025 [(match_operand:DI 1 "register_operand" "A")]
19027 "!TARGET_64BIT && TARGET_XSAVE"
19029 [(set_attr "type" "other")
19030 (set_attr "memory" "store")
19031 (set (attr "length")
19032 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19034 (define_insn "<xsave>_rex64"
19035 [(set (match_operand:BLK 0 "memory_operand" "=m")
19036 (unspec_volatile:BLK
19037 [(match_operand:SI 1 "register_operand" "a")
19038 (match_operand:SI 2 "register_operand" "d")]
19040 "TARGET_64BIT && TARGET_XSAVE"
19042 [(set_attr "type" "other")
19043 (set_attr "memory" "store")
19044 (set (attr "length")
19045 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19047 (define_insn "<xsave>"
19048 [(set (match_operand:BLK 0 "memory_operand" "=m")
19049 (unspec_volatile:BLK
19050 [(match_operand:SI 1 "register_operand" "a")
19051 (match_operand:SI 2 "register_operand" "d")]
19053 "TARGET_64BIT && TARGET_XSAVE"
19055 [(set_attr "type" "other")
19056 (set_attr "memory" "store")
19057 (set (attr "length")
19058 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19060 (define_insn "<xrstor>"
19061 [(unspec_volatile:BLK
19062 [(match_operand:BLK 0 "memory_operand" "m")
19063 (match_operand:DI 1 "register_operand" "A")]
19065 "!TARGET_64BIT && TARGET_XSAVE"
19067 [(set_attr "type" "other")
19068 (set_attr "memory" "load")
19069 (set (attr "length")
19070 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19072 (define_insn "<xrstor>_rex64"
19073 [(unspec_volatile:BLK
19074 [(match_operand:BLK 0 "memory_operand" "m")
19075 (match_operand:SI 1 "register_operand" "a")
19076 (match_operand:SI 2 "register_operand" "d")]
19078 "TARGET_64BIT && TARGET_XSAVE"
19080 [(set_attr "type" "other")
19081 (set_attr "memory" "load")
19082 (set (attr "length")
19083 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19085 (define_insn "<xrstor>64"
19086 [(unspec_volatile:BLK
19087 [(match_operand:BLK 0 "memory_operand" "m")
19088 (match_operand:SI 1 "register_operand" "a")
19089 (match_operand:SI 2 "register_operand" "d")]
19091 "TARGET_64BIT && TARGET_XSAVE"
19093 [(set_attr "type" "other")
19094 (set_attr "memory" "load")
19095 (set (attr "length")
19096 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19098 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19100 ;; Floating-point instructions for atomic compound assignments
19102 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19104 ; Clobber all floating-point registers on environment save and restore
19105 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
19106 (define_insn "fnstenv"
19107 [(set (match_operand:BLK 0 "memory_operand" "=m")
19108 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
19109 (clobber (reg:HI FPCR_REG))
19110 (clobber (reg:XF ST0_REG))
19111 (clobber (reg:XF ST1_REG))
19112 (clobber (reg:XF ST2_REG))
19113 (clobber (reg:XF ST3_REG))
19114 (clobber (reg:XF ST4_REG))
19115 (clobber (reg:XF ST5_REG))
19116 (clobber (reg:XF ST6_REG))
19117 (clobber (reg:XF ST7_REG))]
19120 [(set_attr "type" "other")
19121 (set_attr "memory" "store")
19122 (set (attr "length")
19123 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19125 (define_insn "fldenv"
19126 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19128 (clobber (reg:CCFP FPSR_REG))
19129 (clobber (reg:HI FPCR_REG))
19130 (clobber (reg:XF ST0_REG))
19131 (clobber (reg:XF ST1_REG))
19132 (clobber (reg:XF ST2_REG))
19133 (clobber (reg:XF ST3_REG))
19134 (clobber (reg:XF ST4_REG))
19135 (clobber (reg:XF ST5_REG))
19136 (clobber (reg:XF ST6_REG))
19137 (clobber (reg:XF ST7_REG))]
19140 [(set_attr "type" "other")
19141 (set_attr "memory" "load")
19142 (set (attr "length")
19143 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19145 (define_insn "fnstsw"
19146 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
19147 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
19150 [(set_attr "type" "other,other")
19151 (set_attr "memory" "none,store")
19152 (set (attr "length")
19153 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19155 (define_insn "fnclex"
19156 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
19159 [(set_attr "type" "other")
19160 (set_attr "memory" "none")
19161 (set_attr "length" "2")])
19163 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19165 ;; LWP instructions
19167 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19169 (define_expand "lwp_llwpcb"
19170 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
19171 UNSPECV_LLWP_INTRINSIC)]
19174 (define_insn "*lwp_llwpcb<mode>1"
19175 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
19176 UNSPECV_LLWP_INTRINSIC)]
19179 [(set_attr "type" "lwp")
19180 (set_attr "mode" "<MODE>")
19181 (set_attr "length" "5")])
19183 (define_expand "lwp_slwpcb"
19184 [(set (match_operand 0 "register_operand" "=r")
19185 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19190 insn = (Pmode == DImode
19192 : gen_lwp_slwpcbsi);
19194 emit_insn (insn (operands[0]));
19198 (define_insn "lwp_slwpcb<mode>"
19199 [(set (match_operand:P 0 "register_operand" "=r")
19200 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19203 [(set_attr "type" "lwp")
19204 (set_attr "mode" "<MODE>")
19205 (set_attr "length" "5")])
19207 (define_expand "lwp_lwpval<mode>3"
19208 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
19209 (match_operand:SI 2 "nonimmediate_operand" "rm")
19210 (match_operand:SI 3 "const_int_operand" "i")]
19211 UNSPECV_LWPVAL_INTRINSIC)]
19213 ;; Avoid unused variable warning.
19214 "(void) operands[0];")
19216 (define_insn "*lwp_lwpval<mode>3_1"
19217 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
19218 (match_operand:SI 1 "nonimmediate_operand" "rm")
19219 (match_operand:SI 2 "const_int_operand" "i")]
19220 UNSPECV_LWPVAL_INTRINSIC)]
19222 "lwpval\t{%2, %1, %0|%0, %1, %2}"
19223 [(set_attr "type" "lwp")
19224 (set_attr "mode" "<MODE>")
19225 (set (attr "length")
19226 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19228 (define_expand "lwp_lwpins<mode>3"
19229 [(set (reg:CCC FLAGS_REG)
19230 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
19231 (match_operand:SI 2 "nonimmediate_operand" "rm")
19232 (match_operand:SI 3 "const_int_operand" "i")]
19233 UNSPECV_LWPINS_INTRINSIC))
19234 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
19235 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
19238 (define_insn "*lwp_lwpins<mode>3_1"
19239 [(set (reg:CCC FLAGS_REG)
19240 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
19241 (match_operand:SI 1 "nonimmediate_operand" "rm")
19242 (match_operand:SI 2 "const_int_operand" "i")]
19243 UNSPECV_LWPINS_INTRINSIC))]
19245 "lwpins\t{%2, %1, %0|%0, %1, %2}"
19246 [(set_attr "type" "lwp")
19247 (set_attr "mode" "<MODE>")
19248 (set (attr "length")
19249 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19251 (define_int_iterator RDFSGSBASE
19255 (define_int_iterator WRFSGSBASE
19259 (define_int_attr fsgs
19260 [(UNSPECV_RDFSBASE "fs")
19261 (UNSPECV_RDGSBASE "gs")
19262 (UNSPECV_WRFSBASE "fs")
19263 (UNSPECV_WRGSBASE "gs")])
19265 (define_insn "rd<fsgs>base<mode>"
19266 [(set (match_operand:SWI48 0 "register_operand" "=r")
19267 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
19268 "TARGET_64BIT && TARGET_FSGSBASE"
19270 [(set_attr "type" "other")
19271 (set_attr "prefix_extra" "2")])
19273 (define_insn "wr<fsgs>base<mode>"
19274 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
19276 "TARGET_64BIT && TARGET_FSGSBASE"
19278 [(set_attr "type" "other")
19279 (set_attr "prefix_extra" "2")])
19281 (define_insn "rdrand<mode>_1"
19282 [(set (match_operand:SWI248 0 "register_operand" "=r")
19283 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
19284 (set (reg:CCC FLAGS_REG)
19285 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
19288 [(set_attr "type" "other")
19289 (set_attr "prefix_extra" "1")])
19291 (define_insn "rdseed<mode>_1"
19292 [(set (match_operand:SWI248 0 "register_operand" "=r")
19293 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
19294 (set (reg:CCC FLAGS_REG)
19295 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
19298 [(set_attr "type" "other")
19299 (set_attr "prefix_extra" "1")])
19301 (define_expand "pause"
19302 [(set (match_dup 0)
19303 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19306 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
19307 MEM_VOLATILE_P (operands[0]) = 1;
19310 ;; Use "rep; nop", instead of "pause", to support older assemblers.
19311 ;; They have the same encoding.
19312 (define_insn "*pause"
19313 [(set (match_operand:BLK 0)
19314 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19317 [(set_attr "length" "2")
19318 (set_attr "memory" "unknown")])
19320 (define_expand "xbegin"
19321 [(set (match_operand:SI 0 "register_operand")
19322 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
19325 rtx_code_label *label = gen_label_rtx ();
19327 /* xbegin is emitted as jump_insn, so reload won't be able
19328 to reload its operand. Force the value into AX hard register. */
19329 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
19330 emit_move_insn (ax_reg, constm1_rtx);
19332 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
19334 emit_label (label);
19335 LABEL_NUSES (label) = 1;
19337 emit_move_insn (operands[0], ax_reg);
19342 (define_insn "xbegin_1"
19344 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
19346 (label_ref (match_operand 1))
19348 (set (match_operand:SI 0 "register_operand" "+a")
19349 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
19352 [(set_attr "type" "other")
19353 (set_attr "length" "6")])
19355 (define_insn "xend"
19356 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
19359 [(set_attr "type" "other")
19360 (set_attr "length" "3")])
19362 (define_insn "xabort"
19363 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
19367 [(set_attr "type" "other")
19368 (set_attr "length" "3")])
19370 (define_expand "xtest"
19371 [(set (match_operand:QI 0 "register_operand")
19372 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
19375 emit_insn (gen_xtest_1 ());
19377 ix86_expand_setcc (operands[0], NE,
19378 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
19382 (define_insn "xtest_1"
19383 [(set (reg:CCZ FLAGS_REG)
19384 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
19387 [(set_attr "type" "other")
19388 (set_attr "length" "3")])
19390 (define_insn "clwb"
19391 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
19395 [(set_attr "type" "sse")
19396 (set_attr "atom_sse_attr" "fence")
19397 (set_attr "memory" "unknown")])
19399 (define_insn "clflushopt"
19400 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
19401 UNSPECV_CLFLUSHOPT)]
19402 "TARGET_CLFLUSHOPT"
19404 [(set_attr "type" "sse")
19405 (set_attr "atom_sse_attr" "fence")
19406 (set_attr "memory" "unknown")])
19408 ;; MONITORX and MWAITX
19409 (define_insn "mwaitx"
19410 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
19411 (match_operand:SI 1 "register_operand" "a")
19412 (match_operand:SI 2 "register_operand" "b")]
19415 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
19416 ;; Since 32bit register operands are implicitly zero extended to 64bit,
19417 ;; we only need to set up 32bit registers.
19419 [(set_attr "length" "3")])
19421 (define_insn "monitorx_<mode>"
19422 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
19423 (match_operand:SI 1 "register_operand" "c")
19424 (match_operand:SI 2 "register_operand" "d")]
19427 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
19428 ;; RCX and RDX are used. Since 32bit register operands are implicitly
19429 ;; zero extended to 64bit, we only need to set up 32bit registers.
19431 [(set (attr "length")
19432 (symbol_ref ("(Pmode != word_mode) + 3")))])
19435 (define_insn "clzero_<mode>"
19436 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
19440 [(set_attr "length" "3")
19441 (set_attr "memory" "unknown")])
19443 ;; MPX instructions
19445 (define_expand "<mode>_mk"
19446 [(set (match_operand:BND 0 "register_operand")
19450 [(match_operand:<bnd_ptr> 1 "register_operand")
19451 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
19455 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
19457 UNSPEC_BNDMK_ADDR);
19460 (define_insn "*<mode>_mk"
19461 [(set (match_operand:BND 0 "register_operand" "=w")
19463 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19465 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
19466 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
19467 UNSPEC_BNDMK_ADDR)])]
19470 "bndmk\t{%3, %0|%0, %3}"
19471 [(set_attr "type" "mpxmk")])
19473 (define_expand "mov<mode>"
19474 [(set (match_operand:BND 0 "general_operand")
19475 (match_operand:BND 1 "general_operand"))]
19477 "ix86_expand_move (<MODE>mode, operands); DONE;")
19479 (define_insn "*mov<mode>_internal_mpx"
19480 [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
19481 (match_operand:BND 1 "general_operand" "wm,w"))]
19483 "bndmov\t{%1, %0|%0, %1}"
19484 [(set_attr "type" "mpxmov")])
19486 (define_expand "<mode>_<bndcheck>"
19489 [(match_operand:BND 0 "register_operand")
19490 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
19492 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
19495 operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
19496 MEM_VOLATILE_P (operands[2]) = 1;
19499 (define_insn "*<mode>_<bndcheck>"
19501 [(match_operand:BND 0 "register_operand" "w")
19502 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
19503 (set (match_operand:BLK 2 "bnd_mem_operator")
19504 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))]
19506 "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
19507 [(set_attr "type" "mpxchk")])
19509 (define_expand "<mode>_ldx"
19511 [(set (match_operand:BND 0 "register_operand")
19515 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
19516 (match_operand:<bnd_ptr> 2 "register_operand")]))]
19518 (use (mem:BLK (match_dup 1)))])]
19521 /* Avoid registers which cannot be used as index. */
19522 if (!index_register_operand (operands[2], Pmode))
19523 operands[2] = copy_addr_to_reg (operands[2]);
19525 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
19527 UNSPEC_BNDLDX_ADDR);
19530 (define_insn "*<mode>_ldx"
19531 [(set (match_operand:BND 0 "register_operand" "=w")
19533 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19535 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
19536 (match_operand:<bnd_ptr> 2 "register_operand" "l")]
19537 UNSPEC_BNDLDX_ADDR)])]
19539 (use (mem:BLK (match_dup 1)))]
19541 "bndldx\t{%3, %0|%0, %3}"
19542 [(set_attr "type" "mpxld")])
19544 (define_expand "<mode>_stx"
19549 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
19550 (match_operand:<bnd_ptr> 1 "register_operand")]))
19551 (match_operand:BND 2 "register_operand")]
19554 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
19557 /* Avoid registers which cannot be used as index. */
19558 if (!index_register_operand (operands[1], Pmode))
19559 operands[1] = copy_addr_to_reg (operands[1]);
19561 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
19563 UNSPEC_BNDLDX_ADDR);
19564 operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
19565 MEM_VOLATILE_P (operands[4]) = 1;
19568 (define_insn "*<mode>_stx"
19570 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19572 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
19573 (match_operand:<bnd_ptr> 1 "register_operand" "l")]
19574 UNSPEC_BNDLDX_ADDR)])
19575 (match_operand:BND 2 "register_operand" "w")]
19577 (set (match_operand:BLK 4 "bnd_mem_operator")
19578 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))]
19580 "bndstx\t{%2, %3|%3, %2}"
19581 [(set_attr "type" "mpxst")])
19583 (define_insn "move_size_reloc_<mode>"
19584 [(set (match_operand:SWI48 0 "register_operand" "=r")
19586 [(match_operand:SWI48 1 "symbol_operand")]
19590 if (x86_64_immediate_size_operand (operands[1], VOIDmode))
19591 return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
19593 return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
19595 [(set_attr "type" "imov")
19596 (set_attr "mode" "<MODE>")])
19598 ;; RDPKRU and WRPKRU
19600 (define_expand "rdpkru"
19602 [(set (match_operand:SI 0 "register_operand")
19603 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
19604 (set (match_dup 2) (const_int 0))])]
19607 operands[1] = force_reg (SImode, const0_rtx);
19608 operands[2] = gen_reg_rtx (SImode);
19611 (define_insn "*rdpkru"
19612 [(set (match_operand:SI 0 "register_operand" "=a")
19613 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
19615 (set (match_operand:SI 1 "register_operand" "=d")
19619 [(set_attr "type" "other")])
19621 (define_expand "wrpkru"
19622 [(unspec_volatile:SI
19623 [(match_operand:SI 0 "register_operand")
19624 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
19627 operands[1] = force_reg (SImode, const0_rtx);
19628 operands[2] = force_reg (SImode, const0_rtx);
19631 (define_insn "*wrpkru"
19632 [(unspec_volatile:SI
19633 [(match_operand:SI 0 "register_operand" "a")
19634 (match_operand:SI 1 "register_operand" "d")
19635 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
19638 [(set_attr "type" "other")])
19640 (define_insn "speculation_barrier"
19641 [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
19644 [(set_attr "type" "other")
19645 (set_attr "length" "3")])
19649 (include "sync.md")