1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2015 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
108 UNSPEC_LD_MPIC ; load_macho_picbase
110 UNSPEC_DIV_ALREADY_SPLIT
116 UNSPEC_INSN_FALSE_DEP
118 ;; For SSE/MMX support:
126 ;; Generic math support
128 UNSPEC_IEEE_MIN ; not commutative
129 UNSPEC_IEEE_MAX ; not commutative
131 ;; x87 Floating point
147 UNSPEC_FRNDINT_MASK_PM
151 ;; x87 Double output FP
185 ;; For AVX512F support
199 (define_c_enum "unspecv" [
202 UNSPECV_PROBE_STACK_RANGE
205 UNSPECV_SPLIT_STACK_RETURN
211 UNSPECV_LLWP_INTRINSIC
212 UNSPECV_SLWP_INTRINSIC
213 UNSPECV_LWPVAL_INTRINSIC
214 UNSPECV_LWPINS_INTRINSIC
236 ;; For atomic compound assignments.
242 ;; For RDRAND support
245 ;; For RDSEED support
259 ;; For PCOMMIT support
262 ;; For CLFLUSHOPT support
265 ;; For MONITORX and MWAITX support
271 ;; Constants to represent rounding modes in the ROUND instruction
280 ;; Constants to represent AVX512F embeded rounding
282 [(ROUND_NEAREST_INT 0)
290 ;; Constants to represent pcomtrue/pcomfalse variants
300 ;; Constants used in the XOP pperm instruction
302 [(PPERM_SRC 0x00) /* copy source */
303 (PPERM_INVERT 0x20) /* invert source */
304 (PPERM_REVERSE 0x40) /* bit reverse source */
305 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
306 (PPERM_ZERO 0x80) /* all 0's */
307 (PPERM_ONES 0xa0) /* all 1's */
308 (PPERM_SIGN 0xc0) /* propagate sign bit */
309 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
310 (PPERM_SRC1 0x00) /* use first source byte */
311 (PPERM_SRC2 0x10) /* use second source byte */
314 ;; Registers by name.
397 (FIRST_PSEUDO_REG 81)
400 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
403 ;; In C guard expressions, put expressions which may be compile-time
404 ;; constants first. This allows for better optimization. For
405 ;; example, write "TARGET_64BIT && reload_completed", not
406 ;; "reload_completed && TARGET_64BIT".
410 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
411 atom,slm,generic,amdfam10,bdver1,bdver2,bdver3,bdver4,
413 (const (symbol_ref "ix86_schedule")))
415 ;; A basic instruction type. Refinements due to arguments to be
416 ;; provided in other attributes.
419 alu,alu1,negnot,imov,imovx,lea,
420 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
421 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
422 push,pop,call,callv,leave,
424 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
425 fxch,fistp,fisttp,frndint,
426 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
427 ssemul,sseimul,ssediv,sselog,sselog1,
428 sseishft,sseishft1,ssecmp,ssecomi,
429 ssecvt,ssecvt1,sseicvt,sseins,
430 sseshuf,sseshuf1,ssemuladd,sse4arg,
432 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
433 mpxmov,mpxmk,mpxchk,mpxld,mpxst"
434 (const_string "other"))
436 ;; Main data type used by the insn
438 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
440 (const_string "unknown"))
442 ;; The CPU unit operations uses.
443 (define_attr "unit" "integer,i387,sse,mmx,unknown"
444 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
445 fxch,fistp,fisttp,frndint")
446 (const_string "i387")
447 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
448 ssemul,sseimul,ssediv,sselog,sselog1,
449 sseishft,sseishft1,ssecmp,ssecomi,
450 ssecvt,ssecvt1,sseicvt,sseins,
451 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
453 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
455 (eq_attr "type" "other")
456 (const_string "unknown")]
457 (const_string "integer")))
459 ;; The minimum required alignment of vector mode memory operands of the SSE
460 ;; (non-VEX/EVEX) instruction in bits, if it is different from
461 ;; GET_MODE_ALIGNMENT of the operand, otherwise 0. If an instruction has
462 ;; multiple alternatives, this should be conservative maximum of those minimum
463 ;; required alignments.
464 (define_attr "ssememalign" "" (const_int 0))
466 ;; The (bounding maximum) length of an instruction immediate.
467 (define_attr "length_immediate" ""
468 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
469 bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
472 (eq_attr "unit" "i387,sse,mmx")
474 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
475 rotate,rotatex,rotate1,imul,icmp,push,pop")
476 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
477 (eq_attr "type" "imov,test")
478 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
479 (eq_attr "type" "call")
480 (if_then_else (match_operand 0 "constant_call_address_operand")
483 (eq_attr "type" "callv")
484 (if_then_else (match_operand 1 "constant_call_address_operand")
487 ;; We don't know the size before shorten_branches. Expect
488 ;; the instruction to fit for better scheduling.
489 (eq_attr "type" "ibr")
492 (symbol_ref "/* Update immediate_length and other attributes! */
493 gcc_unreachable (),1")))
495 ;; The (bounding maximum) length of an instruction address.
496 (define_attr "length_address" ""
497 (cond [(eq_attr "type" "str,other,multi,fxch")
499 (and (eq_attr "type" "call")
500 (match_operand 0 "constant_call_address_operand"))
502 (and (eq_attr "type" "callv")
503 (match_operand 1 "constant_call_address_operand"))
506 (symbol_ref "ix86_attr_length_address_default (insn)")))
508 ;; Set when length prefix is used.
509 (define_attr "prefix_data16" ""
510 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
512 (eq_attr "mode" "HI")
514 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
519 ;; Set when string REP prefix is used.
520 (define_attr "prefix_rep" ""
521 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
523 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
525 (and (eq_attr "type" "ibr,call,callv")
526 (match_test "ix86_bnd_prefixed_insn_p (insn)"))
531 ;; Set when 0f opcode prefix is used.
532 (define_attr "prefix_0f" ""
534 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
535 mpxmk,mpxmov,mpxchk,mpxld,mpxst")
536 (eq_attr "unit" "sse,mmx"))
540 ;; Set when REX opcode prefix is used.
541 (define_attr "prefix_rex" ""
542 (cond [(not (match_test "TARGET_64BIT"))
544 (and (eq_attr "mode" "DI")
545 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
546 (eq_attr "unit" "!mmx")))
548 (and (eq_attr "mode" "QI")
549 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
551 (match_test "x86_extended_reg_mentioned_p (insn)")
553 (and (eq_attr "type" "imovx")
554 (match_operand:QI 1 "ext_QIreg_operand"))
559 ;; There are also additional prefixes in 3DNOW, SSSE3.
560 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
561 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
562 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
563 (define_attr "prefix_extra" ""
564 (cond [(eq_attr "type" "ssemuladd,sse4arg")
566 (eq_attr "type" "sseiadd1,ssecvt1")
571 ;; Prefix used: original, VEX or maybe VEX.
572 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
573 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
575 (eq_attr "mode" "XI,V16SF,V8DF")
576 (const_string "evex")
578 (const_string "orig")))
580 ;; VEX W bit is used.
581 (define_attr "prefix_vex_w" "" (const_int 0))
583 ;; The length of VEX prefix
584 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
585 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
586 ;; still prefix_0f 1, with prefix_extra 1.
587 (define_attr "length_vex" ""
588 (if_then_else (and (eq_attr "prefix_0f" "1")
589 (eq_attr "prefix_extra" "0"))
590 (if_then_else (eq_attr "prefix_vex_w" "1")
591 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
592 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
593 (if_then_else (eq_attr "prefix_vex_w" "1")
594 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
595 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
597 ;; 4-bytes evex prefix and 1 byte opcode.
598 (define_attr "length_evex" "" (const_int 5))
600 ;; Set when modrm byte is used.
601 (define_attr "modrm" ""
602 (cond [(eq_attr "type" "str,leave")
604 (eq_attr "unit" "i387")
606 (and (eq_attr "type" "incdec")
607 (and (not (match_test "TARGET_64BIT"))
608 (ior (match_operand:SI 1 "register_operand")
609 (match_operand:HI 1 "register_operand"))))
611 (and (eq_attr "type" "push")
612 (not (match_operand 1 "memory_operand")))
614 (and (eq_attr "type" "pop")
615 (not (match_operand 0 "memory_operand")))
617 (and (eq_attr "type" "imov")
618 (and (not (eq_attr "mode" "DI"))
619 (ior (and (match_operand 0 "register_operand")
620 (match_operand 1 "immediate_operand"))
621 (ior (and (match_operand 0 "ax_reg_operand")
622 (match_operand 1 "memory_displacement_only_operand"))
623 (and (match_operand 0 "memory_displacement_only_operand")
624 (match_operand 1 "ax_reg_operand"))))))
626 (and (eq_attr "type" "call")
627 (match_operand 0 "constant_call_address_operand"))
629 (and (eq_attr "type" "callv")
630 (match_operand 1 "constant_call_address_operand"))
632 (and (eq_attr "type" "alu,alu1,icmp,test")
633 (match_operand 0 "ax_reg_operand"))
634 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
638 ;; When this attribute is set, calculate total insn length from
639 ;; length_nobnd attribute, prefixed with eventual bnd prefix byte
640 (define_attr "length_nobnd" "" (const_int 0))
642 ;; The (bounding maximum) length of an instruction in bytes.
643 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
644 ;; Later we may want to split them and compute proper length as for
646 (define_attr "length" ""
647 (cond [(eq_attr "length_nobnd" "!0")
648 (plus (symbol_ref ("ix86_bnd_prefixed_insn_p (insn)"))
649 (attr "length_nobnd"))
650 (eq_attr "type" "other,multi,fistp,frndint")
652 (eq_attr "type" "fcmp")
654 (eq_attr "unit" "i387")
656 (plus (attr "prefix_data16")
657 (attr "length_address")))
658 (ior (eq_attr "prefix" "evex")
659 (and (ior (eq_attr "prefix" "maybe_evex")
660 (eq_attr "prefix" "maybe_vex"))
661 (match_test "TARGET_AVX512F")))
662 (plus (attr "length_evex")
663 (plus (attr "length_immediate")
665 (attr "length_address"))))
666 (ior (eq_attr "prefix" "vex")
667 (and (ior (eq_attr "prefix" "maybe_vex")
668 (eq_attr "prefix" "maybe_evex"))
669 (match_test "TARGET_AVX")))
670 (plus (attr "length_vex")
671 (plus (attr "length_immediate")
673 (attr "length_address"))))]
674 (plus (plus (attr "modrm")
675 (plus (attr "prefix_0f")
676 (plus (attr "prefix_rex")
677 (plus (attr "prefix_extra")
679 (plus (attr "prefix_rep")
680 (plus (attr "prefix_data16")
681 (plus (attr "length_immediate")
682 (attr "length_address")))))))
684 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
685 ;; `store' if there is a simple memory reference therein, or `unknown'
686 ;; if the instruction is complex.
688 (define_attr "memory" "none,load,store,both,unknown"
689 (cond [(eq_attr "type" "other,multi,str,lwp")
690 (const_string "unknown")
691 (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
692 (const_string "none")
693 (eq_attr "type" "fistp,leave")
694 (const_string "both")
695 (eq_attr "type" "frndint")
696 (const_string "load")
697 (eq_attr "type" "mpxld")
698 (const_string "load")
699 (eq_attr "type" "mpxst")
700 (const_string "store")
701 (eq_attr "type" "push")
702 (if_then_else (match_operand 1 "memory_operand")
703 (const_string "both")
704 (const_string "store"))
705 (eq_attr "type" "pop")
706 (if_then_else (match_operand 0 "memory_operand")
707 (const_string "both")
708 (const_string "load"))
709 (eq_attr "type" "setcc")
710 (if_then_else (match_operand 0 "memory_operand")
711 (const_string "store")
712 (const_string "none"))
713 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
714 (if_then_else (ior (match_operand 0 "memory_operand")
715 (match_operand 1 "memory_operand"))
716 (const_string "load")
717 (const_string "none"))
718 (eq_attr "type" "ibr")
719 (if_then_else (match_operand 0 "memory_operand")
720 (const_string "load")
721 (const_string "none"))
722 (eq_attr "type" "call")
723 (if_then_else (match_operand 0 "constant_call_address_operand")
724 (const_string "none")
725 (const_string "load"))
726 (eq_attr "type" "callv")
727 (if_then_else (match_operand 1 "constant_call_address_operand")
728 (const_string "none")
729 (const_string "load"))
730 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
731 (match_operand 1 "memory_operand"))
732 (const_string "both")
733 (and (match_operand 0 "memory_operand")
734 (match_operand 1 "memory_operand"))
735 (const_string "both")
736 (match_operand 0 "memory_operand")
737 (const_string "store")
738 (match_operand 1 "memory_operand")
739 (const_string "load")
741 "!alu1,negnot,ishift1,
742 imov,imovx,icmp,test,bitmanip,
744 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
745 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
746 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
747 (match_operand 2 "memory_operand"))
748 (const_string "load")
749 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
750 (match_operand 3 "memory_operand"))
751 (const_string "load")
753 (const_string "none")))
755 ;; Indicates if an instruction has both an immediate and a displacement.
757 (define_attr "imm_disp" "false,true,unknown"
758 (cond [(eq_attr "type" "other,multi")
759 (const_string "unknown")
760 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
761 (and (match_operand 0 "memory_displacement_operand")
762 (match_operand 1 "immediate_operand")))
763 (const_string "true")
764 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
765 (and (match_operand 0 "memory_displacement_operand")
766 (match_operand 2 "immediate_operand")))
767 (const_string "true")
769 (const_string "false")))
771 ;; Indicates if an FP operation has an integer source.
773 (define_attr "fp_int_src" "false,true"
774 (const_string "false"))
776 ;; Defines rounding mode of an FP operation.
778 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
779 (const_string "any"))
781 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
782 (define_attr "use_carry" "0,1" (const_string "0"))
784 ;; Define attribute to indicate unaligned ssemov insns
785 (define_attr "movu" "0,1" (const_string "0"))
787 ;; Used to control the "enabled" attribute on a per-instruction basis.
788 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
789 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
790 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
791 fma_avx512f,avx512bw,noavx512bw,avx512dq,noavx512dq"
792 (const_string "base"))
794 (define_attr "enabled" ""
795 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
796 (eq_attr "isa" "x64_sse4")
797 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
798 (eq_attr "isa" "x64_sse4_noavx")
799 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
800 (eq_attr "isa" "x64_avx")
801 (symbol_ref "TARGET_64BIT && TARGET_AVX")
802 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
803 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
804 (eq_attr "isa" "sse2_noavx")
805 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
806 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
807 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
808 (eq_attr "isa" "sse4_noavx")
809 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
810 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
811 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
812 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
813 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
814 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
815 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
816 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
817 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
818 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
819 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
820 (eq_attr "isa" "fma_avx512f")
821 (symbol_ref "TARGET_FMA || TARGET_AVX512F")
822 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
823 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
824 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
825 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
829 (define_attr "preferred_for_size" "" (const_int 1))
830 (define_attr "preferred_for_speed" "" (const_int 1))
832 ;; Describe a user's asm statement.
833 (define_asm_attributes
834 [(set_attr "length" "128")
835 (set_attr "type" "multi")])
837 (define_code_iterator plusminus [plus minus])
839 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
841 (define_code_iterator multdiv [mult div])
843 ;; Base name for define_insn
844 (define_code_attr plusminus_insn
845 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
846 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
848 ;; Base name for insn mnemonic.
849 (define_code_attr plusminus_mnemonic
850 [(plus "add") (ss_plus "adds") (us_plus "addus")
851 (minus "sub") (ss_minus "subs") (us_minus "subus")])
852 (define_code_attr plusminus_carry_mnemonic
853 [(plus "adc") (minus "sbb")])
854 (define_code_attr multdiv_mnemonic
855 [(mult "mul") (div "div")])
857 ;; Mark commutative operators as such in constraints.
858 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
859 (minus "") (ss_minus "") (us_minus "")])
861 ;; Mapping of max and min
862 (define_code_iterator maxmin [smax smin umax umin])
864 ;; Mapping of signed max and min
865 (define_code_iterator smaxmin [smax smin])
867 ;; Mapping of unsigned max and min
868 (define_code_iterator umaxmin [umax umin])
870 ;; Base name for integer and FP insn mnemonic
871 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
872 (umax "maxu") (umin "minu")])
873 (define_code_attr maxmin_float [(smax "max") (smin "min")])
875 ;; Mapping of logic operators
876 (define_code_iterator any_logic [and ior xor])
877 (define_code_iterator any_or [ior xor])
878 (define_code_iterator fpint_logic [and xor])
880 ;; Base name for insn mnemonic.
881 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
883 ;; Mapping of logic-shift operators
884 (define_code_iterator any_lshift [ashift lshiftrt])
886 ;; Mapping of shift-right operators
887 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
889 ;; Mapping of all shift operators
890 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
892 ;; Base name for define_insn
893 (define_code_attr shift_insn
894 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
896 ;; Base name for insn mnemonic.
897 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
898 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
900 ;; Mapping of rotate operators
901 (define_code_iterator any_rotate [rotate rotatert])
903 ;; Base name for define_insn
904 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
906 ;; Base name for insn mnemonic.
907 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
909 ;; Mapping of abs neg operators
910 (define_code_iterator absneg [abs neg])
912 ;; Base name for x87 insn mnemonic.
913 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
915 ;; Used in signed and unsigned widening multiplications.
916 (define_code_iterator any_extend [sign_extend zero_extend])
918 ;; Prefix for insn menmonic.
919 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
921 ;; Prefix for define_insn
922 (define_code_attr u [(sign_extend "") (zero_extend "u")])
923 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
924 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
926 ;; Used in signed and unsigned truncations.
927 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
928 ;; Instruction suffix for truncations.
929 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
931 ;; Used in signed and unsigned fix.
932 (define_code_iterator any_fix [fix unsigned_fix])
933 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
935 ;; Used in signed and unsigned float.
936 (define_code_iterator any_float [float unsigned_float])
937 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
939 ;; All integer modes.
940 (define_mode_iterator SWI1248x [QI HI SI DI])
942 ;; All integer modes with AVX512BW.
943 (define_mode_iterator SWI1248_AVX512BW
944 [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
946 ;; All integer modes without QImode.
947 (define_mode_iterator SWI248x [HI SI DI])
949 ;; All integer modes without QImode and HImode.
950 (define_mode_iterator SWI48x [SI DI])
952 ;; All integer modes without SImode and DImode.
953 (define_mode_iterator SWI12 [QI HI])
955 ;; All integer modes without DImode.
956 (define_mode_iterator SWI124 [QI HI SI])
958 ;; All integer modes without QImode and DImode.
959 (define_mode_iterator SWI24 [HI SI])
961 ;; Single word integer modes.
962 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
964 ;; Single word integer modes without QImode.
965 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
967 ;; Single word integer modes without QImode and HImode.
968 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
970 ;; All math-dependant single and double word integer modes.
971 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
972 (HI "TARGET_HIMODE_MATH")
973 SI DI (TI "TARGET_64BIT")])
975 ;; Math-dependant single word integer modes.
976 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
977 (HI "TARGET_HIMODE_MATH")
978 SI (DI "TARGET_64BIT")])
980 ;; Math-dependant integer modes without DImode.
981 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
982 (HI "TARGET_HIMODE_MATH")
985 ;; Math-dependant single word integer modes without QImode.
986 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
987 SI (DI "TARGET_64BIT")])
989 ;; Double word integer modes.
990 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
991 (TI "TARGET_64BIT")])
993 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
994 ;; compile time constant, it is faster to use <MODE_SIZE> than
995 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
996 ;; command line options just use GET_MODE_SIZE macro.
997 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
998 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
999 (V16QI "16") (V32QI "32") (V64QI "64")
1000 (V8HI "16") (V16HI "32") (V32HI "64")
1001 (V4SI "16") (V8SI "32") (V16SI "64")
1002 (V2DI "16") (V4DI "32") (V8DI "64")
1003 (V1TI "16") (V2TI "32") (V4TI "64")
1004 (V2DF "16") (V4DF "32") (V8DF "64")
1005 (V4SF "16") (V8SF "32") (V16SF "64")])
1007 ;; Double word integer modes as mode attribute.
1008 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1009 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1011 ;; Half mode for double word integer modes.
1012 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1013 (DI "TARGET_64BIT")])
1016 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1017 (BND64 "TARGET_LP64")])
1019 ;; Pointer mode corresponding to bound mode.
1020 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1023 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1026 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1028 (UNSPEC_BNDCN "cn")])
1030 ;; Instruction suffix for integer modes.
1031 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1033 ;; Instruction suffix for masks.
1034 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1036 ;; Pointer size prefix for integer modes (Intel asm dialect)
1037 (define_mode_attr iptrsize [(QI "BYTE")
1042 ;; Register class for integer modes.
1043 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1045 ;; Immediate operand constraint for integer modes.
1046 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1048 ;; General operand constraint for word modes.
1049 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1051 ;; Immediate operand constraint for double integer modes.
1052 (define_mode_attr di [(SI "nF") (DI "e")])
1054 ;; Immediate operand constraint for shifts.
1055 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1057 ;; General operand predicate for integer modes.
1058 (define_mode_attr general_operand
1059 [(QI "general_operand")
1060 (HI "general_operand")
1061 (SI "x86_64_general_operand")
1062 (DI "x86_64_general_operand")
1063 (TI "x86_64_general_operand")])
1065 ;; General sign extend operand predicate for integer modes,
1066 ;; which disallows VOIDmode operands and thus it is suitable
1067 ;; for use inside sign_extend.
1068 (define_mode_attr general_sext_operand
1069 [(QI "sext_operand")
1071 (SI "x86_64_sext_operand")
1072 (DI "x86_64_sext_operand")])
1074 ;; General sign/zero extend operand predicate for integer modes.
1075 (define_mode_attr general_szext_operand
1076 [(QI "general_operand")
1077 (HI "general_operand")
1078 (SI "x86_64_szext_general_operand")
1079 (DI "x86_64_szext_general_operand")])
1081 ;; Immediate operand predicate for integer modes.
1082 (define_mode_attr immediate_operand
1083 [(QI "immediate_operand")
1084 (HI "immediate_operand")
1085 (SI "x86_64_immediate_operand")
1086 (DI "x86_64_immediate_operand")])
1088 ;; Nonmemory operand predicate for integer modes.
1089 (define_mode_attr nonmemory_operand
1090 [(QI "nonmemory_operand")
1091 (HI "nonmemory_operand")
1092 (SI "x86_64_nonmemory_operand")
1093 (DI "x86_64_nonmemory_operand")])
1095 ;; Operand predicate for shifts.
1096 (define_mode_attr shift_operand
1097 [(QI "nonimmediate_operand")
1098 (HI "nonimmediate_operand")
1099 (SI "nonimmediate_operand")
1100 (DI "shiftdi_operand")
1101 (TI "register_operand")])
1103 ;; Operand predicate for shift argument.
1104 (define_mode_attr shift_immediate_operand
1105 [(QI "const_1_to_31_operand")
1106 (HI "const_1_to_31_operand")
1107 (SI "const_1_to_31_operand")
1108 (DI "const_1_to_63_operand")])
1110 ;; Input operand predicate for arithmetic left shifts.
1111 (define_mode_attr ashl_input_operand
1112 [(QI "nonimmediate_operand")
1113 (HI "nonimmediate_operand")
1114 (SI "nonimmediate_operand")
1115 (DI "ashldi_input_operand")
1116 (TI "reg_or_pm1_operand")])
1118 ;; SSE and x87 SFmode and DFmode floating point modes
1119 (define_mode_iterator MODEF [SF DF])
1121 ;; All x87 floating point modes
1122 (define_mode_iterator X87MODEF [SF DF XF])
1124 ;; SSE instruction suffix for various modes
1125 (define_mode_attr ssemodesuffix
1126 [(SF "ss") (DF "sd")
1127 (V16SF "ps") (V8DF "pd")
1128 (V8SF "ps") (V4DF "pd")
1129 (V4SF "ps") (V2DF "pd")
1130 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1131 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1132 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1134 ;; SSE vector suffix for floating point modes
1135 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1137 ;; SSE vector mode corresponding to a scalar mode
1138 (define_mode_attr ssevecmode
1139 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1140 (define_mode_attr ssevecmodelower
1141 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1143 ;; Instruction suffix for REX 64bit operators.
1144 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1146 ;; This mode iterator allows :P to be used for patterns that operate on
1147 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1148 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1150 ;; This mode iterator allows :W to be used for patterns that operate on
1151 ;; word_mode sized quantities.
1152 (define_mode_iterator W
1153 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1155 ;; This mode iterator allows :PTR to be used for patterns that operate on
1156 ;; ptr_mode sized quantities.
1157 (define_mode_iterator PTR
1158 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1160 ;; Scheduling descriptions
1162 (include "pentium.md")
1165 (include "athlon.md")
1166 (include "bdver1.md")
1167 (include "bdver3.md")
1168 (include "btver2.md")
1169 (include "geode.md")
1172 (include "core2.md")
1175 ;; Operand and operator predicates and constraints
1177 (include "predicates.md")
1178 (include "constraints.md")
1181 ;; Compare and branch/compare and store instructions.
1183 (define_expand "cbranch<mode>4"
1184 [(set (reg:CC FLAGS_REG)
1185 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1186 (match_operand:SDWIM 2 "<general_operand>")))
1187 (set (pc) (if_then_else
1188 (match_operator 0 "ordered_comparison_operator"
1189 [(reg:CC FLAGS_REG) (const_int 0)])
1190 (label_ref (match_operand 3))
1194 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1195 operands[1] = force_reg (<MODE>mode, operands[1]);
1196 ix86_expand_branch (GET_CODE (operands[0]),
1197 operands[1], operands[2], operands[3]);
1201 (define_expand "cstore<mode>4"
1202 [(set (reg:CC FLAGS_REG)
1203 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1204 (match_operand:SWIM 3 "<general_operand>")))
1205 (set (match_operand:QI 0 "register_operand")
1206 (match_operator 1 "ordered_comparison_operator"
1207 [(reg:CC FLAGS_REG) (const_int 0)]))]
1210 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1211 operands[2] = force_reg (<MODE>mode, operands[2]);
1212 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1213 operands[2], operands[3]);
1217 (define_expand "cmp<mode>_1"
1218 [(set (reg:CC FLAGS_REG)
1219 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1220 (match_operand:SWI48 1 "<general_operand>")))])
1222 (define_insn "*cmp<mode>_ccno_1"
1223 [(set (reg FLAGS_REG)
1224 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1225 (match_operand:SWI 1 "const0_operand")))]
1226 "ix86_match_ccmode (insn, CCNOmode)"
1228 test{<imodesuffix>}\t%0, %0
1229 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1230 [(set_attr "type" "test,icmp")
1231 (set_attr "length_immediate" "0,1")
1232 (set_attr "mode" "<MODE>")])
1234 (define_insn "*cmp<mode>_1"
1235 [(set (reg FLAGS_REG)
1236 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1237 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1238 "ix86_match_ccmode (insn, CCmode)"
1239 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1240 [(set_attr "type" "icmp")
1241 (set_attr "mode" "<MODE>")])
1243 (define_insn "*cmp<mode>_minus_1"
1244 [(set (reg FLAGS_REG)
1246 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1247 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1249 "ix86_match_ccmode (insn, CCGOCmode)"
1250 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1251 [(set_attr "type" "icmp")
1252 (set_attr "mode" "<MODE>")])
1254 (define_insn "*cmpqi_ext_1"
1255 [(set (reg FLAGS_REG)
1257 (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1260 (match_operand 1 "ext_register_operand" "Q,Q")
1262 (const_int 8)) 0)))]
1263 "ix86_match_ccmode (insn, CCmode)"
1264 "cmp{b}\t{%h1, %0|%0, %h1}"
1265 [(set_attr "isa" "*,nox64")
1266 (set_attr "type" "icmp")
1267 (set_attr "mode" "QI")])
1269 (define_insn "*cmpqi_ext_2"
1270 [(set (reg FLAGS_REG)
1274 (match_operand 0 "ext_register_operand" "Q")
1277 (match_operand:QI 1 "const0_operand")))]
1278 "ix86_match_ccmode (insn, CCNOmode)"
1280 [(set_attr "type" "test")
1281 (set_attr "length_immediate" "0")
1282 (set_attr "mode" "QI")])
1284 (define_expand "cmpqi_ext_3"
1285 [(set (reg:CC FLAGS_REG)
1289 (match_operand 0 "ext_register_operand")
1292 (match_operand:QI 1 "const_int_operand")))])
1294 (define_insn "*cmpqi_ext_3"
1295 [(set (reg FLAGS_REG)
1299 (match_operand 0 "ext_register_operand" "Q,Q")
1302 (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1303 "ix86_match_ccmode (insn, CCmode)"
1304 "cmp{b}\t{%1, %h0|%h0, %1}"
1305 [(set_attr "isa" "*,nox64")
1306 (set_attr "type" "icmp")
1307 (set_attr "modrm" "1")
1308 (set_attr "mode" "QI")])
1310 (define_insn "*cmpqi_ext_4"
1311 [(set (reg FLAGS_REG)
1315 (match_operand 0 "ext_register_operand" "Q")
1320 (match_operand 1 "ext_register_operand" "Q")
1322 (const_int 8)) 0)))]
1323 "ix86_match_ccmode (insn, CCmode)"
1324 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1325 [(set_attr "type" "icmp")
1326 (set_attr "mode" "QI")])
1328 ;; These implement float point compares.
1329 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1330 ;; which would allow mix and match FP modes on the compares. Which is what
1331 ;; the old patterns did, but with many more of them.
1333 (define_expand "cbranchxf4"
1334 [(set (reg:CC FLAGS_REG)
1335 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1336 (match_operand:XF 2 "nonmemory_operand")))
1337 (set (pc) (if_then_else
1338 (match_operator 0 "ix86_fp_comparison_operator"
1341 (label_ref (match_operand 3))
1345 ix86_expand_branch (GET_CODE (operands[0]),
1346 operands[1], operands[2], operands[3]);
1350 (define_expand "cstorexf4"
1351 [(set (reg:CC FLAGS_REG)
1352 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1353 (match_operand:XF 3 "nonmemory_operand")))
1354 (set (match_operand:QI 0 "register_operand")
1355 (match_operator 1 "ix86_fp_comparison_operator"
1360 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1361 operands[2], operands[3]);
1365 (define_expand "cbranch<mode>4"
1366 [(set (reg:CC FLAGS_REG)
1367 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1368 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1369 (set (pc) (if_then_else
1370 (match_operator 0 "ix86_fp_comparison_operator"
1373 (label_ref (match_operand 3))
1375 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1377 ix86_expand_branch (GET_CODE (operands[0]),
1378 operands[1], operands[2], operands[3]);
1382 (define_expand "cstore<mode>4"
1383 [(set (reg:CC FLAGS_REG)
1384 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1385 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1386 (set (match_operand:QI 0 "register_operand")
1387 (match_operator 1 "ix86_fp_comparison_operator"
1390 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1392 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1393 operands[2], operands[3]);
1397 (define_expand "cbranchcc4"
1398 [(set (pc) (if_then_else
1399 (match_operator 0 "comparison_operator"
1400 [(match_operand 1 "flags_reg_operand")
1401 (match_operand 2 "const0_operand")])
1402 (label_ref (match_operand 3))
1406 ix86_expand_branch (GET_CODE (operands[0]),
1407 operands[1], operands[2], operands[3]);
1411 (define_expand "cstorecc4"
1412 [(set (match_operand:QI 0 "register_operand")
1413 (match_operator 1 "comparison_operator"
1414 [(match_operand 2 "flags_reg_operand")
1415 (match_operand 3 "const0_operand")]))]
1418 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1419 operands[2], operands[3]);
1424 ;; FP compares, step 1:
1425 ;; Set the FP condition codes.
1427 ;; CCFPmode compare with exceptions
1428 ;; CCFPUmode compare with no exceptions
1430 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1431 ;; used to manage the reg stack popping would not be preserved.
1433 (define_insn "*cmp<mode>_0_i387"
1434 [(set (match_operand:HI 0 "register_operand" "=a")
1437 (match_operand:X87MODEF 1 "register_operand" "f")
1438 (match_operand:X87MODEF 2 "const0_operand"))]
1441 "* return output_fp_compare (insn, operands, false, false);"
1442 [(set_attr "type" "multi")
1443 (set_attr "unit" "i387")
1444 (set_attr "mode" "<MODE>")])
1446 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1447 [(set (reg:CCFP FLAGS_REG)
1449 (match_operand:X87MODEF 1 "register_operand" "f")
1450 (match_operand:X87MODEF 2 "const0_operand")))
1451 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1452 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1454 "&& reload_completed"
1457 [(compare:CCFP (match_dup 1)(match_dup 2))]
1459 (set (reg:CC FLAGS_REG)
1460 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1462 [(set_attr "type" "multi")
1463 (set_attr "unit" "i387")
1464 (set_attr "mode" "<MODE>")])
1466 (define_insn "*cmpxf_i387"
1467 [(set (match_operand:HI 0 "register_operand" "=a")
1470 (match_operand:XF 1 "register_operand" "f")
1471 (match_operand:XF 2 "register_operand" "f"))]
1474 "* return output_fp_compare (insn, operands, false, false);"
1475 [(set_attr "type" "multi")
1476 (set_attr "unit" "i387")
1477 (set_attr "mode" "XF")])
1479 (define_insn_and_split "*cmpxf_cc_i387"
1480 [(set (reg:CCFP FLAGS_REG)
1482 (match_operand:XF 1 "register_operand" "f")
1483 (match_operand:XF 2 "register_operand" "f")))
1484 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1485 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1487 "&& reload_completed"
1490 [(compare:CCFP (match_dup 1)(match_dup 2))]
1492 (set (reg:CC FLAGS_REG)
1493 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1495 [(set_attr "type" "multi")
1496 (set_attr "unit" "i387")
1497 (set_attr "mode" "XF")])
1499 (define_insn "*cmp<mode>_i387"
1500 [(set (match_operand:HI 0 "register_operand" "=a")
1503 (match_operand:MODEF 1 "register_operand" "f")
1504 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1507 "* return output_fp_compare (insn, operands, false, false);"
1508 [(set_attr "type" "multi")
1509 (set_attr "unit" "i387")
1510 (set_attr "mode" "<MODE>")])
1512 (define_insn_and_split "*cmp<mode>_cc_i387"
1513 [(set (reg:CCFP FLAGS_REG)
1515 (match_operand:MODEF 1 "register_operand" "f")
1516 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1517 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1518 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1520 "&& reload_completed"
1523 [(compare:CCFP (match_dup 1)(match_dup 2))]
1525 (set (reg:CC FLAGS_REG)
1526 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1528 [(set_attr "type" "multi")
1529 (set_attr "unit" "i387")
1530 (set_attr "mode" "<MODE>")])
1532 (define_insn "*cmpu<mode>_i387"
1533 [(set (match_operand:HI 0 "register_operand" "=a")
1536 (match_operand:X87MODEF 1 "register_operand" "f")
1537 (match_operand:X87MODEF 2 "register_operand" "f"))]
1540 "* return output_fp_compare (insn, operands, false, true);"
1541 [(set_attr "type" "multi")
1542 (set_attr "unit" "i387")
1543 (set_attr "mode" "<MODE>")])
1545 (define_insn_and_split "*cmpu<mode>_cc_i387"
1546 [(set (reg:CCFPU FLAGS_REG)
1548 (match_operand:X87MODEF 1 "register_operand" "f")
1549 (match_operand:X87MODEF 2 "register_operand" "f")))
1550 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1551 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1553 "&& reload_completed"
1556 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1558 (set (reg:CC FLAGS_REG)
1559 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1561 [(set_attr "type" "multi")
1562 (set_attr "unit" "i387")
1563 (set_attr "mode" "<MODE>")])
1565 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1566 [(set (match_operand:HI 0 "register_operand" "=a")
1569 (match_operand:X87MODEF 1 "register_operand" "f")
1570 (match_operator:X87MODEF 3 "float_operator"
1571 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1574 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1575 || optimize_function_for_size_p (cfun))"
1576 "* return output_fp_compare (insn, operands, false, false);"
1577 [(set_attr "type" "multi")
1578 (set_attr "unit" "i387")
1579 (set_attr "fp_int_src" "true")
1580 (set_attr "mode" "<SWI24:MODE>")])
1582 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1583 [(set (reg:CCFP FLAGS_REG)
1585 (match_operand:X87MODEF 1 "register_operand" "f")
1586 (match_operator:X87MODEF 3 "float_operator"
1587 [(match_operand:SWI24 2 "memory_operand" "m")])))
1588 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1589 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1590 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1591 || optimize_function_for_size_p (cfun))"
1593 "&& reload_completed"
1598 (match_op_dup 3 [(match_dup 2)]))]
1600 (set (reg:CC FLAGS_REG)
1601 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1603 [(set_attr "type" "multi")
1604 (set_attr "unit" "i387")
1605 (set_attr "fp_int_src" "true")
1606 (set_attr "mode" "<SWI24:MODE>")])
1608 ;; FP compares, step 2
1609 ;; Move the fpsw to ax.
1611 (define_insn "x86_fnstsw_1"
1612 [(set (match_operand:HI 0 "register_operand" "=a")
1613 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1616 [(set_attr "length" "2")
1617 (set_attr "mode" "SI")
1618 (set_attr "unit" "i387")])
1620 ;; FP compares, step 3
1621 ;; Get ax into flags, general case.
1623 (define_insn "x86_sahf_1"
1624 [(set (reg:CC FLAGS_REG)
1625 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1629 #ifndef HAVE_AS_IX86_SAHF
1631 return ASM_BYTE "0x9e";
1636 [(set_attr "length" "1")
1637 (set_attr "athlon_decode" "vector")
1638 (set_attr "amdfam10_decode" "direct")
1639 (set_attr "bdver1_decode" "direct")
1640 (set_attr "mode" "SI")])
1642 ;; Pentium Pro can do steps 1 through 3 in one go.
1643 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1644 ;; (these i387 instructions set flags directly)
1646 (define_mode_iterator FPCMP [CCFP CCFPU])
1647 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1649 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1650 [(set (reg:FPCMP FLAGS_REG)
1652 (match_operand:MODEF 0 "register_operand" "f,v")
1653 (match_operand:MODEF 1 "nonimmediate_operand" "f,vm")))]
1654 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
1655 "* return output_fp_compare (insn, operands, true,
1656 <FPCMP:MODE>mode == CCFPUmode);"
1657 [(set_attr "type" "fcmp,ssecomi")
1658 (set_attr "prefix" "orig,maybe_vex")
1659 (set_attr "mode" "<MODEF:MODE>")
1660 (set_attr "prefix_rep" "*,0")
1661 (set (attr "prefix_data16")
1662 (cond [(eq_attr "alternative" "0")
1664 (eq_attr "mode" "DF")
1667 (const_string "0")))
1668 (set_attr "athlon_decode" "vector")
1669 (set_attr "amdfam10_decode" "direct")
1670 (set_attr "bdver1_decode" "double")
1671 (set (attr "enabled")
1672 (cond [(eq_attr "alternative" "0")
1673 (symbol_ref "TARGET_MIX_SSE_I387")
1675 (symbol_ref "true")))])
1677 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1678 [(set (reg:FPCMP FLAGS_REG)
1680 (match_operand:X87MODEF 0 "register_operand" "f")
1681 (match_operand:X87MODEF 1 "register_operand" "f")))]
1682 "TARGET_80387 && TARGET_CMOVE
1683 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1684 "* return output_fp_compare (insn, operands, true,
1685 <FPCMP:MODE>mode == CCFPUmode);"
1686 [(set_attr "type" "fcmp")
1687 (set_attr "mode" "<X87MODEF:MODE>")
1688 (set_attr "athlon_decode" "vector")
1689 (set_attr "amdfam10_decode" "direct")
1690 (set_attr "bdver1_decode" "double")])
1692 ;; Push/pop instructions.
1694 (define_insn "*push<mode>2"
1695 [(set (match_operand:DWI 0 "push_operand" "=<")
1696 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1699 [(set_attr "type" "multi")
1700 (set_attr "mode" "<MODE>")])
1703 [(set (match_operand:TI 0 "push_operand")
1704 (match_operand:TI 1 "general_operand"))]
1705 "TARGET_64BIT && reload_completed
1706 && !SSE_REG_P (operands[1])"
1708 "ix86_split_long_move (operands); DONE;")
1710 (define_insn "*pushdi2_rex64"
1711 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1712 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1717 [(set_attr "type" "push,multi")
1718 (set_attr "mode" "DI")])
1720 ;; Convert impossible pushes of immediate to existing instructions.
1721 ;; First try to get scratch register and go through it. In case this
1722 ;; fails, push sign extended lower part first and then overwrite
1723 ;; upper part by 32bit move.
1725 [(match_scratch:DI 2 "r")
1726 (set (match_operand:DI 0 "push_operand")
1727 (match_operand:DI 1 "immediate_operand"))]
1728 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1729 && !x86_64_immediate_operand (operands[1], DImode)"
1730 [(set (match_dup 2) (match_dup 1))
1731 (set (match_dup 0) (match_dup 2))])
1733 ;; We need to define this as both peepholer and splitter for case
1734 ;; peephole2 pass is not run.
1735 ;; "&& 1" is needed to keep it from matching the previous pattern.
1737 [(set (match_operand:DI 0 "push_operand")
1738 (match_operand:DI 1 "immediate_operand"))]
1739 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1740 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1741 [(set (match_dup 0) (match_dup 1))
1742 (set (match_dup 2) (match_dup 3))]
1744 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1746 operands[1] = gen_lowpart (DImode, operands[2]);
1747 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1752 [(set (match_operand:DI 0 "push_operand")
1753 (match_operand:DI 1 "immediate_operand"))]
1754 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1755 ? epilogue_completed : reload_completed)
1756 && !symbolic_operand (operands[1], DImode)
1757 && !x86_64_immediate_operand (operands[1], DImode)"
1758 [(set (match_dup 0) (match_dup 1))
1759 (set (match_dup 2) (match_dup 3))]
1761 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1763 operands[1] = gen_lowpart (DImode, operands[2]);
1764 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1769 [(set (match_operand:DI 0 "push_operand")
1770 (match_operand:DI 1 "general_operand"))]
1771 "!TARGET_64BIT && reload_completed
1772 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1774 "ix86_split_long_move (operands); DONE;")
1776 (define_insn "*pushsi2"
1777 [(set (match_operand:SI 0 "push_operand" "=<")
1778 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1781 [(set_attr "type" "push")
1782 (set_attr "mode" "SI")])
1784 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1785 ;; "push a byte/word". But actually we use pushl, which has the effect
1786 ;; of rounding the amount pushed up to a word.
1788 ;; For TARGET_64BIT we always round up to 8 bytes.
1789 (define_insn "*push<mode>2_rex64"
1790 [(set (match_operand:SWI124 0 "push_operand" "=X")
1791 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1794 [(set_attr "type" "push")
1795 (set_attr "mode" "DI")])
1797 (define_insn "*push<mode>2"
1798 [(set (match_operand:SWI12 0 "push_operand" "=X")
1799 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1802 [(set_attr "type" "push")
1803 (set_attr "mode" "SI")])
1805 (define_insn "*push<mode>2_prologue"
1806 [(set (match_operand:W 0 "push_operand" "=<")
1807 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1808 (clobber (mem:BLK (scratch)))]
1810 "push{<imodesuffix>}\t%1"
1811 [(set_attr "type" "push")
1812 (set_attr "mode" "<MODE>")])
1814 (define_insn "*pop<mode>1"
1815 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1816 (match_operand:W 1 "pop_operand" ">"))]
1818 "pop{<imodesuffix>}\t%0"
1819 [(set_attr "type" "pop")
1820 (set_attr "mode" "<MODE>")])
1822 (define_insn "*pop<mode>1_epilogue"
1823 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1824 (match_operand:W 1 "pop_operand" ">"))
1825 (clobber (mem:BLK (scratch)))]
1827 "pop{<imodesuffix>}\t%0"
1828 [(set_attr "type" "pop")
1829 (set_attr "mode" "<MODE>")])
1831 (define_insn "*pushfl<mode>2"
1832 [(set (match_operand:W 0 "push_operand" "=<")
1833 (match_operand:W 1 "flags_reg_operand"))]
1835 "pushf{<imodesuffix>}"
1836 [(set_attr "type" "push")
1837 (set_attr "mode" "<MODE>")])
1839 (define_insn "*popfl<mode>1"
1840 [(set (match_operand:W 0 "flags_reg_operand")
1841 (match_operand:W 1 "pop_operand" ">"))]
1843 "popf{<imodesuffix>}"
1844 [(set_attr "type" "pop")
1845 (set_attr "mode" "<MODE>")])
1848 ;; Move instructions.
1850 (define_expand "movxi"
1851 [(set (match_operand:XI 0 "nonimmediate_operand")
1852 (match_operand:XI 1 "general_operand"))]
1854 "ix86_expand_move (XImode, operands); DONE;")
1856 ;; Reload patterns to support multi-word load/store
1857 ;; with non-offsetable address.
1858 (define_expand "reload_noff_store"
1859 [(parallel [(match_operand 0 "memory_operand" "=m")
1860 (match_operand 1 "register_operand" "r")
1861 (match_operand:DI 2 "register_operand" "=&r")])]
1864 rtx mem = operands[0];
1865 rtx addr = XEXP (mem, 0);
1867 emit_move_insn (operands[2], addr);
1868 mem = replace_equiv_address_nv (mem, operands[2]);
1870 emit_insn (gen_rtx_SET (mem, operands[1]));
1874 (define_expand "reload_noff_load"
1875 [(parallel [(match_operand 0 "register_operand" "=r")
1876 (match_operand 1 "memory_operand" "m")
1877 (match_operand:DI 2 "register_operand" "=r")])]
1880 rtx mem = operands[1];
1881 rtx addr = XEXP (mem, 0);
1883 emit_move_insn (operands[2], addr);
1884 mem = replace_equiv_address_nv (mem, operands[2]);
1886 emit_insn (gen_rtx_SET (operands[0], mem));
1890 (define_expand "movoi"
1891 [(set (match_operand:OI 0 "nonimmediate_operand")
1892 (match_operand:OI 1 "general_operand"))]
1894 "ix86_expand_move (OImode, operands); DONE;")
1896 (define_expand "movti"
1897 [(set (match_operand:TI 0 "nonimmediate_operand")
1898 (match_operand:TI 1 "nonimmediate_operand"))]
1899 "TARGET_64BIT || TARGET_SSE"
1902 ix86_expand_move (TImode, operands);
1904 ix86_expand_vector_move (TImode, operands);
1908 ;; This expands to what emit_move_complex would generate if we didn't
1909 ;; have a movti pattern. Having this avoids problems with reload on
1910 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1911 ;; to have around all the time.
1912 (define_expand "movcdi"
1913 [(set (match_operand:CDI 0 "nonimmediate_operand")
1914 (match_operand:CDI 1 "general_operand"))]
1917 if (push_operand (operands[0], CDImode))
1918 emit_move_complex_push (CDImode, operands[0], operands[1]);
1920 emit_move_complex_parts (operands[0], operands[1]);
1924 (define_expand "mov<mode>"
1925 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1926 (match_operand:SWI1248x 1 "general_operand"))]
1928 "ix86_expand_move (<MODE>mode, operands); DONE;")
1930 (define_insn "*mov<mode>_xor"
1931 [(set (match_operand:SWI48 0 "register_operand" "=r")
1932 (match_operand:SWI48 1 "const0_operand"))
1933 (clobber (reg:CC FLAGS_REG))]
1936 [(set_attr "type" "alu1")
1937 (set_attr "mode" "SI")
1938 (set_attr "length_immediate" "0")])
1940 (define_insn "*mov<mode>_or"
1941 [(set (match_operand:SWI48 0 "register_operand" "=r")
1942 (match_operand:SWI48 1 "const_int_operand"))
1943 (clobber (reg:CC FLAGS_REG))]
1945 && operands[1] == constm1_rtx"
1946 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1947 [(set_attr "type" "alu1")
1948 (set_attr "mode" "<MODE>")
1949 (set_attr "length_immediate" "1")])
1951 (define_insn "*movxi_internal_avx512f"
1952 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,m")
1953 (match_operand:XI 1 "vector_move_operand" "C ,vm,v"))]
1954 "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1956 switch (which_alternative)
1959 return standard_sse_constant_opcode (insn, operands[1]);
1962 if (misaligned_operand (operands[0], XImode)
1963 || misaligned_operand (operands[1], XImode))
1964 return "vmovdqu32\t{%1, %0|%0, %1}";
1966 return "vmovdqa32\t{%1, %0|%0, %1}";
1971 [(set_attr "type" "sselog1,ssemov,ssemov")
1972 (set_attr "prefix" "evex")
1973 (set_attr "mode" "XI")])
1975 (define_insn "*movoi_internal_avx"
1976 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,m")
1977 (match_operand:OI 1 "vector_move_operand" "C ,vm,v"))]
1978 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1980 switch (get_attr_type (insn))
1983 return standard_sse_constant_opcode (insn, operands[1]);
1986 if (misaligned_operand (operands[0], OImode)
1987 || misaligned_operand (operands[1], OImode))
1989 if (get_attr_mode (insn) == MODE_V8SF)
1990 return "vmovups\t{%1, %0|%0, %1}";
1991 else if (get_attr_mode (insn) == MODE_XI)
1992 return "vmovdqu32\t{%1, %0|%0, %1}";
1994 return "vmovdqu\t{%1, %0|%0, %1}";
1998 if (get_attr_mode (insn) == MODE_V8SF)
1999 return "vmovaps\t{%1, %0|%0, %1}";
2000 else if (get_attr_mode (insn) == MODE_XI)
2001 return "vmovdqa32\t{%1, %0|%0, %1}";
2003 return "vmovdqa\t{%1, %0|%0, %1}";
2010 [(set_attr "type" "sselog1,ssemov,ssemov")
2011 (set_attr "prefix" "vex")
2013 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2014 (match_operand 1 "ext_sse_reg_operand"))
2016 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2017 (const_string "V8SF")
2018 (and (eq_attr "alternative" "2")
2019 (match_test "TARGET_SSE_TYPELESS_STORES"))
2020 (const_string "V8SF")
2022 (const_string "OI")))])
2024 (define_insn "*movti_internal"
2025 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,m")
2026 (match_operand:TI 1 "general_operand" "riFo,re,C,vm,v"))]
2027 "(TARGET_64BIT || TARGET_SSE)
2028 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2030 switch (get_attr_type (insn))
2036 return standard_sse_constant_opcode (insn, operands[1]);
2039 /* TDmode values are passed as TImode on the stack. Moving them
2040 to stack may result in unaligned memory access. */
2041 if (misaligned_operand (operands[0], TImode)
2042 || misaligned_operand (operands[1], TImode))
2044 if (get_attr_mode (insn) == MODE_V4SF)
2045 return "%vmovups\t{%1, %0|%0, %1}";
2046 else if (get_attr_mode (insn) == MODE_XI)
2047 return "vmovdqu32\t{%1, %0|%0, %1}";
2049 return "%vmovdqu\t{%1, %0|%0, %1}";
2053 if (get_attr_mode (insn) == MODE_V4SF)
2054 return "%vmovaps\t{%1, %0|%0, %1}";
2055 else if (get_attr_mode (insn) == MODE_XI)
2056 return "vmovdqa32\t{%1, %0|%0, %1}";
2058 return "%vmovdqa\t{%1, %0|%0, %1}";
2065 [(set_attr "isa" "x64,x64,*,*,*")
2066 (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
2067 (set (attr "prefix")
2068 (if_then_else (eq_attr "type" "sselog1,ssemov")
2069 (const_string "maybe_vex")
2070 (const_string "orig")))
2072 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2073 (match_operand 1 "ext_sse_reg_operand"))
2075 (eq_attr "alternative" "0,1")
2077 (ior (not (match_test "TARGET_SSE2"))
2078 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2079 (const_string "V4SF")
2080 (and (eq_attr "alternative" "4")
2081 (match_test "TARGET_SSE_TYPELESS_STORES"))
2082 (const_string "V4SF")
2083 (match_test "TARGET_AVX")
2085 (match_test "optimize_function_for_size_p (cfun)")
2086 (const_string "V4SF")
2088 (const_string "TI")))])
2091 [(set (match_operand:TI 0 "nonimmediate_operand")
2092 (match_operand:TI 1 "general_operand"))]
2094 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2096 "ix86_split_long_move (operands); DONE;")
2098 (define_insn "*movdi_internal"
2099 [(set (match_operand:DI 0 "nonimmediate_operand"
2100 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?r,?*Yi,?*Ym,?*Yi,*k,*k ,*r ,*m")
2101 (match_operand:DI 1 "general_operand"
2102 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,*Yj,*v,r ,*Yj ,*Yn ,*r ,*km,*k,*k"))]
2103 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2105 switch (get_attr_type (insn))
2108 return "kmovq\t{%1, %0|%0, %1}";
2114 return "pxor\t%0, %0";
2117 /* Handle broken assemblers that require movd instead of movq. */
2118 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2119 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2120 return "movd\t{%1, %0|%0, %1}";
2121 return "movq\t{%1, %0|%0, %1}";
2124 if (GENERAL_REG_P (operands[0]))
2125 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2127 return standard_sse_constant_opcode (insn, operands[1]);
2130 switch (get_attr_mode (insn))
2133 /* Handle broken assemblers that require movd instead of movq. */
2134 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2135 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2136 return "%vmovd\t{%1, %0|%0, %1}";
2137 return "%vmovq\t{%1, %0|%0, %1}";
2139 return "%vmovdqa\t{%1, %0|%0, %1}";
2141 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2144 gcc_assert (!TARGET_AVX);
2145 return "movlps\t{%1, %0|%0, %1}";
2147 return "%vmovaps\t{%1, %0|%0, %1}";
2154 if (SSE_REG_P (operands[0]))
2155 return "movq2dq\t{%1, %0|%0, %1}";
2157 return "movdq2q\t{%1, %0|%0, %1}";
2160 return "lea{q}\t{%E1, %0|%0, %E1}";
2163 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2164 if (get_attr_mode (insn) == MODE_SI)
2165 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2166 else if (which_alternative == 4)
2167 return "movabs{q}\t{%1, %0|%0, %1}";
2168 else if (ix86_use_lea_for_mov (insn, operands))
2169 return "lea{q}\t{%E1, %0|%0, %E1}";
2171 return "mov{q}\t{%1, %0|%0, %1}";
2178 (cond [(eq_attr "alternative" "0,1")
2179 (const_string "nox64")
2180 (eq_attr "alternative" "2,3,4,5,10,11,16,18,21,23")
2181 (const_string "x64")
2182 (eq_attr "alternative" "17")
2183 (const_string "x64_sse4")
2185 (const_string "*")))
2187 (cond [(eq_attr "alternative" "0,1")
2188 (const_string "multi")
2189 (eq_attr "alternative" "6")
2190 (const_string "mmx")
2191 (eq_attr "alternative" "7,8,9,10,11")
2192 (const_string "mmxmov")
2193 (eq_attr "alternative" "12,17")
2194 (const_string "sselog1")
2195 (eq_attr "alternative" "13,14,15,16,18")
2196 (const_string "ssemov")
2197 (eq_attr "alternative" "19,20")
2198 (const_string "ssecvt")
2199 (eq_attr "alternative" "21,22,23,24")
2200 (const_string "mskmov")
2201 (and (match_operand 0 "register_operand")
2202 (match_operand 1 "pic_32bit_operand"))
2203 (const_string "lea")
2205 (const_string "imov")))
2208 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2210 (const_string "*")))
2211 (set (attr "length_immediate")
2212 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2214 (eq_attr "alternative" "17")
2217 (const_string "*")))
2218 (set (attr "prefix_rex")
2219 (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2221 (const_string "*")))
2222 (set (attr "prefix_extra")
2223 (if_then_else (eq_attr "alternative" "17")
2225 (const_string "*")))
2226 (set (attr "prefix")
2227 (if_then_else (eq_attr "type" "sselog1,ssemov")
2228 (const_string "maybe_vex")
2229 (const_string "orig")))
2230 (set (attr "prefix_data16")
2231 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2233 (const_string "*")))
2235 (cond [(eq_attr "alternative" "2")
2237 (eq_attr "alternative" "12,13")
2238 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2239 (match_operand 1 "ext_sse_reg_operand"))
2241 (ior (not (match_test "TARGET_SSE2"))
2242 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2243 (const_string "V4SF")
2244 (match_test "TARGET_AVX")
2246 (match_test "optimize_function_for_size_p (cfun)")
2247 (const_string "V4SF")
2249 (const_string "TI"))
2251 (and (eq_attr "alternative" "14,15")
2252 (not (match_test "TARGET_SSE2")))
2253 (const_string "V2SF")
2254 (eq_attr "alternative" "17")
2257 (const_string "DI")))])
2260 [(set (match_operand:DI 0 "nonimmediate_operand")
2261 (match_operand:DI 1 "general_operand"))]
2262 "!TARGET_64BIT && reload_completed
2263 && !(MMX_REG_P (operands[0])
2264 || SSE_REG_P (operands[0])
2265 || MASK_REG_P (operands[0]))
2266 && !(MMX_REG_P (operands[1])
2267 || SSE_REG_P (operands[1])
2268 || MASK_REG_P (operands[1]))"
2270 "ix86_split_long_move (operands); DONE;")
2272 (define_insn "*movsi_internal"
2273 [(set (match_operand:SI 0 "nonimmediate_operand"
2274 "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k ,*rm")
2275 (match_operand:SI 1 "general_operand"
2276 "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r ,*krm,*k"))]
2277 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2279 switch (get_attr_type (insn))
2282 if (GENERAL_REG_P (operands[0]))
2283 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2285 return standard_sse_constant_opcode (insn, operands[1]);
2288 return "kmovd\t{%1, %0|%0, %1}";
2291 switch (get_attr_mode (insn))
2294 return "%vmovd\t{%1, %0|%0, %1}";
2296 return "%vmovdqa\t{%1, %0|%0, %1}";
2298 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2301 return "%vmovaps\t{%1, %0|%0, %1}";
2304 gcc_assert (!TARGET_AVX);
2305 return "movss\t{%1, %0|%0, %1}";
2312 return "pxor\t%0, %0";
2315 switch (get_attr_mode (insn))
2318 return "movq\t{%1, %0|%0, %1}";
2320 return "movd\t{%1, %0|%0, %1}";
2327 return "lea{l}\t{%E1, %0|%0, %E1}";
2330 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2331 if (ix86_use_lea_for_mov (insn, operands))
2332 return "lea{l}\t{%E1, %0|%0, %E1}";
2334 return "mov{l}\t{%1, %0|%0, %1}";
2341 (if_then_else (eq_attr "alternative" "11")
2342 (const_string "sse4")
2343 (const_string "*")))
2345 (cond [(eq_attr "alternative" "2")
2346 (const_string "mmx")
2347 (eq_attr "alternative" "3,4,5")
2348 (const_string "mmxmov")
2349 (eq_attr "alternative" "6,11")
2350 (const_string "sselog1")
2351 (eq_attr "alternative" "7,8,9,10,12")
2352 (const_string "ssemov")
2353 (eq_attr "alternative" "13,14")
2354 (const_string "mskmov")
2355 (and (match_operand 0 "register_operand")
2356 (match_operand 1 "pic_32bit_operand"))
2357 (const_string "lea")
2359 (const_string "imov")))
2360 (set (attr "length_immediate")
2361 (if_then_else (eq_attr "alternative" "11")
2363 (const_string "*")))
2364 (set (attr "prefix_extra")
2365 (if_then_else (eq_attr "alternative" "11")
2367 (const_string "*")))
2368 (set (attr "prefix")
2369 (if_then_else (eq_attr "type" "sselog1,ssemov")
2370 (const_string "maybe_vex")
2371 (const_string "orig")))
2372 (set (attr "prefix_data16")
2373 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2375 (const_string "*")))
2377 (cond [(eq_attr "alternative" "2,3")
2379 (eq_attr "alternative" "6,7")
2380 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2381 (match_operand 1 "ext_sse_reg_operand"))
2383 (ior (not (match_test "TARGET_SSE2"))
2384 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2385 (const_string "V4SF")
2386 (match_test "TARGET_AVX")
2388 (match_test "optimize_function_for_size_p (cfun)")
2389 (const_string "V4SF")
2391 (const_string "TI"))
2393 (and (eq_attr "alternative" "8,9")
2394 (not (match_test "TARGET_SSE2")))
2396 (eq_attr "alternative" "11")
2399 (const_string "SI")))])
2401 (define_insn "kmovw"
2402 [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2404 [(match_operand:HI 1 "nonimmediate_operand" "rm,k")]
2406 "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2408 kmovw\t{%k1, %0|%0, %k1}
2409 kmovw\t{%1, %0|%0, %1}";
2410 [(set_attr "mode" "HI")
2411 (set_attr "type" "mskmov")
2412 (set_attr "prefix" "vex")])
2415 (define_insn "*movhi_internal"
2416 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k,rm")
2417 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,rm,k,k"))]
2418 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2420 switch (get_attr_type (insn))
2423 /* movzwl is faster than movw on p2 due to partial word stalls,
2424 though not as fast as an aligned movl. */
2425 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2428 switch (which_alternative)
2430 case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2431 case 5: return "kmovw\t{%1, %0|%0, %1}";
2432 case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2433 default: gcc_unreachable ();
2437 if (get_attr_mode (insn) == MODE_SI)
2438 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2440 return "mov{w}\t{%1, %0|%0, %1}";
2444 (cond [(eq_attr "alternative" "4,5,6")
2445 (const_string "mskmov")
2446 (match_test "optimize_function_for_size_p (cfun)")
2447 (const_string "imov")
2448 (and (eq_attr "alternative" "0")
2449 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2450 (not (match_test "TARGET_HIMODE_MATH"))))
2451 (const_string "imov")
2452 (and (eq_attr "alternative" "1,2")
2453 (match_operand:HI 1 "aligned_operand"))
2454 (const_string "imov")
2455 (and (match_test "TARGET_MOVX")
2456 (eq_attr "alternative" "0,2"))
2457 (const_string "imovx")
2459 (const_string "imov")))
2460 (set (attr "prefix")
2461 (if_then_else (eq_attr "alternative" "4,5,6")
2462 (const_string "vex")
2463 (const_string "orig")))
2465 (cond [(eq_attr "type" "imovx")
2467 (and (eq_attr "alternative" "1,2")
2468 (match_operand:HI 1 "aligned_operand"))
2470 (and (eq_attr "alternative" "0")
2471 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2472 (not (match_test "TARGET_HIMODE_MATH"))))
2475 (const_string "HI")))])
2477 ;; Situation is quite tricky about when to choose full sized (SImode) move
2478 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2479 ;; partial register dependency machines (such as AMD Athlon), where QImode
2480 ;; moves issue extra dependency and for partial register stalls machines
2481 ;; that don't use QImode patterns (and QImode move cause stall on the next
2484 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2485 ;; register stall machines with, where we use QImode instructions, since
2486 ;; partial register stall can be caused there. Then we use movzx.
2488 (define_insn "*movqi_internal"
2489 [(set (match_operand:QI 0 "nonimmediate_operand"
2490 "=q,q ,q ,r,r ,?r,m ,k,k,r ,m,k")
2491 (match_operand:QI 1 "general_operand"
2492 "q ,qn,qm,q,rn,qm,qn,r ,k,k,k,m"))]
2493 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2495 switch (get_attr_type (insn))
2498 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2499 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2502 switch (which_alternative)
2504 case 7: return TARGET_AVX512DQ ? "kmovb\t{%k1, %0|%0, %k1}"
2505 : "kmovw\t{%k1, %0|%0, %k1}";
2506 case 8: return TARGET_AVX512DQ ? "kmovb\t{%1, %0|%0, %1}"
2507 : "kmovw\t{%1, %0|%0, %1}";
2508 case 9: return TARGET_AVX512DQ ? "kmovb\t{%1, %k0|%k0, %1}"
2509 : "kmovw\t{%1, %k0|%k0, %1}";
2512 gcc_assert (TARGET_AVX512DQ);
2513 return "kmovb\t{%1, %0|%0, %1}";
2514 default: gcc_unreachable ();
2518 if (get_attr_mode (insn) == MODE_SI)
2519 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2521 return "mov{b}\t{%1, %0|%0, %1}";
2524 [(set_attr "isa" "*,*,*,*,*,*,*,*,*,*,avx512dq,avx512dq")
2526 (cond [(eq_attr "alternative" "7,8,9,10,11")
2527 (const_string "mskmov")
2528 (and (eq_attr "alternative" "5")
2529 (not (match_operand:QI 1 "aligned_operand")))
2530 (const_string "imovx")
2531 (match_test "optimize_function_for_size_p (cfun)")
2532 (const_string "imov")
2533 (and (eq_attr "alternative" "3")
2534 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2535 (not (match_test "TARGET_QIMODE_MATH"))))
2536 (const_string "imov")
2537 (eq_attr "alternative" "3,5")
2538 (const_string "imovx")
2539 (and (match_test "TARGET_MOVX")
2540 (eq_attr "alternative" "2"))
2541 (const_string "imovx")
2543 (const_string "imov")))
2544 (set (attr "prefix")
2545 (if_then_else (eq_attr "alternative" "7,8,9")
2546 (const_string "vex")
2547 (const_string "orig")))
2549 (cond [(eq_attr "alternative" "3,4,5")
2551 (eq_attr "alternative" "6")
2553 (eq_attr "type" "imovx")
2555 (and (eq_attr "type" "imov")
2556 (and (eq_attr "alternative" "0,1")
2557 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2558 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2559 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2561 ;; Avoid partial register stalls when not using QImode arithmetic
2562 (and (eq_attr "type" "imov")
2563 (and (eq_attr "alternative" "0,1")
2564 (and (match_test "TARGET_PARTIAL_REG_STALL")
2565 (not (match_test "TARGET_QIMODE_MATH")))))
2568 (const_string "QI")))])
2570 ;; Stores and loads of ax to arbitrary constant address.
2571 ;; We fake an second form of instruction to force reload to load address
2572 ;; into register when rax is not available
2573 (define_insn "*movabs<mode>_1"
2574 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2575 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2576 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2578 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2579 mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2580 [(set_attr "type" "imov")
2581 (set_attr "modrm" "0,*")
2582 (set_attr "length_address" "8,0")
2583 (set_attr "length_immediate" "0,*")
2584 (set_attr "memory" "store")
2585 (set_attr "mode" "<MODE>")])
2587 (define_insn "*movabs<mode>_2"
2588 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2589 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2590 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2592 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2593 mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2594 [(set_attr "type" "imov")
2595 (set_attr "modrm" "0,*")
2596 (set_attr "length_address" "8,0")
2597 (set_attr "length_immediate" "0")
2598 (set_attr "memory" "load")
2599 (set_attr "mode" "<MODE>")])
2601 (define_insn "*swap<mode>"
2602 [(set (match_operand:SWI48 0 "register_operand" "+r")
2603 (match_operand:SWI48 1 "register_operand" "+r"))
2607 "xchg{<imodesuffix>}\t%1, %0"
2608 [(set_attr "type" "imov")
2609 (set_attr "mode" "<MODE>")
2610 (set_attr "pent_pair" "np")
2611 (set_attr "athlon_decode" "vector")
2612 (set_attr "amdfam10_decode" "double")
2613 (set_attr "bdver1_decode" "double")])
2615 (define_insn "*swap<mode>_1"
2616 [(set (match_operand:SWI12 0 "register_operand" "+r")
2617 (match_operand:SWI12 1 "register_operand" "+r"))
2620 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2622 [(set_attr "type" "imov")
2623 (set_attr "mode" "SI")
2624 (set_attr "pent_pair" "np")
2625 (set_attr "athlon_decode" "vector")
2626 (set_attr "amdfam10_decode" "double")
2627 (set_attr "bdver1_decode" "double")])
2629 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2630 ;; is disabled for AMDFAM10
2631 (define_insn "*swap<mode>_2"
2632 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2633 (match_operand:SWI12 1 "register_operand" "+<r>"))
2636 "TARGET_PARTIAL_REG_STALL"
2637 "xchg{<imodesuffix>}\t%1, %0"
2638 [(set_attr "type" "imov")
2639 (set_attr "mode" "<MODE>")
2640 (set_attr "pent_pair" "np")
2641 (set_attr "athlon_decode" "vector")])
2643 (define_expand "movstrict<mode>"
2644 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2645 (match_operand:SWI12 1 "general_operand"))]
2648 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2650 if (GET_CODE (operands[0]) == SUBREG
2651 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2653 /* Don't generate memory->memory moves, go through a register */
2654 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2655 operands[1] = force_reg (<MODE>mode, operands[1]);
2658 (define_insn "*movstrict<mode>_1"
2659 [(set (strict_low_part
2660 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2661 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2662 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2663 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2664 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2665 [(set_attr "type" "imov")
2666 (set_attr "mode" "<MODE>")])
2668 (define_insn "*movstrict<mode>_xor"
2669 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2670 (match_operand:SWI12 1 "const0_operand"))
2671 (clobber (reg:CC FLAGS_REG))]
2673 "xor{<imodesuffix>}\t%0, %0"
2674 [(set_attr "type" "alu1")
2675 (set_attr "mode" "<MODE>")
2676 (set_attr "length_immediate" "0")])
2678 (define_expand "extv<mode>"
2679 [(set (match_operand:SWI24 0 "register_operand")
2680 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2681 (match_operand:SI 2 "const_int_operand")
2682 (match_operand:SI 3 "const_int_operand")))]
2685 /* Handle extractions from %ah et al. */
2686 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2689 if (! ext_register_operand (operands[1], VOIDmode))
2690 operands[1] = copy_to_reg (operands[1]);
2693 (define_insn "*extv<mode>"
2694 [(set (match_operand:SWI24 0 "register_operand" "=R")
2695 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2699 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2700 [(set_attr "type" "imovx")
2701 (set_attr "mode" "SI")])
2703 (define_insn "*extvqi"
2704 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2705 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2710 switch (get_attr_type (insn))
2713 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2715 return "mov{b}\t{%h1, %0|%0, %h1}";
2718 [(set_attr "isa" "*,*,nox64")
2720 (if_then_else (and (match_operand:QI 0 "register_operand")
2721 (ior (not (match_operand:QI 0 "QIreg_operand"))
2722 (match_test "TARGET_MOVX")))
2723 (const_string "imovx")
2724 (const_string "imov")))
2726 (if_then_else (eq_attr "type" "imovx")
2728 (const_string "QI")))])
2730 (define_expand "extzv<mode>"
2731 [(set (match_operand:SWI248 0 "register_operand")
2732 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2733 (match_operand:SI 2 "const_int_operand")
2734 (match_operand:SI 3 "const_int_operand")))]
2737 if (ix86_expand_pextr (operands))
2740 /* Handle extractions from %ah et al. */
2741 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2744 if (! ext_register_operand (operands[1], VOIDmode))
2745 operands[1] = copy_to_reg (operands[1]);
2748 (define_insn "*extzv<mode>"
2749 [(set (match_operand:SWI248 0 "register_operand" "=R")
2750 (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2754 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2755 [(set_attr "type" "imovx")
2756 (set_attr "mode" "SI")])
2758 (define_insn "*extzvqi"
2759 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2761 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2766 switch (get_attr_type (insn))
2769 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2771 return "mov{b}\t{%h1, %0|%0, %h1}";
2774 [(set_attr "isa" "*,*,nox64")
2776 (if_then_else (and (match_operand:QI 0 "register_operand")
2777 (ior (not (match_operand:QI 0 "QIreg_operand"))
2778 (match_test "TARGET_MOVX")))
2779 (const_string "imovx")
2780 (const_string "imov")))
2782 (if_then_else (eq_attr "type" "imovx")
2784 (const_string "QI")))])
2786 (define_expand "insv<mode>"
2787 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
2788 (match_operand:SI 1 "const_int_operand")
2789 (match_operand:SI 2 "const_int_operand"))
2790 (match_operand:SWI248 3 "register_operand"))]
2795 if (ix86_expand_pinsr (operands))
2798 /* Handle insertions to %ah et al. */
2799 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
2804 if (!ext_register_operand (dst, VOIDmode))
2805 dst = copy_to_reg (dst);
2807 emit_insn (gen_insv<mode>_1 (dst, operands[3]));
2809 /* Fix up the destination if needed. */
2810 if (dst != operands[0])
2811 emit_move_insn (operands[0], dst);
2816 (define_insn "insv<mode>_1"
2817 [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
2820 (match_operand:SWI248 1 "general_x64nomem_operand" "Qn,m"))]
2823 if (CONST_INT_P (operands[1]))
2824 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2825 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2827 [(set_attr "isa" "*,nox64")
2828 (set_attr "type" "imov")
2829 (set_attr "mode" "QI")])
2831 (define_insn "*insvqi"
2832 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2835 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2838 "mov{b}\t{%h1, %h0|%h0, %h1}"
2839 [(set_attr "type" "imov")
2840 (set_attr "mode" "QI")])
2842 ;; Floating point push instructions.
2844 (define_insn "*pushtf"
2845 [(set (match_operand:TF 0 "push_operand" "=<,<")
2846 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2847 "TARGET_64BIT || TARGET_SSE"
2849 /* This insn should be already split before reg-stack. */
2852 [(set_attr "isa" "*,x64")
2853 (set_attr "type" "multi")
2854 (set_attr "unit" "sse,*")
2855 (set_attr "mode" "TF,DI")])
2857 ;; %%% Kill this when call knows how to work this out.
2859 [(set (match_operand:TF 0 "push_operand")
2860 (match_operand:TF 1 "sse_reg_operand"))]
2861 "TARGET_SSE && reload_completed"
2862 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2863 (set (match_dup 0) (match_dup 1))]
2865 /* Preserve memory attributes. */
2866 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2869 (define_insn "*pushxf"
2870 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<")
2871 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF"))]
2874 /* This insn should be already split before reg-stack. */
2877 [(set_attr "type" "multi")
2878 (set_attr "unit" "i387,*,*,*")
2880 (cond [(eq_attr "alternative" "1,2,3")
2881 (if_then_else (match_test "TARGET_64BIT")
2883 (const_string "SI"))
2885 (const_string "XF")))
2886 (set (attr "preferred_for_size")
2887 (cond [(eq_attr "alternative" "1")
2888 (symbol_ref "false")]
2889 (symbol_ref "true")))])
2891 ;; %%% Kill this when call knows how to work this out.
2893 [(set (match_operand:XF 0 "push_operand")
2894 (match_operand:XF 1 "fp_register_operand"))]
2896 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2897 (set (match_dup 0) (match_dup 1))]
2899 operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2900 /* Preserve memory attributes. */
2901 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2904 (define_insn "*pushdf"
2905 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
2906 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmF,x"))]
2909 /* This insn should be already split before reg-stack. */
2912 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
2913 (set_attr "type" "multi")
2914 (set_attr "unit" "i387,*,*,*,*,sse")
2915 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
2916 (set (attr "preferred_for_size")
2917 (cond [(eq_attr "alternative" "1")
2918 (symbol_ref "false")]
2919 (symbol_ref "true")))
2920 (set (attr "preferred_for_speed")
2921 (cond [(eq_attr "alternative" "1")
2922 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
2923 (symbol_ref "true")))])
2925 ;; %%% Kill this when call knows how to work this out.
2927 [(set (match_operand:DF 0 "push_operand")
2928 (match_operand:DF 1 "any_fp_register_operand"))]
2930 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2931 (set (match_dup 0) (match_dup 1))]
2933 /* Preserve memory attributes. */
2934 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2937 (define_insn "*pushsf_rex64"
2938 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2939 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2942 /* Anything else should be already split before reg-stack. */
2943 gcc_assert (which_alternative == 1);
2944 return "push{q}\t%q1";
2946 [(set_attr "type" "multi,push,multi")
2947 (set_attr "unit" "i387,*,*")
2948 (set_attr "mode" "SF,DI,SF")])
2950 (define_insn "*pushsf"
2951 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2952 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2955 /* Anything else should be already split before reg-stack. */
2956 gcc_assert (which_alternative == 1);
2957 return "push{l}\t%1";
2959 [(set_attr "type" "multi,push,multi")
2960 (set_attr "unit" "i387,*,*")
2961 (set_attr "mode" "SF,SI,SF")])
2963 ;; %%% Kill this when call knows how to work this out.
2965 [(set (match_operand:SF 0 "push_operand")
2966 (match_operand:SF 1 "any_fp_register_operand"))]
2968 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2969 (set (match_dup 0) (match_dup 1))]
2971 rtx op = XEXP (operands[0], 0);
2972 if (GET_CODE (op) == PRE_DEC)
2974 gcc_assert (!TARGET_64BIT);
2979 op = XEXP (XEXP (op, 1), 1);
2980 gcc_assert (CONST_INT_P (op));
2983 /* Preserve memory attributes. */
2984 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2988 [(set (match_operand:SF 0 "push_operand")
2989 (match_operand:SF 1 "memory_operand"))]
2991 && (operands[2] = find_constant_src (insn))"
2992 [(set (match_dup 0) (match_dup 2))])
2995 [(set (match_operand 0 "push_operand")
2996 (match_operand 1 "general_operand"))]
2998 && (GET_MODE (operands[0]) == TFmode
2999 || GET_MODE (operands[0]) == XFmode
3000 || GET_MODE (operands[0]) == DFmode)
3001 && !ANY_FP_REG_P (operands[1])"
3003 "ix86_split_long_move (operands); DONE;")
3005 ;; Floating point move instructions.
3007 (define_expand "movtf"
3008 [(set (match_operand:TF 0 "nonimmediate_operand")
3009 (match_operand:TF 1 "nonimmediate_operand"))]
3010 "TARGET_64BIT || TARGET_SSE"
3011 "ix86_expand_move (TFmode, operands); DONE;")
3013 (define_expand "mov<mode>"
3014 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3015 (match_operand:X87MODEF 1 "general_operand"))]
3017 "ix86_expand_move (<MODE>mode, operands); DONE;")
3019 (define_insn "*movtf_internal"
3020 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
3021 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
3022 "(TARGET_64BIT || TARGET_SSE)
3023 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3024 && (!can_create_pseudo_p ()
3025 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3026 || !CONST_DOUBLE_P (operands[1])
3027 || (optimize_function_for_size_p (cfun)
3028 && standard_sse_constant_p (operands[1])
3029 && !memory_operand (operands[0], TFmode))
3030 || (!TARGET_MEMORY_MISMATCH_STALL
3031 && memory_operand (operands[0], TFmode)))"
3033 switch (get_attr_type (insn))
3036 return standard_sse_constant_opcode (insn, operands[1]);
3039 /* Handle misaligned load/store since we
3040 don't have movmisaligntf pattern. */
3041 if (misaligned_operand (operands[0], TFmode)
3042 || misaligned_operand (operands[1], TFmode))
3044 if (get_attr_mode (insn) == MODE_V4SF)
3045 return "%vmovups\t{%1, %0|%0, %1}";
3047 return "%vmovdqu\t{%1, %0|%0, %1}";
3051 if (get_attr_mode (insn) == MODE_V4SF)
3052 return "%vmovaps\t{%1, %0|%0, %1}";
3054 return "%vmovdqa\t{%1, %0|%0, %1}";
3064 [(set_attr "isa" "*,*,*,x64,x64")
3065 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3066 (set (attr "prefix")
3067 (if_then_else (eq_attr "type" "sselog1,ssemov")
3068 (const_string "maybe_vex")
3069 (const_string "orig")))
3071 (cond [(eq_attr "alternative" "3,4")
3073 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3074 (const_string "V4SF")
3075 (and (eq_attr "alternative" "2")
3076 (match_test "TARGET_SSE_TYPELESS_STORES"))
3077 (const_string "V4SF")
3078 (match_test "TARGET_AVX")
3080 (ior (not (match_test "TARGET_SSE2"))
3081 (match_test "optimize_function_for_size_p (cfun)"))
3082 (const_string "V4SF")
3084 (const_string "TI")))])
3086 ;; Possible store forwarding (partial memory) stall
3087 ;; in alternatives 4, 6, 7 and 8.
3088 (define_insn "*movxf_internal"
3089 [(set (match_operand:XF 0 "nonimmediate_operand"
3090 "=f,m,f,?r ,!o,?*r ,!o,!o,!o")
3091 (match_operand:XF 1 "general_operand"
3092 "fm,f,G,roF,r , *roF,*r,F ,C"))]
3093 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3094 && (!can_create_pseudo_p ()
3095 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3096 || !CONST_DOUBLE_P (operands[1])
3097 || (optimize_function_for_size_p (cfun)
3098 && standard_80387_constant_p (operands[1]) > 0
3099 && !memory_operand (operands[0], XFmode))
3100 || (!TARGET_MEMORY_MISMATCH_STALL
3101 && memory_operand (operands[0], XFmode)))"
3103 switch (get_attr_type (insn))
3106 if (which_alternative == 2)
3107 return standard_80387_constant_opcode (operands[1]);
3108 return output_387_reg_move (insn, operands);
3118 (cond [(eq_attr "alternative" "7")
3119 (const_string "nox64")
3120 (eq_attr "alternative" "8")
3121 (const_string "x64")
3123 (const_string "*")))
3125 (cond [(eq_attr "alternative" "3,4,5,6,7,8")
3126 (const_string "multi")
3128 (const_string "fmov")))
3130 (cond [(eq_attr "alternative" "3,4,5,6,7,8")
3131 (if_then_else (match_test "TARGET_64BIT")
3133 (const_string "SI"))
3135 (const_string "XF")))
3136 (set (attr "preferred_for_size")
3137 (cond [(eq_attr "alternative" "3,4")
3138 (symbol_ref "false")]
3139 (symbol_ref "true")))])
3141 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3142 (define_insn "*movdf_internal"
3143 [(set (match_operand:DF 0 "nonimmediate_operand"
3144 "=Yf*f,m ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
3145 (match_operand:DF 1 "general_operand"
3146 "Yf*fm,Yf*f,G ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
3147 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3148 && (!can_create_pseudo_p ()
3149 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3150 || !CONST_DOUBLE_P (operands[1])
3151 || (optimize_function_for_size_p (cfun)
3152 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3153 && standard_80387_constant_p (operands[1]) > 0)
3154 || (TARGET_SSE2 && TARGET_SSE_MATH
3155 && standard_sse_constant_p (operands[1])))
3156 && !memory_operand (operands[0], DFmode))
3157 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3158 && memory_operand (operands[0], DFmode)))"
3160 switch (get_attr_type (insn))
3163 if (which_alternative == 2)
3164 return standard_80387_constant_opcode (operands[1]);
3165 return output_387_reg_move (insn, operands);
3171 if (get_attr_mode (insn) == MODE_SI)
3172 return "mov{l}\t{%1, %k0|%k0, %1}";
3173 else if (which_alternative == 11)
3174 return "movabs{q}\t{%1, %0|%0, %1}";
3176 return "mov{q}\t{%1, %0|%0, %1}";
3179 return standard_sse_constant_opcode (insn, operands[1]);
3182 switch (get_attr_mode (insn))
3185 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3186 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3187 return "%vmovsd\t{%1, %0|%0, %1}";
3190 return "%vmovaps\t{%1, %0|%0, %1}";
3192 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3194 return "%vmovapd\t{%1, %0|%0, %1}";
3197 gcc_assert (!TARGET_AVX);
3198 return "movlps\t{%1, %0|%0, %1}";
3200 gcc_assert (!TARGET_AVX);
3201 return "movlpd\t{%1, %0|%0, %1}";
3204 /* Handle broken assemblers that require movd instead of movq. */
3205 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3206 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3207 return "%vmovd\t{%1, %0|%0, %1}";
3208 return "%vmovq\t{%1, %0|%0, %1}";
3219 (cond [(eq_attr "alternative" "3,4,5,6,7")
3220 (const_string "nox64")
3221 (eq_attr "alternative" "8,9,10,11,20,21")
3222 (const_string "x64")
3223 (eq_attr "alternative" "12,13,14,15")
3224 (const_string "sse2")
3226 (const_string "*")))
3228 (cond [(eq_attr "alternative" "0,1,2")
3229 (const_string "fmov")
3230 (eq_attr "alternative" "3,4,5,6,7")
3231 (const_string "multi")
3232 (eq_attr "alternative" "8,9,10,11")
3233 (const_string "imov")
3234 (eq_attr "alternative" "12,16")
3235 (const_string "sselog1")
3237 (const_string "ssemov")))
3239 (if_then_else (eq_attr "alternative" "11")
3241 (const_string "*")))
3242 (set (attr "length_immediate")
3243 (if_then_else (eq_attr "alternative" "11")
3245 (const_string "*")))
3246 (set (attr "prefix")
3247 (if_then_else (eq_attr "type" "sselog1,ssemov")
3248 (const_string "maybe_vex")
3249 (const_string "orig")))
3250 (set (attr "prefix_data16")
3252 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3253 (eq_attr "mode" "V1DF"))
3255 (const_string "*")))
3257 (cond [(eq_attr "alternative" "3,4,5,6,7,10")
3259 (eq_attr "alternative" "8,9,11,20,21")
3262 /* xorps is one byte shorter for non-AVX targets. */
3263 (eq_attr "alternative" "12,16")
3264 (cond [(not (match_test "TARGET_SSE2"))
3265 (const_string "V4SF")
3266 (match_test "TARGET_AVX512F")
3268 (match_test "TARGET_AVX")
3269 (const_string "V2DF")
3270 (match_test "optimize_function_for_size_p (cfun)")
3271 (const_string "V4SF")
3272 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3275 (const_string "V2DF"))
3277 /* For architectures resolving dependencies on
3278 whole SSE registers use movapd to break dependency
3279 chains, otherwise use short move to avoid extra work. */
3281 /* movaps is one byte shorter for non-AVX targets. */
3282 (eq_attr "alternative" "13,17")
3283 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3284 (match_operand 1 "ext_sse_reg_operand"))
3285 (const_string "V8DF")
3286 (ior (not (match_test "TARGET_SSE2"))
3287 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3288 (const_string "V4SF")
3289 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3290 (const_string "V2DF")
3291 (match_test "TARGET_AVX")
3293 (match_test "optimize_function_for_size_p (cfun)")
3294 (const_string "V4SF")
3296 (const_string "DF"))
3298 /* For architectures resolving dependencies on register
3299 parts we may avoid extra work to zero out upper part
3301 (eq_attr "alternative" "14,18")
3302 (cond [(not (match_test "TARGET_SSE2"))
3303 (const_string "V2SF")
3304 (match_test "TARGET_AVX")
3306 (match_test "TARGET_SSE_SPLIT_REGS")
3307 (const_string "V1DF")
3309 (const_string "DF"))
3311 (and (eq_attr "alternative" "15,19")
3312 (not (match_test "TARGET_SSE2")))
3313 (const_string "V2SF")
3315 (const_string "DF")))
3316 (set (attr "preferred_for_size")
3317 (cond [(eq_attr "alternative" "3,4")
3318 (symbol_ref "false")]
3319 (symbol_ref "true")))
3320 (set (attr "preferred_for_speed")
3321 (cond [(eq_attr "alternative" "3,4")
3322 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3323 (symbol_ref "true")))])
3325 (define_insn "*movsf_internal"
3326 [(set (match_operand:SF 0 "nonimmediate_operand"
3327 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3328 (match_operand:SF 1 "general_operand"
3329 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r"))]
3330 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3331 && (!can_create_pseudo_p ()
3332 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3333 || !CONST_DOUBLE_P (operands[1])
3334 || (optimize_function_for_size_p (cfun)
3335 && ((!TARGET_SSE_MATH
3336 && standard_80387_constant_p (operands[1]) > 0)
3338 && standard_sse_constant_p (operands[1]))))
3339 || memory_operand (operands[0], SFmode))"
3341 switch (get_attr_type (insn))
3344 if (which_alternative == 2)
3345 return standard_80387_constant_opcode (operands[1]);
3346 return output_387_reg_move (insn, operands);
3349 return "mov{l}\t{%1, %0|%0, %1}";
3352 return standard_sse_constant_opcode (insn, operands[1]);
3355 switch (get_attr_mode (insn))
3358 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3359 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3360 return "%vmovss\t{%1, %0|%0, %1}";
3363 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3365 return "%vmovaps\t{%1, %0|%0, %1}";
3368 return "%vmovd\t{%1, %0|%0, %1}";
3375 switch (get_attr_mode (insn))
3378 return "movq\t{%1, %0|%0, %1}";
3380 return "movd\t{%1, %0|%0, %1}";
3391 (cond [(eq_attr "alternative" "0,1,2")
3392 (const_string "fmov")
3393 (eq_attr "alternative" "3,4")
3394 (const_string "imov")
3395 (eq_attr "alternative" "5")
3396 (const_string "sselog1")
3397 (eq_attr "alternative" "11,12,13,14,15")
3398 (const_string "mmxmov")
3400 (const_string "ssemov")))
3401 (set (attr "prefix")
3402 (if_then_else (eq_attr "type" "sselog1,ssemov")
3403 (const_string "maybe_vex")
3404 (const_string "orig")))
3405 (set (attr "prefix_data16")
3406 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3408 (const_string "*")))
3410 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15")
3412 (eq_attr "alternative" "11")
3414 (eq_attr "alternative" "5")
3415 (cond [(not (match_test "TARGET_SSE2"))
3416 (const_string "V4SF")
3417 (match_test "TARGET_AVX512F")
3418 (const_string "V16SF")
3419 (match_test "TARGET_AVX")
3420 (const_string "V4SF")
3421 (match_test "optimize_function_for_size_p (cfun)")
3422 (const_string "V4SF")
3423 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3426 (const_string "V4SF"))
3428 /* For architectures resolving dependencies on
3429 whole SSE registers use APS move to break dependency
3430 chains, otherwise use short move to avoid extra work.
3432 Do the same for architectures resolving dependencies on
3433 the parts. While in DF mode it is better to always handle
3434 just register parts, the SF mode is different due to lack
3435 of instructions to load just part of the register. It is
3436 better to maintain the whole registers in single format
3437 to avoid problems on using packed logical operations. */
3438 (eq_attr "alternative" "6")
3439 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3440 (match_operand 1 "ext_sse_reg_operand"))
3441 (const_string "V16SF")
3442 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3443 (match_test "TARGET_SSE_SPLIT_REGS"))
3444 (const_string "V4SF")
3446 (const_string "SF"))
3448 (const_string "SF")))])
3451 [(set (match_operand 0 "any_fp_register_operand")
3452 (match_operand 1 "memory_operand"))]
3454 && (GET_MODE (operands[0]) == TFmode
3455 || GET_MODE (operands[0]) == XFmode
3456 || GET_MODE (operands[0]) == DFmode
3457 || GET_MODE (operands[0]) == SFmode)
3458 && (operands[2] = find_constant_src (insn))"
3459 [(set (match_dup 0) (match_dup 2))]
3461 rtx c = operands[2];
3462 int r = REGNO (operands[0]);
3464 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3465 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3470 [(set (match_operand 0 "any_fp_register_operand")
3471 (float_extend (match_operand 1 "memory_operand")))]
3473 && (GET_MODE (operands[0]) == TFmode
3474 || GET_MODE (operands[0]) == XFmode
3475 || GET_MODE (operands[0]) == DFmode)
3476 && (operands[2] = find_constant_src (insn))"
3477 [(set (match_dup 0) (match_dup 2))]
3479 rtx c = operands[2];
3480 int r = REGNO (operands[0]);
3482 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3483 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3487 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3489 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3490 (match_operand:X87MODEF 1 "immediate_operand"))]
3492 && (standard_80387_constant_p (operands[1]) == 8
3493 || standard_80387_constant_p (operands[1]) == 9)"
3494 [(set (match_dup 0)(match_dup 1))
3496 (neg:X87MODEF (match_dup 0)))]
3500 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3501 if (real_isnegzero (&r))
3502 operands[1] = CONST0_RTX (<MODE>mode);
3504 operands[1] = CONST1_RTX (<MODE>mode);
3508 [(set (match_operand 0 "nonimmediate_operand")
3509 (match_operand 1 "general_operand"))]
3511 && (GET_MODE (operands[0]) == TFmode
3512 || GET_MODE (operands[0]) == XFmode
3513 || GET_MODE (operands[0]) == DFmode)
3514 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3516 "ix86_split_long_move (operands); DONE;")
3518 (define_insn "swapxf"
3519 [(set (match_operand:XF 0 "register_operand" "+f")
3520 (match_operand:XF 1 "register_operand" "+f"))
3525 if (STACK_TOP_P (operands[0]))
3530 [(set_attr "type" "fxch")
3531 (set_attr "mode" "XF")])
3533 (define_insn "*swap<mode>"
3534 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3535 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3538 "TARGET_80387 || reload_completed"
3540 if (STACK_TOP_P (operands[0]))
3545 [(set_attr "type" "fxch")
3546 (set_attr "mode" "<MODE>")])
3548 ;; Zero extension instructions
3550 (define_expand "zero_extendsidi2"
3551 [(set (match_operand:DI 0 "nonimmediate_operand")
3552 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3554 (define_insn "*zero_extendsidi2"
3555 [(set (match_operand:DI 0 "nonimmediate_operand"
3556 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3558 (match_operand:SI 1 "x86_64_zext_operand"
3559 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))]
3562 switch (get_attr_type (insn))
3565 if (ix86_use_lea_for_mov (insn, operands))
3566 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3568 return "mov{l}\t{%1, %k0|%k0, %1}";
3574 return "movd\t{%1, %0|%0, %1}";
3577 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3580 if (GENERAL_REG_P (operands[0]))
3581 return "%vmovd\t{%1, %k0|%k0, %1}";
3583 return "%vmovd\t{%1, %0|%0, %1}";
3590 (cond [(eq_attr "alternative" "0,1,2")
3591 (const_string "nox64")
3592 (eq_attr "alternative" "3,7")
3593 (const_string "x64")
3594 (eq_attr "alternative" "8")
3595 (const_string "x64_sse4")
3596 (eq_attr "alternative" "10")
3597 (const_string "sse2")
3599 (const_string "*")))
3601 (cond [(eq_attr "alternative" "0,1,2,4")
3602 (const_string "multi")
3603 (eq_attr "alternative" "5,6")
3604 (const_string "mmxmov")
3605 (eq_attr "alternative" "7,9,10")
3606 (const_string "ssemov")
3607 (eq_attr "alternative" "8")
3608 (const_string "sselog1")
3610 (const_string "imovx")))
3611 (set (attr "prefix_extra")
3612 (if_then_else (eq_attr "alternative" "8")
3614 (const_string "*")))
3615 (set (attr "length_immediate")
3616 (if_then_else (eq_attr "alternative" "8")
3618 (const_string "*")))
3619 (set (attr "prefix")
3620 (if_then_else (eq_attr "type" "ssemov,sselog1")
3621 (const_string "maybe_vex")
3622 (const_string "orig")))
3623 (set (attr "prefix_0f")
3624 (if_then_else (eq_attr "type" "imovx")
3626 (const_string "*")))
3628 (cond [(eq_attr "alternative" "5,6")
3630 (eq_attr "alternative" "7,8,9")
3633 (const_string "SI")))])
3636 [(set (match_operand:DI 0 "memory_operand")
3637 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3639 [(set (match_dup 4) (const_int 0))]
3640 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3643 [(set (match_operand:DI 0 "register_operand")
3644 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3645 "!TARGET_64BIT && reload_completed
3646 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3647 && true_regnum (operands[0]) == true_regnum (operands[1])"
3648 [(set (match_dup 4) (const_int 0))]
3649 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3652 [(set (match_operand:DI 0 "nonimmediate_operand")
3653 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3654 "!TARGET_64BIT && reload_completed
3655 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3656 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3657 [(set (match_dup 3) (match_dup 1))
3658 (set (match_dup 4) (const_int 0))]
3659 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3661 (define_insn "zero_extend<mode>di2"
3662 [(set (match_operand:DI 0 "register_operand" "=r")
3664 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3666 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3667 [(set_attr "type" "imovx")
3668 (set_attr "mode" "SI")])
3670 (define_expand "zero_extend<mode>si2"
3671 [(set (match_operand:SI 0 "register_operand")
3672 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3675 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3677 operands[1] = force_reg (<MODE>mode, operands[1]);
3678 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3683 (define_insn_and_split "zero_extend<mode>si2_and"
3684 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3686 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3687 (clobber (reg:CC FLAGS_REG))]
3688 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3690 "&& reload_completed"
3691 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3692 (clobber (reg:CC FLAGS_REG))])]
3694 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3696 ix86_expand_clear (operands[0]);
3698 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3699 emit_insn (gen_movstrict<mode>
3700 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3704 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3706 [(set_attr "type" "alu1")
3707 (set_attr "mode" "SI")])
3709 (define_insn "*zero_extend<mode>si2"
3710 [(set (match_operand:SI 0 "register_operand" "=r")
3712 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3713 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3714 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3715 [(set_attr "type" "imovx")
3716 (set_attr "mode" "SI")])
3718 (define_expand "zero_extendqihi2"
3719 [(set (match_operand:HI 0 "register_operand")
3720 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3723 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3725 operands[1] = force_reg (QImode, operands[1]);
3726 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3731 (define_insn_and_split "zero_extendqihi2_and"
3732 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3733 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3734 (clobber (reg:CC FLAGS_REG))]
3735 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3737 "&& reload_completed"
3738 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3739 (clobber (reg:CC FLAGS_REG))])]
3741 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3743 ix86_expand_clear (operands[0]);
3745 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3746 emit_insn (gen_movstrictqi
3747 (gen_lowpart (QImode, operands[0]), operands[1]));
3751 operands[0] = gen_lowpart (SImode, operands[0]);
3753 [(set_attr "type" "alu1")
3754 (set_attr "mode" "SI")])
3756 ; zero extend to SImode to avoid partial register stalls
3757 (define_insn "*zero_extendqihi2"
3758 [(set (match_operand:HI 0 "register_operand" "=r")
3759 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3760 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3761 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3762 [(set_attr "type" "imovx")
3763 (set_attr "mode" "SI")])
3765 ;; Sign extension instructions
3767 (define_expand "extendsidi2"
3768 [(set (match_operand:DI 0 "register_operand")
3769 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3774 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3779 (define_insn "*extendsidi2_rex64"
3780 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3781 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3785 movs{lq|x}\t{%1, %0|%0, %1}"
3786 [(set_attr "type" "imovx")
3787 (set_attr "mode" "DI")
3788 (set_attr "prefix_0f" "0")
3789 (set_attr "modrm" "0,1")])
3791 (define_insn "extendsidi2_1"
3792 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3793 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3794 (clobber (reg:CC FLAGS_REG))
3795 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3799 ;; Split the memory case. If the source register doesn't die, it will stay
3800 ;; this way, if it does die, following peephole2s take care of it.
3802 [(set (match_operand:DI 0 "memory_operand")
3803 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3804 (clobber (reg:CC FLAGS_REG))
3805 (clobber (match_operand:SI 2 "register_operand"))]
3809 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3811 emit_move_insn (operands[3], operands[1]);
3813 /* Generate a cltd if possible and doing so it profitable. */
3814 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3815 && true_regnum (operands[1]) == AX_REG
3816 && true_regnum (operands[2]) == DX_REG)
3818 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3822 emit_move_insn (operands[2], operands[1]);
3823 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3825 emit_move_insn (operands[4], operands[2]);
3829 ;; Peepholes for the case where the source register does die, after
3830 ;; being split with the above splitter.
3832 [(set (match_operand:SI 0 "memory_operand")
3833 (match_operand:SI 1 "register_operand"))
3834 (set (match_operand:SI 2 "register_operand") (match_dup 1))
3835 (parallel [(set (match_dup 2)
3836 (ashiftrt:SI (match_dup 2) (const_int 31)))
3837 (clobber (reg:CC FLAGS_REG))])
3838 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3839 "REGNO (operands[1]) != REGNO (operands[2])
3840 && peep2_reg_dead_p (2, operands[1])
3841 && peep2_reg_dead_p (4, operands[2])
3842 && !reg_mentioned_p (operands[2], operands[3])"
3843 [(set (match_dup 0) (match_dup 1))
3844 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3845 (clobber (reg:CC FLAGS_REG))])
3846 (set (match_dup 3) (match_dup 1))])
3849 [(set (match_operand:SI 0 "memory_operand")
3850 (match_operand:SI 1 "register_operand"))
3851 (parallel [(set (match_operand:SI 2 "register_operand")
3852 (ashiftrt:SI (match_dup 1) (const_int 31)))
3853 (clobber (reg:CC FLAGS_REG))])
3854 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3855 "/* cltd is shorter than sarl $31, %eax */
3856 !optimize_function_for_size_p (cfun)
3857 && true_regnum (operands[1]) == AX_REG
3858 && true_regnum (operands[2]) == DX_REG
3859 && peep2_reg_dead_p (2, operands[1])
3860 && peep2_reg_dead_p (3, operands[2])
3861 && !reg_mentioned_p (operands[2], operands[3])"
3862 [(set (match_dup 0) (match_dup 1))
3863 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3864 (clobber (reg:CC FLAGS_REG))])
3865 (set (match_dup 3) (match_dup 1))])
3867 ;; Extend to register case. Optimize case where source and destination
3868 ;; registers match and cases where we can use cltd.
3870 [(set (match_operand:DI 0 "register_operand")
3871 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3872 (clobber (reg:CC FLAGS_REG))
3873 (clobber (match_scratch:SI 2))]
3877 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3879 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3880 emit_move_insn (operands[3], operands[1]);
3882 /* Generate a cltd if possible and doing so it profitable. */
3883 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3884 && true_regnum (operands[3]) == AX_REG
3885 && true_regnum (operands[4]) == DX_REG)
3887 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3891 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3892 emit_move_insn (operands[4], operands[1]);
3894 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3898 (define_insn "extend<mode>di2"
3899 [(set (match_operand:DI 0 "register_operand" "=r")
3901 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3903 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3904 [(set_attr "type" "imovx")
3905 (set_attr "mode" "DI")])
3907 (define_insn "extendhisi2"
3908 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3909 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3912 switch (get_attr_prefix_0f (insn))
3915 return "{cwtl|cwde}";
3917 return "movs{wl|x}\t{%1, %0|%0, %1}";
3920 [(set_attr "type" "imovx")
3921 (set_attr "mode" "SI")
3922 (set (attr "prefix_0f")
3923 ;; movsx is short decodable while cwtl is vector decoded.
3924 (if_then_else (and (eq_attr "cpu" "!k6")
3925 (eq_attr "alternative" "0"))
3927 (const_string "1")))
3929 (if_then_else (eq_attr "prefix_0f" "0")
3931 (const_string "1")))])
3933 (define_insn "*extendhisi2_zext"
3934 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3937 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3940 switch (get_attr_prefix_0f (insn))
3943 return "{cwtl|cwde}";
3945 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3948 [(set_attr "type" "imovx")
3949 (set_attr "mode" "SI")
3950 (set (attr "prefix_0f")
3951 ;; movsx is short decodable while cwtl is vector decoded.
3952 (if_then_else (and (eq_attr "cpu" "!k6")
3953 (eq_attr "alternative" "0"))
3955 (const_string "1")))
3957 (if_then_else (eq_attr "prefix_0f" "0")
3959 (const_string "1")))])
3961 (define_insn "extendqisi2"
3962 [(set (match_operand:SI 0 "register_operand" "=r")
3963 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3965 "movs{bl|x}\t{%1, %0|%0, %1}"
3966 [(set_attr "type" "imovx")
3967 (set_attr "mode" "SI")])
3969 (define_insn "*extendqisi2_zext"
3970 [(set (match_operand:DI 0 "register_operand" "=r")
3972 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3974 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3975 [(set_attr "type" "imovx")
3976 (set_attr "mode" "SI")])
3978 (define_insn "extendqihi2"
3979 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3980 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3983 switch (get_attr_prefix_0f (insn))
3986 return "{cbtw|cbw}";
3988 return "movs{bw|x}\t{%1, %0|%0, %1}";
3991 [(set_attr "type" "imovx")
3992 (set_attr "mode" "HI")
3993 (set (attr "prefix_0f")
3994 ;; movsx is short decodable while cwtl is vector decoded.
3995 (if_then_else (and (eq_attr "cpu" "!k6")
3996 (eq_attr "alternative" "0"))
3998 (const_string "1")))
4000 (if_then_else (eq_attr "prefix_0f" "0")
4002 (const_string "1")))])
4004 ;; Conversions between float and double.
4006 ;; These are all no-ops in the model used for the 80387.
4007 ;; So just emit moves.
4009 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4011 [(set (match_operand:DF 0 "push_operand")
4012 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4014 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4015 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4018 [(set (match_operand:XF 0 "push_operand")
4019 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4021 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4022 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4023 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4025 (define_expand "extendsfdf2"
4026 [(set (match_operand:DF 0 "nonimmediate_operand")
4027 (float_extend:DF (match_operand:SF 1 "general_operand")))]
4028 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4030 /* ??? Needed for compress_float_constant since all fp constants
4031 are TARGET_LEGITIMATE_CONSTANT_P. */
4032 if (CONST_DOUBLE_P (operands[1]))
4034 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4035 && standard_80387_constant_p (operands[1]) > 0)
4037 operands[1] = simplify_const_unary_operation
4038 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4039 emit_move_insn_1 (operands[0], operands[1]);
4042 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4046 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4048 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4050 We do the conversion post reload to avoid producing of 128bit spills
4051 that might lead to ICE on 32bit target. The sequence unlikely combine
4054 [(set (match_operand:DF 0 "register_operand")
4056 (match_operand:SF 1 "nonimmediate_operand")))]
4057 "TARGET_USE_VECTOR_FP_CONVERTS
4058 && optimize_insn_for_speed_p ()
4059 && reload_completed && SSE_REG_P (operands[0])
4060 && (!EXT_REX_SSE_REG_P (operands[0])
4061 || TARGET_AVX512VL)"
4066 (parallel [(const_int 0) (const_int 1)]))))]
4068 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4069 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4070 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4071 Try to avoid move when unpacking can be done in source. */
4072 if (REG_P (operands[1]))
4074 /* If it is unsafe to overwrite upper half of source, we need
4075 to move to destination and unpack there. */
4076 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4077 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4078 && true_regnum (operands[0]) != true_regnum (operands[1]))
4080 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4081 emit_move_insn (tmp, operands[1]);
4084 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4085 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4089 emit_insn (gen_vec_setv4sf_0 (operands[3],
4090 CONST0_RTX (V4SFmode), operands[1]));
4093 ;; It's more profitable to split and then extend in the same register.
4095 [(set (match_operand:DF 0 "register_operand")
4097 (match_operand:SF 1 "memory_operand")))]
4098 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4099 && optimize_insn_for_speed_p ()
4100 && SSE_REG_P (operands[0])"
4101 [(set (match_dup 2) (match_dup 1))
4102 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4103 "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
4105 (define_insn "*extendsfdf2_mixed"
4106 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,v")
4108 (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4109 "TARGET_SSE2 && TARGET_SSE_MATH"
4111 switch (which_alternative)
4115 return output_387_reg_move (insn, operands);
4118 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4124 [(set_attr "type" "fmov,fmov,ssecvt")
4125 (set_attr "prefix" "orig,orig,maybe_vex")
4126 (set_attr "mode" "SF,XF,DF")
4127 (set (attr "enabled")
4128 (cond [(eq_attr "alternative" "0,1")
4129 (symbol_ref "TARGET_MIX_SSE_I387")
4131 (symbol_ref "true")))])
4133 (define_insn "*extendsfdf2_i387"
4134 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4135 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4137 "* return output_387_reg_move (insn, operands);"
4138 [(set_attr "type" "fmov")
4139 (set_attr "mode" "SF,XF")])
4141 (define_expand "extend<mode>xf2"
4142 [(set (match_operand:XF 0 "nonimmediate_operand")
4143 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4146 /* ??? Needed for compress_float_constant since all fp constants
4147 are TARGET_LEGITIMATE_CONSTANT_P. */
4148 if (CONST_DOUBLE_P (operands[1]))
4150 if (standard_80387_constant_p (operands[1]) > 0)
4152 operands[1] = simplify_const_unary_operation
4153 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4154 emit_move_insn_1 (operands[0], operands[1]);
4157 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4161 (define_insn "*extend<mode>xf2_i387"
4162 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4164 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4166 "* return output_387_reg_move (insn, operands);"
4167 [(set_attr "type" "fmov")
4168 (set_attr "mode" "<MODE>,XF")])
4170 ;; %%% This seems like bad news.
4171 ;; This cannot output into an f-reg because there is no way to be sure
4172 ;; of truncating in that case. Otherwise this is just like a simple move
4173 ;; insn. So we pretend we can output to a reg in order to get better
4174 ;; register preferencing, but we really use a stack slot.
4176 ;; Conversion from DFmode to SFmode.
4178 (define_expand "truncdfsf2"
4179 [(set (match_operand:SF 0 "nonimmediate_operand")
4181 (match_operand:DF 1 "nonimmediate_operand")))]
4182 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4184 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4186 else if (flag_unsafe_math_optimizations)
4190 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4191 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4196 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4198 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4200 We do the conversion post reload to avoid producing of 128bit spills
4201 that might lead to ICE on 32bit target. The sequence unlikely combine
4204 [(set (match_operand:SF 0 "register_operand")
4206 (match_operand:DF 1 "nonimmediate_operand")))]
4207 "TARGET_USE_VECTOR_FP_CONVERTS
4208 && optimize_insn_for_speed_p ()
4209 && reload_completed && SSE_REG_P (operands[0])
4210 && (!EXT_REX_SSE_REG_P (operands[0])
4211 || TARGET_AVX512VL)"
4214 (float_truncate:V2SF
4218 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4219 operands[3] = CONST0_RTX (V2SFmode);
4220 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4221 /* Use movsd for loading from memory, unpcklpd for registers.
4222 Try to avoid move when unpacking can be done in source, or SSE3
4223 movddup is available. */
4224 if (REG_P (operands[1]))
4227 && true_regnum (operands[0]) != true_regnum (operands[1])
4228 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4229 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4231 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4232 emit_move_insn (tmp, operands[1]);
4235 else if (!TARGET_SSE3)
4236 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4237 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4240 emit_insn (gen_sse2_loadlpd (operands[4],
4241 CONST0_RTX (V2DFmode), operands[1]));
4244 ;; It's more profitable to split and then extend in the same register.
4246 [(set (match_operand:SF 0 "register_operand")
4248 (match_operand:DF 1 "memory_operand")))]
4249 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4250 && optimize_insn_for_speed_p ()
4251 && SSE_REG_P (operands[0])"
4252 [(set (match_dup 2) (match_dup 1))
4253 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4254 "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4256 (define_expand "truncdfsf2_with_temp"
4257 [(parallel [(set (match_operand:SF 0)
4258 (float_truncate:SF (match_operand:DF 1)))
4259 (clobber (match_operand:SF 2))])])
4261 ;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
4262 ;; because nothing we do there is unsafe.
4263 (define_insn "*truncdfsf_fast_mixed"
4264 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,v")
4266 (match_operand:DF 1 "nonimmediate_operand" "f ,vm")))]
4267 "TARGET_SSE2 && TARGET_SSE_MATH"
4269 switch (which_alternative)
4272 return output_387_reg_move (insn, operands);
4274 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4279 [(set_attr "type" "fmov,ssecvt")
4280 (set_attr "prefix" "orig,maybe_vex")
4281 (set_attr "mode" "SF")
4282 (set (attr "enabled")
4283 (cond [(eq_attr "alternative" "0")
4284 (symbol_ref "TARGET_MIX_SSE_I387
4285 && flag_unsafe_math_optimizations")
4287 (symbol_ref "true")))])
4289 (define_insn "*truncdfsf_fast_i387"
4290 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4292 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4293 "TARGET_80387 && flag_unsafe_math_optimizations"
4294 "* return output_387_reg_move (insn, operands);"
4295 [(set_attr "type" "fmov")
4296 (set_attr "mode" "SF")])
4298 (define_insn "*truncdfsf_mixed"
4299 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4301 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4302 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4303 "TARGET_MIX_SSE_I387"
4305 switch (which_alternative)
4308 return output_387_reg_move (insn, operands);
4310 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4316 [(set_attr "isa" "*,sse2,*,*,*")
4317 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4318 (set_attr "unit" "*,*,i387,i387,i387")
4319 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4320 (set_attr "mode" "SF")])
4322 (define_insn "*truncdfsf_i387"
4323 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4325 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4326 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4329 switch (which_alternative)
4332 return output_387_reg_move (insn, operands);
4338 [(set_attr "type" "fmov,multi,multi,multi")
4339 (set_attr "unit" "*,i387,i387,i387")
4340 (set_attr "mode" "SF")])
4342 (define_insn "*truncdfsf2_i387_1"
4343 [(set (match_operand:SF 0 "memory_operand" "=m")
4345 (match_operand:DF 1 "register_operand" "f")))]
4347 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4348 && !TARGET_MIX_SSE_I387"
4349 "* return output_387_reg_move (insn, operands);"
4350 [(set_attr "type" "fmov")
4351 (set_attr "mode" "SF")])
4354 [(set (match_operand:SF 0 "register_operand")
4356 (match_operand:DF 1 "fp_register_operand")))
4357 (clobber (match_operand 2))]
4359 [(set (match_dup 2) (match_dup 1))
4360 (set (match_dup 0) (match_dup 2))]
4361 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4363 ;; Conversion from XFmode to {SF,DF}mode
4365 (define_expand "truncxf<mode>2"
4366 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4367 (float_truncate:MODEF
4368 (match_operand:XF 1 "register_operand")))
4369 (clobber (match_dup 2))])]
4372 if (flag_unsafe_math_optimizations)
4374 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4375 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4376 if (reg != operands[0])
4377 emit_move_insn (operands[0], reg);
4381 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4384 (define_insn "*truncxfsf2_mixed"
4385 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4387 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4388 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4391 gcc_assert (!which_alternative);
4392 return output_387_reg_move (insn, operands);
4394 [(set_attr "type" "fmov,multi,multi,multi")
4395 (set_attr "unit" "*,i387,i387,i387")
4396 (set_attr "mode" "SF")])
4398 (define_insn "*truncxfdf2_mixed"
4399 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4401 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4402 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4405 gcc_assert (!which_alternative);
4406 return output_387_reg_move (insn, operands);
4408 [(set_attr "isa" "*,*,sse2,*")
4409 (set_attr "type" "fmov,multi,multi,multi")
4410 (set_attr "unit" "*,i387,i387,i387")
4411 (set_attr "mode" "DF")])
4413 (define_insn "truncxf<mode>2_i387_noop"
4414 [(set (match_operand:MODEF 0 "register_operand" "=f")
4415 (float_truncate:MODEF
4416 (match_operand:XF 1 "register_operand" "f")))]
4417 "TARGET_80387 && flag_unsafe_math_optimizations"
4418 "* return output_387_reg_move (insn, operands);"
4419 [(set_attr "type" "fmov")
4420 (set_attr "mode" "<MODE>")])
4422 (define_insn "*truncxf<mode>2_i387"
4423 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4424 (float_truncate:MODEF
4425 (match_operand:XF 1 "register_operand" "f")))]
4427 "* return output_387_reg_move (insn, operands);"
4428 [(set_attr "type" "fmov")
4429 (set_attr "mode" "<MODE>")])
4432 [(set (match_operand:MODEF 0 "register_operand")
4433 (float_truncate:MODEF
4434 (match_operand:XF 1 "register_operand")))
4435 (clobber (match_operand:MODEF 2 "memory_operand"))]
4436 "TARGET_80387 && reload_completed"
4437 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4438 (set (match_dup 0) (match_dup 2))])
4441 [(set (match_operand:MODEF 0 "memory_operand")
4442 (float_truncate:MODEF
4443 (match_operand:XF 1 "register_operand")))
4444 (clobber (match_operand:MODEF 2 "memory_operand"))]
4446 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4448 ;; Signed conversion to DImode.
4450 (define_expand "fix_truncxfdi2"
4451 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4452 (fix:DI (match_operand:XF 1 "register_operand")))
4453 (clobber (reg:CC FLAGS_REG))])]
4458 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4463 (define_expand "fix_trunc<mode>di2"
4464 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4465 (fix:DI (match_operand:MODEF 1 "register_operand")))
4466 (clobber (reg:CC FLAGS_REG))])]
4467 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4470 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4472 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4475 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4477 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4478 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4479 if (out != operands[0])
4480 emit_move_insn (operands[0], out);
4485 ;; Signed conversion to SImode.
4487 (define_expand "fix_truncxfsi2"
4488 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4489 (fix:SI (match_operand:XF 1 "register_operand")))
4490 (clobber (reg:CC FLAGS_REG))])]
4495 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4500 (define_expand "fix_trunc<mode>si2"
4501 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4502 (fix:SI (match_operand:MODEF 1 "register_operand")))
4503 (clobber (reg:CC FLAGS_REG))])]
4504 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4507 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4509 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4512 if (SSE_FLOAT_MODE_P (<MODE>mode))
4514 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4515 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4516 if (out != operands[0])
4517 emit_move_insn (operands[0], out);
4522 ;; Signed conversion to HImode.
4524 (define_expand "fix_trunc<mode>hi2"
4525 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4526 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4527 (clobber (reg:CC FLAGS_REG))])]
4529 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4533 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4538 ;; Unsigned conversion to SImode.
4540 (define_expand "fixuns_trunc<mode>si2"
4542 [(set (match_operand:SI 0 "register_operand")
4544 (match_operand:MODEF 1 "nonimmediate_operand")))
4546 (clobber (match_scratch:<ssevecmode> 3))
4547 (clobber (match_scratch:<ssevecmode> 4))])]
4548 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4550 machine_mode mode = <MODE>mode;
4551 machine_mode vecmode = <ssevecmode>mode;
4552 REAL_VALUE_TYPE TWO31r;
4555 if (optimize_insn_for_size_p ())
4558 real_ldexp (&TWO31r, &dconst1, 31);
4559 two31 = const_double_from_real_value (TWO31r, mode);
4560 two31 = ix86_build_const_vector (vecmode, true, two31);
4561 operands[2] = force_reg (vecmode, two31);
4564 (define_insn_and_split "*fixuns_trunc<mode>_1"
4565 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4567 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4568 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4569 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4570 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4571 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4572 && optimize_function_for_speed_p (cfun)"
4574 "&& reload_completed"
4577 ix86_split_convert_uns_si_sse (operands);
4581 ;; Unsigned conversion to HImode.
4582 ;; Without these patterns, we'll try the unsigned SI conversion which
4583 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4585 (define_expand "fixuns_trunc<mode>hi2"
4587 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4588 (set (match_operand:HI 0 "nonimmediate_operand")
4589 (subreg:HI (match_dup 2) 0))]
4590 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4591 "operands[2] = gen_reg_rtx (SImode);")
4593 ;; When SSE is available, it is always faster to use it!
4594 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4595 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4596 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
4597 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4598 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4599 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4600 [(set_attr "type" "sseicvt")
4601 (set_attr "prefix" "maybe_vex")
4602 (set (attr "prefix_rex")
4604 (match_test "<SWI48:MODE>mode == DImode")
4606 (const_string "*")))
4607 (set_attr "mode" "<MODEF:MODE>")
4608 (set_attr "athlon_decode" "double,vector")
4609 (set_attr "amdfam10_decode" "double,double")
4610 (set_attr "bdver1_decode" "double,double")])
4612 ;; Avoid vector decoded forms of the instruction.
4614 [(match_scratch:MODEF 2 "x")
4615 (set (match_operand:SWI48 0 "register_operand")
4616 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4617 "TARGET_AVOID_VECTOR_DECODE
4618 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4619 && optimize_insn_for_speed_p ()"
4620 [(set (match_dup 2) (match_dup 1))
4621 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4623 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4624 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4625 (fix:SWI248x (match_operand 1 "register_operand")))]
4626 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4628 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4629 && (TARGET_64BIT || <MODE>mode != DImode))
4631 && can_create_pseudo_p ()"
4636 if (memory_operand (operands[0], VOIDmode))
4637 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4640 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4641 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4647 [(set_attr "type" "fisttp")
4648 (set_attr "mode" "<MODE>")])
4650 (define_insn "fix_trunc<mode>_i387_fisttp"
4651 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4652 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4653 (clobber (match_scratch:XF 2 "=&1f"))]
4654 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4656 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4657 && (TARGET_64BIT || <MODE>mode != DImode))
4658 && TARGET_SSE_MATH)"
4659 "* return output_fix_trunc (insn, operands, true);"
4660 [(set_attr "type" "fisttp")
4661 (set_attr "mode" "<MODE>")])
4663 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4664 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4665 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4666 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4667 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4668 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4670 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4671 && (TARGET_64BIT || <MODE>mode != DImode))
4672 && TARGET_SSE_MATH)"
4674 [(set_attr "type" "fisttp")
4675 (set_attr "mode" "<MODE>")])
4678 [(set (match_operand:SWI248x 0 "register_operand")
4679 (fix:SWI248x (match_operand 1 "register_operand")))
4680 (clobber (match_operand:SWI248x 2 "memory_operand"))
4681 (clobber (match_scratch 3))]
4683 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4684 (clobber (match_dup 3))])
4685 (set (match_dup 0) (match_dup 2))])
4688 [(set (match_operand:SWI248x 0 "memory_operand")
4689 (fix:SWI248x (match_operand 1 "register_operand")))
4690 (clobber (match_operand:SWI248x 2 "memory_operand"))
4691 (clobber (match_scratch 3))]
4693 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4694 (clobber (match_dup 3))])])
4696 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4697 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4698 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4699 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4700 ;; function in i386.c.
4701 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4702 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4703 (fix:SWI248x (match_operand 1 "register_operand")))
4704 (clobber (reg:CC FLAGS_REG))]
4705 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4707 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4708 && (TARGET_64BIT || <MODE>mode != DImode))
4709 && can_create_pseudo_p ()"
4714 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4716 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4717 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4718 if (memory_operand (operands[0], VOIDmode))
4719 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4720 operands[2], operands[3]));
4723 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4724 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4725 operands[2], operands[3],
4730 [(set_attr "type" "fistp")
4731 (set_attr "i387_cw" "trunc")
4732 (set_attr "mode" "<MODE>")])
4734 (define_insn "fix_truncdi_i387"
4735 [(set (match_operand:DI 0 "memory_operand" "=m")
4736 (fix:DI (match_operand 1 "register_operand" "f")))
4737 (use (match_operand:HI 2 "memory_operand" "m"))
4738 (use (match_operand:HI 3 "memory_operand" "m"))
4739 (clobber (match_scratch:XF 4 "=&1f"))]
4740 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4742 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4743 "* return output_fix_trunc (insn, operands, false);"
4744 [(set_attr "type" "fistp")
4745 (set_attr "i387_cw" "trunc")
4746 (set_attr "mode" "DI")])
4748 (define_insn "fix_truncdi_i387_with_temp"
4749 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4750 (fix:DI (match_operand 1 "register_operand" "f,f")))
4751 (use (match_operand:HI 2 "memory_operand" "m,m"))
4752 (use (match_operand:HI 3 "memory_operand" "m,m"))
4753 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4754 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4755 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4757 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4759 [(set_attr "type" "fistp")
4760 (set_attr "i387_cw" "trunc")
4761 (set_attr "mode" "DI")])
4764 [(set (match_operand:DI 0 "register_operand")
4765 (fix:DI (match_operand 1 "register_operand")))
4766 (use (match_operand:HI 2 "memory_operand"))
4767 (use (match_operand:HI 3 "memory_operand"))
4768 (clobber (match_operand:DI 4 "memory_operand"))
4769 (clobber (match_scratch 5))]
4771 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4774 (clobber (match_dup 5))])
4775 (set (match_dup 0) (match_dup 4))])
4778 [(set (match_operand:DI 0 "memory_operand")
4779 (fix:DI (match_operand 1 "register_operand")))
4780 (use (match_operand:HI 2 "memory_operand"))
4781 (use (match_operand:HI 3 "memory_operand"))
4782 (clobber (match_operand:DI 4 "memory_operand"))
4783 (clobber (match_scratch 5))]
4785 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4788 (clobber (match_dup 5))])])
4790 (define_insn "fix_trunc<mode>_i387"
4791 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4792 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4793 (use (match_operand:HI 2 "memory_operand" "m"))
4794 (use (match_operand:HI 3 "memory_operand" "m"))]
4795 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4797 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4798 "* return output_fix_trunc (insn, operands, false);"
4799 [(set_attr "type" "fistp")
4800 (set_attr "i387_cw" "trunc")
4801 (set_attr "mode" "<MODE>")])
4803 (define_insn "fix_trunc<mode>_i387_with_temp"
4804 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4805 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4806 (use (match_operand:HI 2 "memory_operand" "m,m"))
4807 (use (match_operand:HI 3 "memory_operand" "m,m"))
4808 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4809 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4811 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4813 [(set_attr "type" "fistp")
4814 (set_attr "i387_cw" "trunc")
4815 (set_attr "mode" "<MODE>")])
4818 [(set (match_operand:SWI24 0 "register_operand")
4819 (fix:SWI24 (match_operand 1 "register_operand")))
4820 (use (match_operand:HI 2 "memory_operand"))
4821 (use (match_operand:HI 3 "memory_operand"))
4822 (clobber (match_operand:SWI24 4 "memory_operand"))]
4824 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4826 (use (match_dup 3))])
4827 (set (match_dup 0) (match_dup 4))])
4830 [(set (match_operand:SWI24 0 "memory_operand")
4831 (fix:SWI24 (match_operand 1 "register_operand")))
4832 (use (match_operand:HI 2 "memory_operand"))
4833 (use (match_operand:HI 3 "memory_operand"))
4834 (clobber (match_operand:SWI24 4 "memory_operand"))]
4836 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4838 (use (match_dup 3))])])
4840 (define_insn "x86_fnstcw_1"
4841 [(set (match_operand:HI 0 "memory_operand" "=m")
4842 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4845 [(set (attr "length")
4846 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4847 (set_attr "mode" "HI")
4848 (set_attr "unit" "i387")
4849 (set_attr "bdver1_decode" "vector")])
4851 (define_insn "x86_fldcw_1"
4852 [(set (reg:HI FPCR_REG)
4853 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4856 [(set (attr "length")
4857 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4858 (set_attr "mode" "HI")
4859 (set_attr "unit" "i387")
4860 (set_attr "athlon_decode" "vector")
4861 (set_attr "amdfam10_decode" "vector")
4862 (set_attr "bdver1_decode" "vector")])
4864 ;; Conversion between fixed point and floating point.
4866 ;; Even though we only accept memory inputs, the backend _really_
4867 ;; wants to be able to do this between registers. Thankfully, LRA
4868 ;; will fix this up for us during register allocation.
4870 (define_insn "floathi<mode>2"
4871 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4872 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4874 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4875 || TARGET_MIX_SSE_I387)"
4877 [(set_attr "type" "fmov")
4878 (set_attr "mode" "<MODE>")
4879 (set_attr "fp_int_src" "true")])
4881 (define_insn "float<SWI48x:mode>xf2"
4882 [(set (match_operand:XF 0 "register_operand" "=f")
4883 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4886 [(set_attr "type" "fmov")
4887 (set_attr "mode" "XF")
4888 (set_attr "fp_int_src" "true")])
4890 (define_expand "float<SWI48:mode><MODEF:mode>2"
4891 [(set (match_operand:MODEF 0 "register_operand")
4892 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4893 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
4895 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
4896 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
4898 rtx reg = gen_reg_rtx (XFmode);
4899 rtx (*insn)(rtx, rtx);
4901 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
4903 if (<MODEF:MODE>mode == SFmode)
4904 insn = gen_truncxfsf2;
4905 else if (<MODEF:MODE>mode == DFmode)
4906 insn = gen_truncxfdf2;
4910 emit_insn (insn (operands[0], reg));
4915 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed"
4916 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
4918 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4919 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4922 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4923 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4924 [(set_attr "type" "fmov,sseicvt,sseicvt")
4925 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4926 (set_attr "mode" "<MODEF:MODE>")
4927 (set (attr "prefix_rex")
4929 (and (eq_attr "prefix" "maybe_vex")
4930 (match_test "<SWI48:MODE>mode == DImode"))
4932 (const_string "*")))
4933 (set_attr "unit" "i387,*,*")
4934 (set_attr "athlon_decode" "*,double,direct")
4935 (set_attr "amdfam10_decode" "*,vector,double")
4936 (set_attr "bdver1_decode" "*,double,direct")
4937 (set_attr "fp_int_src" "true")
4938 (set (attr "enabled")
4939 (cond [(eq_attr "alternative" "0")
4940 (symbol_ref "TARGET_MIX_SSE_I387
4941 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
4944 (symbol_ref "true")))
4945 (set (attr "preferred_for_speed")
4946 (cond [(eq_attr "alternative" "1")
4947 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
4948 (symbol_ref "true")))])
4950 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
4951 [(set (match_operand:MODEF 0 "register_operand" "=f")
4952 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4953 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
4955 [(set_attr "type" "fmov")
4956 (set_attr "mode" "<MODEF:MODE>")
4957 (set_attr "fp_int_src" "true")])
4959 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
4960 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
4961 ;; alternative in sse2_loadld.
4963 [(set (match_operand:MODEF 0 "register_operand")
4964 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
4965 "TARGET_SSE2 && TARGET_SSE_MATH
4966 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4967 && reload_completed && SSE_REG_P (operands[0])
4968 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
4969 && (!EXT_REX_SSE_REG_P (operands[0])
4970 || TARGET_AVX512VL)"
4973 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4975 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4977 emit_insn (gen_sse2_loadld (operands[4],
4978 CONST0_RTX (V4SImode), operands[1]));
4980 if (<ssevecmode>mode == V4SFmode)
4981 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4983 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4987 ;; Avoid partial SSE register dependency stalls
4989 [(set (match_operand:MODEF 0 "register_operand")
4990 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4991 "TARGET_SSE2 && TARGET_SSE_MATH
4992 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4993 && optimize_function_for_speed_p (cfun)
4994 && reload_completed && SSE_REG_P (operands[0])
4995 && (!EXT_REX_SSE_REG_P (operands[0])
4996 || TARGET_AVX512VL)"
4999 const machine_mode vmode = <MODEF:ssevecmode>mode;
5000 const machine_mode mode = <MODEF:MODE>mode;
5001 rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
5003 emit_move_insn (op0, CONST0_RTX (vmode));
5005 t = gen_rtx_FLOAT (mode, operands[1]);
5006 t = gen_rtx_VEC_DUPLICATE (vmode, t);
5007 t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
5008 emit_insn (gen_rtx_SET (op0, t));
5012 ;; Break partial reg stall for cvtsd2ss.
5015 [(set (match_operand:SF 0 "register_operand")
5017 (match_operand:DF 1 "nonimmediate_operand")))]
5018 "TARGET_SSE2 && TARGET_SSE_MATH
5019 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5020 && optimize_function_for_speed_p (cfun)
5021 && SSE_REG_P (operands[0])
5022 && (!SSE_REG_P (operands[1])
5023 || REGNO (operands[0]) != REGNO (operands[1]))
5024 && (!EXT_REX_SSE_REG_P (operands[0])
5025 || TARGET_AVX512VL)"
5029 (float_truncate:V2SF
5034 operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
5036 operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
5038 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5041 ;; Break partial reg stall for cvtss2sd.
5044 [(set (match_operand:DF 0 "register_operand")
5046 (match_operand:SF 1 "nonimmediate_operand")))]
5047 "TARGET_SSE2 && TARGET_SSE_MATH
5048 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5049 && optimize_function_for_speed_p (cfun)
5050 && SSE_REG_P (operands[0])
5051 && (!SSE_REG_P (operands[1])
5052 || REGNO (operands[0]) != REGNO (operands[1]))
5053 && (!EXT_REX_SSE_REG_P (operands[0])
5054 || TARGET_AVX512VL)"
5060 (parallel [(const_int 0) (const_int 1)])))
5064 operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
5066 operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
5068 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5071 ;; Avoid store forwarding (partial memory) stall penalty
5072 ;; by passing DImode value through XMM registers. */
5074 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5075 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5077 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5078 (clobber (match_scratch:V4SI 3 "=X,x"))
5079 (clobber (match_scratch:V4SI 4 "=X,x"))
5080 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5081 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5082 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5083 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5085 [(set_attr "type" "multi")
5086 (set_attr "mode" "<X87MODEF:MODE>")
5087 (set_attr "unit" "i387")
5088 (set_attr "fp_int_src" "true")])
5091 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5092 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5093 (clobber (match_scratch:V4SI 3))
5094 (clobber (match_scratch:V4SI 4))
5095 (clobber (match_operand:DI 2 "memory_operand"))]
5096 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5097 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5098 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5099 && reload_completed"
5100 [(set (match_dup 2) (match_dup 3))
5101 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5103 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5104 Assemble the 64-bit DImode value in an xmm register. */
5105 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5106 gen_lowpart (SImode, operands[1])));
5107 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5108 gen_highpart (SImode, operands[1])));
5109 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5112 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5116 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5117 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5118 (clobber (match_scratch:V4SI 3))
5119 (clobber (match_scratch:V4SI 4))
5120 (clobber (match_operand:DI 2 "memory_operand"))]
5121 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5122 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5123 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5124 && reload_completed"
5125 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5127 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5128 [(set (match_operand:MODEF 0 "register_operand")
5129 (unsigned_float:MODEF
5130 (match_operand:SWI12 1 "nonimmediate_operand")))]
5132 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5134 operands[1] = convert_to_mode (SImode, operands[1], 1);
5135 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5139 ;; Avoid store forwarding (partial memory) stall penalty by extending
5140 ;; SImode value to DImode through XMM register instead of pushing two
5141 ;; SImode values to stack. Also note that fild loads from memory only.
5143 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5144 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5145 (unsigned_float:X87MODEF
5146 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5147 (clobber (match_scratch:DI 3 "=x"))
5148 (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5150 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5151 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5153 "&& reload_completed"
5154 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5155 (set (match_dup 2) (match_dup 3))
5157 (float:X87MODEF (match_dup 2)))]
5159 [(set_attr "type" "multi")
5160 (set_attr "mode" "<MODE>")])
5162 (define_expand "floatunssi<mode>2"
5164 [(set (match_operand:X87MODEF 0 "register_operand")
5165 (unsigned_float:X87MODEF
5166 (match_operand:SI 1 "nonimmediate_operand")))
5167 (clobber (match_scratch:DI 3))
5168 (clobber (match_dup 2))])]
5170 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5171 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5172 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5174 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5176 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5180 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5183 (define_expand "floatunsdisf2"
5184 [(use (match_operand:SF 0 "register_operand"))
5185 (use (match_operand:DI 1 "nonimmediate_operand"))]
5186 "TARGET_64BIT && TARGET_SSE_MATH"
5187 "x86_emit_floatuns (operands); DONE;")
5189 (define_expand "floatunsdidf2"
5190 [(use (match_operand:DF 0 "register_operand"))
5191 (use (match_operand:DI 1 "nonimmediate_operand"))]
5192 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5193 && TARGET_SSE2 && TARGET_SSE_MATH"
5196 x86_emit_floatuns (operands);
5198 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5202 ;; Load effective address instructions
5204 (define_insn_and_split "*lea<mode>"
5205 [(set (match_operand:SWI48 0 "register_operand" "=r")
5206 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5209 if (SImode_address_operand (operands[1], VOIDmode))
5211 gcc_assert (TARGET_64BIT);
5212 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5215 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5217 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5220 machine_mode mode = <MODE>mode;
5223 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5224 change operands[] array behind our back. */
5225 pat = PATTERN (curr_insn);
5227 operands[0] = SET_DEST (pat);
5228 operands[1] = SET_SRC (pat);
5230 /* Emit all operations in SImode for zero-extended addresses. */
5231 if (SImode_address_operand (operands[1], VOIDmode))
5234 ix86_split_lea_for_addr (curr_insn, operands, mode);
5236 /* Zero-extend return register to DImode for zero-extended addresses. */
5237 if (mode != <MODE>mode)
5238 emit_insn (gen_zero_extendsidi2
5239 (operands[0], gen_lowpart (mode, operands[0])));
5243 [(set_attr "type" "lea")
5246 (match_operand 1 "SImode_address_operand")
5248 (const_string "<MODE>")))])
5252 (define_expand "add<mode>3"
5253 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5254 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5255 (match_operand:SDWIM 2 "<general_operand>")))]
5257 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5259 (define_insn_and_split "*add<dwi>3_doubleword"
5260 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5262 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5263 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5264 (clobber (reg:CC FLAGS_REG))]
5265 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5268 [(parallel [(set (reg:CC FLAGS_REG)
5269 (unspec:CC [(match_dup 1) (match_dup 2)]
5272 (plus:DWIH (match_dup 1) (match_dup 2)))])
5273 (parallel [(set (match_dup 3)
5277 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5279 (clobber (reg:CC FLAGS_REG))])]
5280 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5282 (define_insn "*add<mode>3_cc"
5283 [(set (reg:CC FLAGS_REG)
5285 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5286 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5288 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5289 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5290 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5291 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5292 [(set_attr "type" "alu")
5293 (set_attr "mode" "<MODE>")])
5295 (define_insn "addqi3_cc"
5296 [(set (reg:CC FLAGS_REG)
5298 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5299 (match_operand:QI 2 "general_operand" "qn,qm")]
5301 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5302 (plus:QI (match_dup 1) (match_dup 2)))]
5303 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5304 "add{b}\t{%2, %0|%0, %2}"
5305 [(set_attr "type" "alu")
5306 (set_attr "mode" "QI")])
5308 (define_insn "*add<mode>_1"
5309 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5311 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5312 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5313 (clobber (reg:CC FLAGS_REG))]
5314 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5316 switch (get_attr_type (insn))
5322 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5323 if (operands[2] == const1_rtx)
5324 return "inc{<imodesuffix>}\t%0";
5327 gcc_assert (operands[2] == constm1_rtx);
5328 return "dec{<imodesuffix>}\t%0";
5332 /* For most processors, ADD is faster than LEA. This alternative
5333 was added to use ADD as much as possible. */
5334 if (which_alternative == 2)
5335 std::swap (operands[1], operands[2]);
5337 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5338 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5339 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5341 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5345 (cond [(eq_attr "alternative" "3")
5346 (const_string "lea")
5347 (match_operand:SWI48 2 "incdec_operand")
5348 (const_string "incdec")
5350 (const_string "alu")))
5351 (set (attr "length_immediate")
5353 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5355 (const_string "*")))
5356 (set_attr "mode" "<MODE>")])
5358 ;; It may seem that nonimmediate operand is proper one for operand 1.
5359 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5360 ;; we take care in ix86_binary_operator_ok to not allow two memory
5361 ;; operands so proper swapping will be done in reload. This allow
5362 ;; patterns constructed from addsi_1 to match.
5364 (define_insn "addsi_1_zext"
5365 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5367 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5368 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5369 (clobber (reg:CC FLAGS_REG))]
5370 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5372 switch (get_attr_type (insn))
5378 if (operands[2] == const1_rtx)
5379 return "inc{l}\t%k0";
5382 gcc_assert (operands[2] == constm1_rtx);
5383 return "dec{l}\t%k0";
5387 /* For most processors, ADD is faster than LEA. This alternative
5388 was added to use ADD as much as possible. */
5389 if (which_alternative == 1)
5390 std::swap (operands[1], operands[2]);
5392 if (x86_maybe_negate_const_int (&operands[2], SImode))
5393 return "sub{l}\t{%2, %k0|%k0, %2}";
5395 return "add{l}\t{%2, %k0|%k0, %2}";
5399 (cond [(eq_attr "alternative" "2")
5400 (const_string "lea")
5401 (match_operand:SI 2 "incdec_operand")
5402 (const_string "incdec")
5404 (const_string "alu")))
5405 (set (attr "length_immediate")
5407 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5409 (const_string "*")))
5410 (set_attr "mode" "SI")])
5412 (define_insn "*addhi_1"
5413 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5414 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5415 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5416 (clobber (reg:CC FLAGS_REG))]
5417 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5419 switch (get_attr_type (insn))
5425 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5426 if (operands[2] == const1_rtx)
5427 return "inc{w}\t%0";
5430 gcc_assert (operands[2] == constm1_rtx);
5431 return "dec{w}\t%0";
5435 /* For most processors, ADD is faster than LEA. This alternative
5436 was added to use ADD as much as possible. */
5437 if (which_alternative == 2)
5438 std::swap (operands[1], operands[2]);
5440 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5441 if (x86_maybe_negate_const_int (&operands[2], HImode))
5442 return "sub{w}\t{%2, %0|%0, %2}";
5444 return "add{w}\t{%2, %0|%0, %2}";
5448 (cond [(eq_attr "alternative" "3")
5449 (const_string "lea")
5450 (match_operand:HI 2 "incdec_operand")
5451 (const_string "incdec")
5453 (const_string "alu")))
5454 (set (attr "length_immediate")
5456 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5458 (const_string "*")))
5459 (set_attr "mode" "HI,HI,HI,SI")])
5461 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5462 (define_insn "*addqi_1"
5463 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5464 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5465 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5466 (clobber (reg:CC FLAGS_REG))]
5467 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5469 bool widen = (which_alternative == 3 || which_alternative == 4);
5471 switch (get_attr_type (insn))
5477 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5478 if (operands[2] == const1_rtx)
5479 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5482 gcc_assert (operands[2] == constm1_rtx);
5483 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5487 /* For most processors, ADD is faster than LEA. These alternatives
5488 were added to use ADD as much as possible. */
5489 if (which_alternative == 2 || which_alternative == 4)
5490 std::swap (operands[1], operands[2]);
5492 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5493 if (x86_maybe_negate_const_int (&operands[2], QImode))
5496 return "sub{l}\t{%2, %k0|%k0, %2}";
5498 return "sub{b}\t{%2, %0|%0, %2}";
5501 return "add{l}\t{%k2, %k0|%k0, %k2}";
5503 return "add{b}\t{%2, %0|%0, %2}";
5507 (cond [(eq_attr "alternative" "5")
5508 (const_string "lea")
5509 (match_operand:QI 2 "incdec_operand")
5510 (const_string "incdec")
5512 (const_string "alu")))
5513 (set (attr "length_immediate")
5515 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5517 (const_string "*")))
5518 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5520 (define_insn "*addqi_1_slp"
5521 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5522 (plus:QI (match_dup 0)
5523 (match_operand:QI 1 "general_operand" "qn,qm")))
5524 (clobber (reg:CC FLAGS_REG))]
5525 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5526 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5528 switch (get_attr_type (insn))
5531 if (operands[1] == const1_rtx)
5532 return "inc{b}\t%0";
5535 gcc_assert (operands[1] == constm1_rtx);
5536 return "dec{b}\t%0";
5540 if (x86_maybe_negate_const_int (&operands[1], QImode))
5541 return "sub{b}\t{%1, %0|%0, %1}";
5543 return "add{b}\t{%1, %0|%0, %1}";
5547 (if_then_else (match_operand:QI 1 "incdec_operand")
5548 (const_string "incdec")
5549 (const_string "alu1")))
5550 (set (attr "memory")
5551 (if_then_else (match_operand 1 "memory_operand")
5552 (const_string "load")
5553 (const_string "none")))
5554 (set_attr "mode" "QI")])
5556 ;; Split non destructive adds if we cannot use lea.
5558 [(set (match_operand:SWI48 0 "register_operand")
5559 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5560 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5561 (clobber (reg:CC FLAGS_REG))]
5562 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5563 [(set (match_dup 0) (match_dup 1))
5564 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5565 (clobber (reg:CC FLAGS_REG))])])
5567 ;; Convert add to the lea pattern to avoid flags dependency.
5569 [(set (match_operand:SWI 0 "register_operand")
5570 (plus:SWI (match_operand:SWI 1 "register_operand")
5571 (match_operand:SWI 2 "<nonmemory_operand>")))
5572 (clobber (reg:CC FLAGS_REG))]
5573 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5576 machine_mode mode = <MODE>mode;
5579 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5582 operands[0] = gen_lowpart (mode, operands[0]);
5583 operands[1] = gen_lowpart (mode, operands[1]);
5584 operands[2] = gen_lowpart (mode, operands[2]);
5587 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5589 emit_insn (gen_rtx_SET (operands[0], pat));
5593 ;; Split non destructive adds if we cannot use lea.
5595 [(set (match_operand:DI 0 "register_operand")
5597 (plus:SI (match_operand:SI 1 "register_operand")
5598 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5599 (clobber (reg:CC FLAGS_REG))]
5601 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5602 [(set (match_dup 3) (match_dup 1))
5603 (parallel [(set (match_dup 0)
5604 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5605 (clobber (reg:CC FLAGS_REG))])]
5606 "operands[3] = gen_lowpart (SImode, operands[0]);")
5608 ;; Convert add to the lea pattern to avoid flags dependency.
5610 [(set (match_operand:DI 0 "register_operand")
5612 (plus:SI (match_operand:SI 1 "register_operand")
5613 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5614 (clobber (reg:CC FLAGS_REG))]
5615 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5617 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5619 (define_insn "*add<mode>_2"
5620 [(set (reg FLAGS_REG)
5623 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5624 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5626 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5627 (plus:SWI (match_dup 1) (match_dup 2)))]
5628 "ix86_match_ccmode (insn, CCGOCmode)
5629 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5631 switch (get_attr_type (insn))
5634 if (operands[2] == const1_rtx)
5635 return "inc{<imodesuffix>}\t%0";
5638 gcc_assert (operands[2] == constm1_rtx);
5639 return "dec{<imodesuffix>}\t%0";
5643 if (which_alternative == 2)
5644 std::swap (operands[1], operands[2]);
5646 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5647 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5648 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5650 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5654 (if_then_else (match_operand:SWI 2 "incdec_operand")
5655 (const_string "incdec")
5656 (const_string "alu")))
5657 (set (attr "length_immediate")
5659 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5661 (const_string "*")))
5662 (set_attr "mode" "<MODE>")])
5664 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5665 (define_insn "*addsi_2_zext"
5666 [(set (reg FLAGS_REG)
5668 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5669 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5671 (set (match_operand:DI 0 "register_operand" "=r,r")
5672 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5673 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5674 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5676 switch (get_attr_type (insn))
5679 if (operands[2] == const1_rtx)
5680 return "inc{l}\t%k0";
5683 gcc_assert (operands[2] == constm1_rtx);
5684 return "dec{l}\t%k0";
5688 if (which_alternative == 1)
5689 std::swap (operands[1], operands[2]);
5691 if (x86_maybe_negate_const_int (&operands[2], SImode))
5692 return "sub{l}\t{%2, %k0|%k0, %2}";
5694 return "add{l}\t{%2, %k0|%k0, %2}";
5698 (if_then_else (match_operand:SI 2 "incdec_operand")
5699 (const_string "incdec")
5700 (const_string "alu")))
5701 (set (attr "length_immediate")
5703 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5705 (const_string "*")))
5706 (set_attr "mode" "SI")])
5708 (define_insn "*add<mode>_3"
5709 [(set (reg FLAGS_REG)
5711 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5712 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5713 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5714 "ix86_match_ccmode (insn, CCZmode)
5715 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5717 switch (get_attr_type (insn))
5720 if (operands[2] == const1_rtx)
5721 return "inc{<imodesuffix>}\t%0";
5724 gcc_assert (operands[2] == constm1_rtx);
5725 return "dec{<imodesuffix>}\t%0";
5729 if (which_alternative == 1)
5730 std::swap (operands[1], operands[2]);
5732 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5733 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5734 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5736 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5740 (if_then_else (match_operand:SWI 2 "incdec_operand")
5741 (const_string "incdec")
5742 (const_string "alu")))
5743 (set (attr "length_immediate")
5745 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5747 (const_string "*")))
5748 (set_attr "mode" "<MODE>")])
5750 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5751 (define_insn "*addsi_3_zext"
5752 [(set (reg FLAGS_REG)
5754 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5755 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5756 (set (match_operand:DI 0 "register_operand" "=r,r")
5757 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5758 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5759 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5761 switch (get_attr_type (insn))
5764 if (operands[2] == const1_rtx)
5765 return "inc{l}\t%k0";
5768 gcc_assert (operands[2] == constm1_rtx);
5769 return "dec{l}\t%k0";
5773 if (which_alternative == 1)
5774 std::swap (operands[1], operands[2]);
5776 if (x86_maybe_negate_const_int (&operands[2], SImode))
5777 return "sub{l}\t{%2, %k0|%k0, %2}";
5779 return "add{l}\t{%2, %k0|%k0, %2}";
5783 (if_then_else (match_operand:SI 2 "incdec_operand")
5784 (const_string "incdec")
5785 (const_string "alu")))
5786 (set (attr "length_immediate")
5788 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5790 (const_string "*")))
5791 (set_attr "mode" "SI")])
5793 ; For comparisons against 1, -1 and 128, we may generate better code
5794 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5795 ; is matched then. We can't accept general immediate, because for
5796 ; case of overflows, the result is messed up.
5797 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5798 ; only for comparisons not depending on it.
5800 (define_insn "*adddi_4"
5801 [(set (reg FLAGS_REG)
5803 (match_operand:DI 1 "nonimmediate_operand" "0")
5804 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5805 (clobber (match_scratch:DI 0 "=rm"))]
5807 && ix86_match_ccmode (insn, CCGCmode)"
5809 switch (get_attr_type (insn))
5812 if (operands[2] == constm1_rtx)
5813 return "inc{q}\t%0";
5816 gcc_assert (operands[2] == const1_rtx);
5817 return "dec{q}\t%0";
5821 if (x86_maybe_negate_const_int (&operands[2], DImode))
5822 return "add{q}\t{%2, %0|%0, %2}";
5824 return "sub{q}\t{%2, %0|%0, %2}";
5828 (if_then_else (match_operand:DI 2 "incdec_operand")
5829 (const_string "incdec")
5830 (const_string "alu")))
5831 (set (attr "length_immediate")
5833 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5835 (const_string "*")))
5836 (set_attr "mode" "DI")])
5838 ; For comparisons against 1, -1 and 128, we may generate better code
5839 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5840 ; is matched then. We can't accept general immediate, because for
5841 ; case of overflows, the result is messed up.
5842 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5843 ; only for comparisons not depending on it.
5845 (define_insn "*add<mode>_4"
5846 [(set (reg FLAGS_REG)
5848 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5849 (match_operand:SWI124 2 "const_int_operand" "n")))
5850 (clobber (match_scratch:SWI124 0 "=<r>m"))]
5851 "ix86_match_ccmode (insn, CCGCmode)"
5853 switch (get_attr_type (insn))
5856 if (operands[2] == constm1_rtx)
5857 return "inc{<imodesuffix>}\t%0";
5860 gcc_assert (operands[2] == const1_rtx);
5861 return "dec{<imodesuffix>}\t%0";
5865 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5866 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5868 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5872 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5873 (const_string "incdec")
5874 (const_string "alu")))
5875 (set (attr "length_immediate")
5877 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5879 (const_string "*")))
5880 (set_attr "mode" "<MODE>")])
5882 (define_insn "*add<mode>_5"
5883 [(set (reg FLAGS_REG)
5886 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5887 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5889 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5890 "ix86_match_ccmode (insn, CCGOCmode)
5891 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5893 switch (get_attr_type (insn))
5896 if (operands[2] == const1_rtx)
5897 return "inc{<imodesuffix>}\t%0";
5900 gcc_assert (operands[2] == constm1_rtx);
5901 return "dec{<imodesuffix>}\t%0";
5905 if (which_alternative == 1)
5906 std::swap (operands[1], operands[2]);
5908 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5909 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5910 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5912 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5916 (if_then_else (match_operand:SWI 2 "incdec_operand")
5917 (const_string "incdec")
5918 (const_string "alu")))
5919 (set (attr "length_immediate")
5921 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5923 (const_string "*")))
5924 (set_attr "mode" "<MODE>")])
5926 (define_insn "addqi_ext_1"
5927 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5932 (match_operand 1 "ext_register_operand" "0,0")
5935 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5936 (clobber (reg:CC FLAGS_REG))]
5939 switch (get_attr_type (insn))
5942 if (operands[2] == const1_rtx)
5943 return "inc{b}\t%h0";
5946 gcc_assert (operands[2] == constm1_rtx);
5947 return "dec{b}\t%h0";
5951 return "add{b}\t{%2, %h0|%h0, %2}";
5954 [(set_attr "isa" "*,nox64")
5956 (if_then_else (match_operand:QI 2 "incdec_operand")
5957 (const_string "incdec")
5958 (const_string "alu")))
5959 (set_attr "modrm" "1")
5960 (set_attr "mode" "QI")])
5962 (define_insn "*addqi_ext_2"
5963 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5968 (match_operand 1 "ext_register_operand" "%0")
5972 (match_operand 2 "ext_register_operand" "Q")
5975 (clobber (reg:CC FLAGS_REG))]
5977 "add{b}\t{%h2, %h0|%h0, %h2}"
5978 [(set_attr "type" "alu")
5979 (set_attr "mode" "QI")])
5981 ;; Add with jump on overflow.
5982 (define_expand "addv<mode>4"
5983 [(parallel [(set (reg:CCO FLAGS_REG)
5986 (match_operand:SWI 1 "nonimmediate_operand"))
5989 (plus:SWI (match_dup 1)
5990 (match_operand:SWI 2
5991 "<general_operand>")))))
5992 (set (match_operand:SWI 0 "register_operand")
5993 (plus:SWI (match_dup 1) (match_dup 2)))])
5994 (set (pc) (if_then_else
5995 (eq (reg:CCO FLAGS_REG) (const_int 0))
5996 (label_ref (match_operand 3))
6000 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6001 if (CONST_INT_P (operands[2]))
6002 operands[4] = operands[2];
6004 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6007 (define_insn "*addv<mode>4"
6008 [(set (reg:CCO FLAGS_REG)
6011 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6013 (match_operand:SWI 2 "<general_sext_operand>"
6016 (plus:SWI (match_dup 1) (match_dup 2)))))
6017 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6018 (plus:SWI (match_dup 1) (match_dup 2)))]
6019 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6020 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6021 [(set_attr "type" "alu")
6022 (set_attr "mode" "<MODE>")])
6024 (define_insn "*addv<mode>4_1"
6025 [(set (reg:CCO FLAGS_REG)
6028 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6029 (match_operand:<DWI> 3 "const_int_operand" "i"))
6031 (plus:SWI (match_dup 1)
6032 (match_operand:SWI 2 "x86_64_immediate_operand"
6034 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6035 (plus:SWI (match_dup 1) (match_dup 2)))]
6036 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6037 && CONST_INT_P (operands[2])
6038 && INTVAL (operands[2]) == INTVAL (operands[3])"
6039 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6040 [(set_attr "type" "alu")
6041 (set_attr "mode" "<MODE>")
6042 (set (attr "length_immediate")
6043 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6045 (match_test "<MODE_SIZE> == 8")
6047 (const_string "<MODE_SIZE>")))])
6049 ;; The lea patterns for modes less than 32 bits need to be matched by
6050 ;; several insns converted to real lea by splitters.
6052 (define_insn_and_split "*lea_general_1"
6053 [(set (match_operand 0 "register_operand" "=r")
6054 (plus (plus (match_operand 1 "index_register_operand" "l")
6055 (match_operand 2 "register_operand" "r"))
6056 (match_operand 3 "immediate_operand" "i")))]
6057 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6058 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6059 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6060 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6061 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6062 || GET_MODE (operands[3]) == VOIDmode)"
6064 "&& reload_completed"
6067 machine_mode mode = SImode;
6070 operands[0] = gen_lowpart (mode, operands[0]);
6071 operands[1] = gen_lowpart (mode, operands[1]);
6072 operands[2] = gen_lowpart (mode, operands[2]);
6073 operands[3] = gen_lowpart (mode, operands[3]);
6075 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6078 emit_insn (gen_rtx_SET (operands[0], pat));
6081 [(set_attr "type" "lea")
6082 (set_attr "mode" "SI")])
6084 (define_insn_and_split "*lea_general_2"
6085 [(set (match_operand 0 "register_operand" "=r")
6086 (plus (mult (match_operand 1 "index_register_operand" "l")
6087 (match_operand 2 "const248_operand" "n"))
6088 (match_operand 3 "nonmemory_operand" "ri")))]
6089 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6090 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6091 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6092 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6093 || GET_MODE (operands[3]) == VOIDmode)"
6095 "&& reload_completed"
6098 machine_mode mode = SImode;
6101 operands[0] = gen_lowpart (mode, operands[0]);
6102 operands[1] = gen_lowpart (mode, operands[1]);
6103 operands[3] = gen_lowpart (mode, operands[3]);
6105 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6108 emit_insn (gen_rtx_SET (operands[0], pat));
6111 [(set_attr "type" "lea")
6112 (set_attr "mode" "SI")])
6114 (define_insn_and_split "*lea_general_3"
6115 [(set (match_operand 0 "register_operand" "=r")
6116 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6117 (match_operand 2 "const248_operand" "n"))
6118 (match_operand 3 "register_operand" "r"))
6119 (match_operand 4 "immediate_operand" "i")))]
6120 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6121 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6122 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6123 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6125 "&& reload_completed"
6128 machine_mode mode = SImode;
6131 operands[0] = gen_lowpart (mode, operands[0]);
6132 operands[1] = gen_lowpart (mode, operands[1]);
6133 operands[3] = gen_lowpart (mode, operands[3]);
6134 operands[4] = gen_lowpart (mode, operands[4]);
6136 pat = gen_rtx_PLUS (mode,
6138 gen_rtx_MULT (mode, operands[1],
6143 emit_insn (gen_rtx_SET (operands[0], pat));
6146 [(set_attr "type" "lea")
6147 (set_attr "mode" "SI")])
6149 (define_insn_and_split "*lea_general_4"
6150 [(set (match_operand 0 "register_operand" "=r")
6152 (match_operand 1 "index_register_operand" "l")
6153 (match_operand 2 "const_int_operand" "n"))
6154 (match_operand 3 "const_int_operand" "n")))]
6155 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6156 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6157 || GET_MODE (operands[0]) == SImode
6158 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6159 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6160 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6161 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6162 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6164 "&& reload_completed"
6167 machine_mode mode = GET_MODE (operands[0]);
6170 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6173 operands[0] = gen_lowpart (mode, operands[0]);
6174 operands[1] = gen_lowpart (mode, operands[1]);
6177 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6179 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6180 INTVAL (operands[3]));
6182 emit_insn (gen_rtx_SET (operands[0], pat));
6185 [(set_attr "type" "lea")
6187 (if_then_else (match_operand:DI 0)
6189 (const_string "SI")))])
6191 ;; Subtract instructions
6193 (define_expand "sub<mode>3"
6194 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6195 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6196 (match_operand:SDWIM 2 "<general_operand>")))]
6198 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6200 (define_insn_and_split "*sub<dwi>3_doubleword"
6201 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6203 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6204 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6205 (clobber (reg:CC FLAGS_REG))]
6206 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6209 [(parallel [(set (reg:CC FLAGS_REG)
6210 (compare:CC (match_dup 1) (match_dup 2)))
6212 (minus:DWIH (match_dup 1) (match_dup 2)))])
6213 (parallel [(set (match_dup 3)
6217 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6219 (clobber (reg:CC FLAGS_REG))])]
6220 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6222 (define_insn "*sub<mode>_1"
6223 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6225 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6226 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6227 (clobber (reg:CC FLAGS_REG))]
6228 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6229 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6230 [(set_attr "type" "alu")
6231 (set_attr "mode" "<MODE>")])
6233 (define_insn "*subsi_1_zext"
6234 [(set (match_operand:DI 0 "register_operand" "=r")
6236 (minus:SI (match_operand:SI 1 "register_operand" "0")
6237 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6238 (clobber (reg:CC FLAGS_REG))]
6239 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6240 "sub{l}\t{%2, %k0|%k0, %2}"
6241 [(set_attr "type" "alu")
6242 (set_attr "mode" "SI")])
6244 (define_insn "*subqi_1_slp"
6245 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6246 (minus:QI (match_dup 0)
6247 (match_operand:QI 1 "general_operand" "qn,qm")))
6248 (clobber (reg:CC FLAGS_REG))]
6249 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6250 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6251 "sub{b}\t{%1, %0|%0, %1}"
6252 [(set_attr "type" "alu1")
6253 (set_attr "mode" "QI")])
6255 (define_insn "*sub<mode>_2"
6256 [(set (reg FLAGS_REG)
6259 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6260 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6262 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6263 (minus:SWI (match_dup 1) (match_dup 2)))]
6264 "ix86_match_ccmode (insn, CCGOCmode)
6265 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6266 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6267 [(set_attr "type" "alu")
6268 (set_attr "mode" "<MODE>")])
6270 (define_insn "*subsi_2_zext"
6271 [(set (reg FLAGS_REG)
6273 (minus:SI (match_operand:SI 1 "register_operand" "0")
6274 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6276 (set (match_operand:DI 0 "register_operand" "=r")
6278 (minus:SI (match_dup 1)
6280 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6281 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6282 "sub{l}\t{%2, %k0|%k0, %2}"
6283 [(set_attr "type" "alu")
6284 (set_attr "mode" "SI")])
6286 ;; Subtract with jump on overflow.
6287 (define_expand "subv<mode>4"
6288 [(parallel [(set (reg:CCO FLAGS_REG)
6289 (eq:CCO (minus:<DWI>
6291 (match_operand:SWI 1 "nonimmediate_operand"))
6294 (minus:SWI (match_dup 1)
6295 (match_operand:SWI 2
6296 "<general_operand>")))))
6297 (set (match_operand:SWI 0 "register_operand")
6298 (minus:SWI (match_dup 1) (match_dup 2)))])
6299 (set (pc) (if_then_else
6300 (eq (reg:CCO FLAGS_REG) (const_int 0))
6301 (label_ref (match_operand 3))
6305 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6306 if (CONST_INT_P (operands[2]))
6307 operands[4] = operands[2];
6309 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6312 (define_insn "*subv<mode>4"
6313 [(set (reg:CCO FLAGS_REG)
6314 (eq:CCO (minus:<DWI>
6316 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6318 (match_operand:SWI 2 "<general_sext_operand>"
6321 (minus:SWI (match_dup 1) (match_dup 2)))))
6322 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6323 (minus:SWI (match_dup 1) (match_dup 2)))]
6324 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6325 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6326 [(set_attr "type" "alu")
6327 (set_attr "mode" "<MODE>")])
6329 (define_insn "*subv<mode>4_1"
6330 [(set (reg:CCO FLAGS_REG)
6331 (eq:CCO (minus:<DWI>
6333 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6334 (match_operand:<DWI> 3 "const_int_operand" "i"))
6336 (minus:SWI (match_dup 1)
6337 (match_operand:SWI 2 "x86_64_immediate_operand"
6339 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6340 (minus:SWI (match_dup 1) (match_dup 2)))]
6341 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6342 && CONST_INT_P (operands[2])
6343 && INTVAL (operands[2]) == INTVAL (operands[3])"
6344 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6345 [(set_attr "type" "alu")
6346 (set_attr "mode" "<MODE>")
6347 (set (attr "length_immediate")
6348 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6350 (match_test "<MODE_SIZE> == 8")
6352 (const_string "<MODE_SIZE>")))])
6354 (define_insn "*sub<mode>_3"
6355 [(set (reg FLAGS_REG)
6356 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6357 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6358 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6359 (minus:SWI (match_dup 1) (match_dup 2)))]
6360 "ix86_match_ccmode (insn, CCmode)
6361 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6362 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6363 [(set_attr "type" "alu")
6364 (set_attr "mode" "<MODE>")])
6366 (define_insn "*subsi_3_zext"
6367 [(set (reg FLAGS_REG)
6368 (compare (match_operand:SI 1 "register_operand" "0")
6369 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6370 (set (match_operand:DI 0 "register_operand" "=r")
6372 (minus:SI (match_dup 1)
6374 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6375 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6376 "sub{l}\t{%2, %1|%1, %2}"
6377 [(set_attr "type" "alu")
6378 (set_attr "mode" "SI")])
6380 ;; Add with carry and subtract with borrow
6382 (define_expand "<plusminus_insn><mode>3_carry"
6384 [(set (match_operand:SWI 0 "nonimmediate_operand")
6386 (match_operand:SWI 1 "nonimmediate_operand")
6387 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6388 [(match_operand 3 "flags_reg_operand")
6390 (match_operand:SWI 2 "<general_operand>"))))
6391 (clobber (reg:CC FLAGS_REG))])]
6392 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6394 (define_insn "*<plusminus_insn><mode>3_carry"
6395 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6397 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6399 (match_operator 3 "ix86_carry_flag_operator"
6400 [(reg FLAGS_REG) (const_int 0)])
6401 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6402 (clobber (reg:CC FLAGS_REG))]
6403 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6404 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6405 [(set_attr "type" "alu")
6406 (set_attr "use_carry" "1")
6407 (set_attr "pent_pair" "pu")
6408 (set_attr "mode" "<MODE>")])
6410 (define_insn "*addsi3_carry_zext"
6411 [(set (match_operand:DI 0 "register_operand" "=r")
6413 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6414 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6415 [(reg FLAGS_REG) (const_int 0)])
6416 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6417 (clobber (reg:CC FLAGS_REG))]
6418 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6419 "adc{l}\t{%2, %k0|%k0, %2}"
6420 [(set_attr "type" "alu")
6421 (set_attr "use_carry" "1")
6422 (set_attr "pent_pair" "pu")
6423 (set_attr "mode" "SI")])
6425 (define_insn "*subsi3_carry_zext"
6426 [(set (match_operand:DI 0 "register_operand" "=r")
6428 (minus:SI (match_operand:SI 1 "register_operand" "0")
6429 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6430 [(reg FLAGS_REG) (const_int 0)])
6431 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6432 (clobber (reg:CC FLAGS_REG))]
6433 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6434 "sbb{l}\t{%2, %k0|%k0, %2}"
6435 [(set_attr "type" "alu")
6436 (set_attr "pent_pair" "pu")
6437 (set_attr "mode" "SI")])
6441 (define_insn "adcx<mode>3"
6442 [(set (reg:CCC FLAGS_REG)
6445 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6447 (match_operator 4 "ix86_carry_flag_operator"
6448 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6449 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6451 (set (match_operand:SWI48 0 "register_operand" "=r")
6452 (plus:SWI48 (match_dup 1)
6453 (plus:SWI48 (match_op_dup 4
6454 [(match_dup 3) (const_int 0)])
6456 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6457 "adcx\t{%2, %0|%0, %2}"
6458 [(set_attr "type" "alu")
6459 (set_attr "use_carry" "1")
6460 (set_attr "mode" "<MODE>")])
6462 ;; Overflow setting add instructions
6464 (define_insn "*add<mode>3_cconly_overflow"
6465 [(set (reg:CCC FLAGS_REG)
6468 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6469 (match_operand:SWI 2 "<general_operand>" "<g>"))
6471 (clobber (match_scratch:SWI 0 "=<r>"))]
6472 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6473 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6474 [(set_attr "type" "alu")
6475 (set_attr "mode" "<MODE>")])
6477 (define_insn "*add<mode>3_cc_overflow"
6478 [(set (reg:CCC FLAGS_REG)
6481 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6482 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6484 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6485 (plus:SWI (match_dup 1) (match_dup 2)))]
6486 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6487 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6488 [(set_attr "type" "alu")
6489 (set_attr "mode" "<MODE>")])
6491 (define_insn "*addsi3_zext_cc_overflow"
6492 [(set (reg:CCC FLAGS_REG)
6495 (match_operand:SI 1 "nonimmediate_operand" "%0")
6496 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6498 (set (match_operand:DI 0 "register_operand" "=r")
6499 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6500 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6501 "add{l}\t{%2, %k0|%k0, %2}"
6502 [(set_attr "type" "alu")
6503 (set_attr "mode" "SI")])
6505 ;; The patterns that match these are at the end of this file.
6507 (define_expand "<plusminus_insn>xf3"
6508 [(set (match_operand:XF 0 "register_operand")
6510 (match_operand:XF 1 "register_operand")
6511 (match_operand:XF 2 "register_operand")))]
6514 (define_expand "<plusminus_insn><mode>3"
6515 [(set (match_operand:MODEF 0 "register_operand")
6517 (match_operand:MODEF 1 "register_operand")
6518 (match_operand:MODEF 2 "nonimmediate_operand")))]
6519 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6520 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6522 ;; Multiply instructions
6524 (define_expand "mul<mode>3"
6525 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6527 (match_operand:SWIM248 1 "register_operand")
6528 (match_operand:SWIM248 2 "<general_operand>")))
6529 (clobber (reg:CC FLAGS_REG))])])
6531 (define_expand "mulqi3"
6532 [(parallel [(set (match_operand:QI 0 "register_operand")
6534 (match_operand:QI 1 "register_operand")
6535 (match_operand:QI 2 "nonimmediate_operand")))
6536 (clobber (reg:CC FLAGS_REG))])]
6537 "TARGET_QIMODE_MATH")
6540 ;; IMUL reg32/64, reg32/64, imm8 Direct
6541 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6542 ;; IMUL reg32/64, reg32/64, imm32 Direct
6543 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6544 ;; IMUL reg32/64, reg32/64 Direct
6545 ;; IMUL reg32/64, mem32/64 Direct
6547 ;; On BDVER1, all above IMULs use DirectPath
6550 ;; IMUL reg16, reg16, imm8 VectorPath
6551 ;; IMUL reg16, mem16, imm8 VectorPath
6552 ;; IMUL reg16, reg16, imm16 VectorPath
6553 ;; IMUL reg16, mem16, imm16 VectorPath
6554 ;; IMUL reg16, reg16 Direct
6555 ;; IMUL reg16, mem16 Direct
6557 ;; On BDVER1, all HI MULs use DoublePath
6559 (define_insn "*mul<mode>3_1"
6560 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
6562 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
6563 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
6564 (clobber (reg:CC FLAGS_REG))]
6565 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6567 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6568 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6569 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6570 [(set_attr "type" "imul")
6571 (set_attr "prefix_0f" "0,0,1")
6572 (set (attr "athlon_decode")
6573 (cond [(eq_attr "cpu" "athlon")
6574 (const_string "vector")
6575 (eq_attr "alternative" "1")
6576 (const_string "vector")
6577 (and (eq_attr "alternative" "2")
6578 (ior (match_test "<MODE>mode == HImode")
6579 (match_operand 1 "memory_operand")))
6580 (const_string "vector")]
6581 (const_string "direct")))
6582 (set (attr "amdfam10_decode")
6583 (cond [(and (eq_attr "alternative" "0,1")
6584 (ior (match_test "<MODE>mode == HImode")
6585 (match_operand 1 "memory_operand")))
6586 (const_string "vector")]
6587 (const_string "direct")))
6588 (set (attr "bdver1_decode")
6590 (match_test "<MODE>mode == HImode")
6591 (const_string "double")
6592 (const_string "direct")))
6593 (set_attr "mode" "<MODE>")])
6595 (define_insn "*mulsi3_1_zext"
6596 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6598 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6599 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6600 (clobber (reg:CC FLAGS_REG))]
6602 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6604 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6605 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6606 imul{l}\t{%2, %k0|%k0, %2}"
6607 [(set_attr "type" "imul")
6608 (set_attr "prefix_0f" "0,0,1")
6609 (set (attr "athlon_decode")
6610 (cond [(eq_attr "cpu" "athlon")
6611 (const_string "vector")
6612 (eq_attr "alternative" "1")
6613 (const_string "vector")
6614 (and (eq_attr "alternative" "2")
6615 (match_operand 1 "memory_operand"))
6616 (const_string "vector")]
6617 (const_string "direct")))
6618 (set (attr "amdfam10_decode")
6619 (cond [(and (eq_attr "alternative" "0,1")
6620 (match_operand 1 "memory_operand"))
6621 (const_string "vector")]
6622 (const_string "direct")))
6623 (set_attr "bdver1_decode" "direct")
6624 (set_attr "mode" "SI")])
6626 ;;On AMDFAM10 and BDVER1
6630 (define_insn "*mulqi3_1"
6631 [(set (match_operand:QI 0 "register_operand" "=a")
6632 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6633 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6634 (clobber (reg:CC FLAGS_REG))]
6636 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6638 [(set_attr "type" "imul")
6639 (set_attr "length_immediate" "0")
6640 (set (attr "athlon_decode")
6641 (if_then_else (eq_attr "cpu" "athlon")
6642 (const_string "vector")
6643 (const_string "direct")))
6644 (set_attr "amdfam10_decode" "direct")
6645 (set_attr "bdver1_decode" "direct")
6646 (set_attr "mode" "QI")])
6648 ;; Multiply with jump on overflow.
6649 (define_expand "mulv<mode>4"
6650 [(parallel [(set (reg:CCO FLAGS_REG)
6653 (match_operand:SWI248 1 "register_operand"))
6656 (mult:SWI248 (match_dup 1)
6657 (match_operand:SWI248 2
6658 "<general_operand>")))))
6659 (set (match_operand:SWI248 0 "register_operand")
6660 (mult:SWI248 (match_dup 1) (match_dup 2)))])
6661 (set (pc) (if_then_else
6662 (eq (reg:CCO FLAGS_REG) (const_int 0))
6663 (label_ref (match_operand 3))
6667 if (CONST_INT_P (operands[2]))
6668 operands[4] = operands[2];
6670 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6673 (define_insn "*mulv<mode>4"
6674 [(set (reg:CCO FLAGS_REG)
6677 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6679 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
6681 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6682 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6683 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6684 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6686 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6687 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6688 [(set_attr "type" "imul")
6689 (set_attr "prefix_0f" "0,1")
6690 (set (attr "athlon_decode")
6691 (cond [(eq_attr "cpu" "athlon")
6692 (const_string "vector")
6693 (eq_attr "alternative" "0")
6694 (const_string "vector")
6695 (and (eq_attr "alternative" "1")
6696 (match_operand 1 "memory_operand"))
6697 (const_string "vector")]
6698 (const_string "direct")))
6699 (set (attr "amdfam10_decode")
6700 (cond [(and (eq_attr "alternative" "1")
6701 (match_operand 1 "memory_operand"))
6702 (const_string "vector")]
6703 (const_string "direct")))
6704 (set_attr "bdver1_decode" "direct")
6705 (set_attr "mode" "<MODE>")])
6707 (define_insn "*mulvhi4"
6708 [(set (reg:CCO FLAGS_REG)
6711 (match_operand:HI 1 "nonimmediate_operand" "%0"))
6713 (match_operand:HI 2 "nonimmediate_operand" "mr")))
6715 (mult:HI (match_dup 1) (match_dup 2)))))
6716 (set (match_operand:HI 0 "register_operand" "=r")
6717 (mult:HI (match_dup 1) (match_dup 2)))]
6718 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6719 "imul{w}\t{%2, %0|%0, %2}"
6720 [(set_attr "type" "imul")
6721 (set_attr "prefix_0f" "1")
6722 (set_attr "athlon_decode" "vector")
6723 (set_attr "amdfam10_decode" "direct")
6724 (set_attr "bdver1_decode" "double")
6725 (set_attr "mode" "HI")])
6727 (define_insn "*mulv<mode>4_1"
6728 [(set (reg:CCO FLAGS_REG)
6731 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
6732 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
6734 (mult:SWI248 (match_dup 1)
6735 (match_operand:SWI248 2
6736 "<immediate_operand>" "K,<i>")))))
6737 (set (match_operand:SWI248 0 "register_operand" "=r,r")
6738 (mult:SWI248 (match_dup 1) (match_dup 2)))]
6739 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
6740 && CONST_INT_P (operands[2])
6741 && INTVAL (operands[2]) == INTVAL (operands[3])"
6742 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6743 [(set_attr "type" "imul")
6744 (set (attr "prefix_0f")
6746 (match_test "<MODE>mode == HImode")
6748 (const_string "*")))
6749 (set (attr "athlon_decode")
6750 (cond [(eq_attr "cpu" "athlon")
6751 (const_string "vector")
6752 (eq_attr "alternative" "1")
6753 (const_string "vector")]
6754 (const_string "direct")))
6755 (set (attr "amdfam10_decode")
6756 (cond [(ior (match_test "<MODE>mode == HImode")
6757 (match_operand 1 "memory_operand"))
6758 (const_string "vector")]
6759 (const_string "direct")))
6760 (set (attr "bdver1_decode")
6762 (match_test "<MODE>mode == HImode")
6763 (const_string "double")
6764 (const_string "direct")))
6765 (set_attr "mode" "<MODE>")
6766 (set (attr "length_immediate")
6767 (cond [(eq_attr "alternative" "0")
6769 (match_test "<MODE_SIZE> == 8")
6771 (const_string "<MODE_SIZE>")))])
6773 (define_expand "umulv<mode>4"
6774 [(parallel [(set (reg:CCO FLAGS_REG)
6777 (match_operand:SWI248 1
6778 "nonimmediate_operand"))
6780 (match_operand:SWI248 2
6781 "nonimmediate_operand")))
6783 (mult:SWI248 (match_dup 1) (match_dup 2)))))
6784 (set (match_operand:SWI248 0 "register_operand")
6785 (mult:SWI248 (match_dup 1) (match_dup 2)))
6786 (clobber (match_scratch:SWI248 4))])
6787 (set (pc) (if_then_else
6788 (eq (reg:CCO FLAGS_REG) (const_int 0))
6789 (label_ref (match_operand 3))
6793 if (MEM_P (operands[1]) && MEM_P (operands[2]))
6794 operands[1] = force_reg (<MODE>mode, operands[1]);
6797 (define_insn "*umulv<mode>4"
6798 [(set (reg:CCO FLAGS_REG)
6801 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
6803 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
6805 (mult:SWI248 (match_dup 1) (match_dup 2)))))
6806 (set (match_operand:SWI248 0 "register_operand" "=a")
6807 (mult:SWI248 (match_dup 1) (match_dup 2)))
6808 (clobber (match_scratch:SWI248 3 "=d"))]
6809 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6810 "mul{<imodesuffix>}\t%2"
6811 [(set_attr "type" "imul")
6812 (set_attr "length_immediate" "0")
6813 (set (attr "athlon_decode")
6814 (if_then_else (eq_attr "cpu" "athlon")
6815 (const_string "vector")
6816 (const_string "double")))
6817 (set_attr "amdfam10_decode" "double")
6818 (set_attr "bdver1_decode" "direct")
6819 (set_attr "mode" "<MODE>")])
6821 (define_expand "<u>mulvqi4"
6822 [(parallel [(set (reg:CCO FLAGS_REG)
6825 (match_operand:QI 1 "nonimmediate_operand"))
6827 (match_operand:QI 2 "nonimmediate_operand")))
6829 (mult:QI (match_dup 1) (match_dup 2)))))
6830 (set (match_operand:QI 0 "register_operand")
6831 (mult:QI (match_dup 1) (match_dup 2)))])
6832 (set (pc) (if_then_else
6833 (eq (reg:CCO FLAGS_REG) (const_int 0))
6834 (label_ref (match_operand 3))
6836 "TARGET_QIMODE_MATH"
6838 if (MEM_P (operands[1]) && MEM_P (operands[2]))
6839 operands[1] = force_reg (QImode, operands[1]);
6842 (define_insn "*<u>mulvqi4"
6843 [(set (reg:CCO FLAGS_REG)
6846 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6848 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6850 (mult:QI (match_dup 1) (match_dup 2)))))
6851 (set (match_operand:QI 0 "register_operand" "=a")
6852 (mult:QI (match_dup 1) (match_dup 2)))]
6854 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6855 "<sgnprefix>mul{b}\t%2"
6856 [(set_attr "type" "imul")
6857 (set_attr "length_immediate" "0")
6858 (set (attr "athlon_decode")
6859 (if_then_else (eq_attr "cpu" "athlon")
6860 (const_string "vector")
6861 (const_string "direct")))
6862 (set_attr "amdfam10_decode" "direct")
6863 (set_attr "bdver1_decode" "direct")
6864 (set_attr "mode" "QI")])
6866 (define_expand "<u>mul<mode><dwi>3"
6867 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6870 (match_operand:DWIH 1 "nonimmediate_operand"))
6872 (match_operand:DWIH 2 "register_operand"))))
6873 (clobber (reg:CC FLAGS_REG))])])
6875 (define_expand "<u>mulqihi3"
6876 [(parallel [(set (match_operand:HI 0 "register_operand")
6879 (match_operand:QI 1 "nonimmediate_operand"))
6881 (match_operand:QI 2 "register_operand"))))
6882 (clobber (reg:CC FLAGS_REG))])]
6883 "TARGET_QIMODE_MATH")
6885 (define_insn "*bmi2_umul<mode><dwi>3_1"
6886 [(set (match_operand:DWIH 0 "register_operand" "=r")
6888 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
6889 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
6890 (set (match_operand:DWIH 1 "register_operand" "=r")
6893 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
6894 (zero_extend:<DWI> (match_dup 3)))
6895 (match_operand:QI 4 "const_int_operand" "n"))))]
6896 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
6897 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6898 "mulx\t{%3, %0, %1|%1, %0, %3}"
6899 [(set_attr "type" "imulx")
6900 (set_attr "prefix" "vex")
6901 (set_attr "mode" "<MODE>")])
6903 (define_insn "*umul<mode><dwi>3_1"
6904 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6907 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6909 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6910 (clobber (reg:CC FLAGS_REG))]
6911 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6914 mul{<imodesuffix>}\t%2"
6915 [(set_attr "isa" "bmi2,*")
6916 (set_attr "type" "imulx,imul")
6917 (set_attr "length_immediate" "*,0")
6918 (set (attr "athlon_decode")
6919 (cond [(eq_attr "alternative" "1")
6920 (if_then_else (eq_attr "cpu" "athlon")
6921 (const_string "vector")
6922 (const_string "double"))]
6923 (const_string "*")))
6924 (set_attr "amdfam10_decode" "*,double")
6925 (set_attr "bdver1_decode" "*,direct")
6926 (set_attr "prefix" "vex,orig")
6927 (set_attr "mode" "<MODE>")])
6929 ;; Convert mul to the mulx pattern to avoid flags dependency.
6931 [(set (match_operand:<DWI> 0 "register_operand")
6934 (match_operand:DWIH 1 "register_operand"))
6936 (match_operand:DWIH 2 "nonimmediate_operand"))))
6937 (clobber (reg:CC FLAGS_REG))]
6938 "TARGET_BMI2 && reload_completed
6939 && true_regnum (operands[1]) == DX_REG"
6940 [(parallel [(set (match_dup 3)
6941 (mult:DWIH (match_dup 1) (match_dup 2)))
6945 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6946 (zero_extend:<DWI> (match_dup 2)))
6949 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6951 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
6954 (define_insn "*mul<mode><dwi>3_1"
6955 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6958 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6960 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6961 (clobber (reg:CC FLAGS_REG))]
6962 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6963 "imul{<imodesuffix>}\t%2"
6964 [(set_attr "type" "imul")
6965 (set_attr "length_immediate" "0")
6966 (set (attr "athlon_decode")
6967 (if_then_else (eq_attr "cpu" "athlon")
6968 (const_string "vector")
6969 (const_string "double")))
6970 (set_attr "amdfam10_decode" "double")
6971 (set_attr "bdver1_decode" "direct")
6972 (set_attr "mode" "<MODE>")])
6974 (define_insn "*<u>mulqihi3_1"
6975 [(set (match_operand:HI 0 "register_operand" "=a")
6978 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6980 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6981 (clobber (reg:CC FLAGS_REG))]
6983 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6984 "<sgnprefix>mul{b}\t%2"
6985 [(set_attr "type" "imul")
6986 (set_attr "length_immediate" "0")
6987 (set (attr "athlon_decode")
6988 (if_then_else (eq_attr "cpu" "athlon")
6989 (const_string "vector")
6990 (const_string "direct")))
6991 (set_attr "amdfam10_decode" "direct")
6992 (set_attr "bdver1_decode" "direct")
6993 (set_attr "mode" "QI")])
6995 (define_expand "<s>mul<mode>3_highpart"
6996 [(parallel [(set (match_operand:SWI48 0 "register_operand")
7001 (match_operand:SWI48 1 "nonimmediate_operand"))
7003 (match_operand:SWI48 2 "register_operand")))
7005 (clobber (match_scratch:SWI48 3))
7006 (clobber (reg:CC FLAGS_REG))])]
7008 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7010 (define_insn "*<s>muldi3_highpart_1"
7011 [(set (match_operand:DI 0 "register_operand" "=d")
7016 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7018 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7020 (clobber (match_scratch:DI 3 "=1"))
7021 (clobber (reg:CC FLAGS_REG))]
7023 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7024 "<sgnprefix>mul{q}\t%2"
7025 [(set_attr "type" "imul")
7026 (set_attr "length_immediate" "0")
7027 (set (attr "athlon_decode")
7028 (if_then_else (eq_attr "cpu" "athlon")
7029 (const_string "vector")
7030 (const_string "double")))
7031 (set_attr "amdfam10_decode" "double")
7032 (set_attr "bdver1_decode" "direct")
7033 (set_attr "mode" "DI")])
7035 (define_insn "*<s>mulsi3_highpart_1"
7036 [(set (match_operand:SI 0 "register_operand" "=d")
7041 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7043 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7045 (clobber (match_scratch:SI 3 "=1"))
7046 (clobber (reg:CC FLAGS_REG))]
7047 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7048 "<sgnprefix>mul{l}\t%2"
7049 [(set_attr "type" "imul")
7050 (set_attr "length_immediate" "0")
7051 (set (attr "athlon_decode")
7052 (if_then_else (eq_attr "cpu" "athlon")
7053 (const_string "vector")
7054 (const_string "double")))
7055 (set_attr "amdfam10_decode" "double")
7056 (set_attr "bdver1_decode" "direct")
7057 (set_attr "mode" "SI")])
7059 (define_insn "*<s>mulsi3_highpart_zext"
7060 [(set (match_operand:DI 0 "register_operand" "=d")
7061 (zero_extend:DI (truncate:SI
7063 (mult:DI (any_extend:DI
7064 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7066 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7068 (clobber (match_scratch:SI 3 "=1"))
7069 (clobber (reg:CC FLAGS_REG))]
7071 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7072 "<sgnprefix>mul{l}\t%2"
7073 [(set_attr "type" "imul")
7074 (set_attr "length_immediate" "0")
7075 (set (attr "athlon_decode")
7076 (if_then_else (eq_attr "cpu" "athlon")
7077 (const_string "vector")
7078 (const_string "double")))
7079 (set_attr "amdfam10_decode" "double")
7080 (set_attr "bdver1_decode" "direct")
7081 (set_attr "mode" "SI")])
7083 ;; The patterns that match these are at the end of this file.
7085 (define_expand "mulxf3"
7086 [(set (match_operand:XF 0 "register_operand")
7087 (mult:XF (match_operand:XF 1 "register_operand")
7088 (match_operand:XF 2 "register_operand")))]
7091 (define_expand "mul<mode>3"
7092 [(set (match_operand:MODEF 0 "register_operand")
7093 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7094 (match_operand:MODEF 2 "nonimmediate_operand")))]
7095 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7096 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7098 ;; Divide instructions
7100 ;; The patterns that match these are at the end of this file.
7102 (define_expand "divxf3"
7103 [(set (match_operand:XF 0 "register_operand")
7104 (div:XF (match_operand:XF 1 "register_operand")
7105 (match_operand:XF 2 "register_operand")))]
7108 (define_expand "divdf3"
7109 [(set (match_operand:DF 0 "register_operand")
7110 (div:DF (match_operand:DF 1 "register_operand")
7111 (match_operand:DF 2 "nonimmediate_operand")))]
7112 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7113 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7115 (define_expand "divsf3"
7116 [(set (match_operand:SF 0 "register_operand")
7117 (div:SF (match_operand:SF 1 "register_operand")
7118 (match_operand:SF 2 "nonimmediate_operand")))]
7119 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7124 && optimize_insn_for_speed_p ()
7125 && flag_finite_math_only && !flag_trapping_math
7126 && flag_unsafe_math_optimizations)
7128 ix86_emit_swdivsf (operands[0], operands[1],
7129 operands[2], SFmode);
7134 ;; Divmod instructions.
7136 (define_expand "divmod<mode>4"
7137 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7139 (match_operand:SWIM248 1 "register_operand")
7140 (match_operand:SWIM248 2 "nonimmediate_operand")))
7141 (set (match_operand:SWIM248 3 "register_operand")
7142 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7143 (clobber (reg:CC FLAGS_REG))])])
7145 ;; Split with 8bit unsigned divide:
7146 ;; if (dividend an divisor are in [0-255])
7147 ;; use 8bit unsigned integer divide
7149 ;; use original integer divide
7151 [(set (match_operand:SWI48 0 "register_operand")
7152 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7153 (match_operand:SWI48 3 "nonimmediate_operand")))
7154 (set (match_operand:SWI48 1 "register_operand")
7155 (mod:SWI48 (match_dup 2) (match_dup 3)))
7156 (clobber (reg:CC FLAGS_REG))]
7157 "TARGET_USE_8BIT_IDIV
7158 && TARGET_QIMODE_MATH
7159 && can_create_pseudo_p ()
7160 && !optimize_insn_for_size_p ()"
7162 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7164 (define_insn_and_split "divmod<mode>4_1"
7165 [(set (match_operand:SWI48 0 "register_operand" "=a")
7166 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7167 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7168 (set (match_operand:SWI48 1 "register_operand" "=&d")
7169 (mod:SWI48 (match_dup 2) (match_dup 3)))
7170 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7171 (clobber (reg:CC FLAGS_REG))]
7175 [(parallel [(set (match_dup 1)
7176 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7177 (clobber (reg:CC FLAGS_REG))])
7178 (parallel [(set (match_dup 0)
7179 (div:SWI48 (match_dup 2) (match_dup 3)))
7181 (mod:SWI48 (match_dup 2) (match_dup 3)))
7183 (clobber (reg:CC FLAGS_REG))])]
7185 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7187 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7188 operands[4] = operands[2];
7191 /* Avoid use of cltd in favor of a mov+shift. */
7192 emit_move_insn (operands[1], operands[2]);
7193 operands[4] = operands[1];
7196 [(set_attr "type" "multi")
7197 (set_attr "mode" "<MODE>")])
7199 (define_insn_and_split "*divmod<mode>4"
7200 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7201 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7202 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7203 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7204 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7205 (clobber (reg:CC FLAGS_REG))]
7209 [(parallel [(set (match_dup 1)
7210 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7211 (clobber (reg:CC FLAGS_REG))])
7212 (parallel [(set (match_dup 0)
7213 (div:SWIM248 (match_dup 2) (match_dup 3)))
7215 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7217 (clobber (reg:CC FLAGS_REG))])]
7219 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7221 if (<MODE>mode != HImode
7222 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7223 operands[4] = operands[2];
7226 /* Avoid use of cltd in favor of a mov+shift. */
7227 emit_move_insn (operands[1], operands[2]);
7228 operands[4] = operands[1];
7231 [(set_attr "type" "multi")
7232 (set_attr "mode" "<MODE>")])
7234 (define_insn "*divmod<mode>4_noext"
7235 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7236 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7237 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7238 (set (match_operand:SWIM248 1 "register_operand" "=d")
7239 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7240 (use (match_operand:SWIM248 4 "register_operand" "1"))
7241 (clobber (reg:CC FLAGS_REG))]
7243 "idiv{<imodesuffix>}\t%3"
7244 [(set_attr "type" "idiv")
7245 (set_attr "mode" "<MODE>")])
7247 (define_expand "divmodqi4"
7248 [(parallel [(set (match_operand:QI 0 "register_operand")
7250 (match_operand:QI 1 "register_operand")
7251 (match_operand:QI 2 "nonimmediate_operand")))
7252 (set (match_operand:QI 3 "register_operand")
7253 (mod:QI (match_dup 1) (match_dup 2)))
7254 (clobber (reg:CC FLAGS_REG))])]
7255 "TARGET_QIMODE_MATH"
7260 tmp0 = gen_reg_rtx (HImode);
7261 tmp1 = gen_reg_rtx (HImode);
7263 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7265 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7266 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7268 /* Extract remainder from AH. */
7269 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7270 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7272 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7273 set_unique_reg_note (insn, REG_EQUAL, mod);
7275 /* Extract quotient from AL. */
7276 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7278 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7279 set_unique_reg_note (insn, REG_EQUAL, div);
7284 ;; Divide AX by r/m8, with result stored in
7287 ;; Change div/mod to HImode and extend the second argument to HImode
7288 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7289 ;; combine may fail.
7290 (define_insn "divmodhiqi3"
7291 [(set (match_operand:HI 0 "register_operand" "=a")
7296 (mod:HI (match_operand:HI 1 "register_operand" "0")
7298 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7302 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7303 (clobber (reg:CC FLAGS_REG))]
7304 "TARGET_QIMODE_MATH"
7306 [(set_attr "type" "idiv")
7307 (set_attr "mode" "QI")])
7309 (define_expand "udivmod<mode>4"
7310 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7312 (match_operand:SWIM248 1 "register_operand")
7313 (match_operand:SWIM248 2 "nonimmediate_operand")))
7314 (set (match_operand:SWIM248 3 "register_operand")
7315 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7316 (clobber (reg:CC FLAGS_REG))])])
7318 ;; Split with 8bit unsigned divide:
7319 ;; if (dividend an divisor are in [0-255])
7320 ;; use 8bit unsigned integer divide
7322 ;; use original integer divide
7324 [(set (match_operand:SWI48 0 "register_operand")
7325 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7326 (match_operand:SWI48 3 "nonimmediate_operand")))
7327 (set (match_operand:SWI48 1 "register_operand")
7328 (umod:SWI48 (match_dup 2) (match_dup 3)))
7329 (clobber (reg:CC FLAGS_REG))]
7330 "TARGET_USE_8BIT_IDIV
7331 && TARGET_QIMODE_MATH
7332 && can_create_pseudo_p ()
7333 && !optimize_insn_for_size_p ()"
7335 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7337 (define_insn_and_split "udivmod<mode>4_1"
7338 [(set (match_operand:SWI48 0 "register_operand" "=a")
7339 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7340 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7341 (set (match_operand:SWI48 1 "register_operand" "=&d")
7342 (umod:SWI48 (match_dup 2) (match_dup 3)))
7343 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7344 (clobber (reg:CC FLAGS_REG))]
7348 [(set (match_dup 1) (const_int 0))
7349 (parallel [(set (match_dup 0)
7350 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7352 (umod:SWI48 (match_dup 2) (match_dup 3)))
7354 (clobber (reg:CC FLAGS_REG))])]
7356 [(set_attr "type" "multi")
7357 (set_attr "mode" "<MODE>")])
7359 (define_insn_and_split "*udivmod<mode>4"
7360 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7361 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7362 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7363 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7364 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7365 (clobber (reg:CC FLAGS_REG))]
7369 [(set (match_dup 1) (const_int 0))
7370 (parallel [(set (match_dup 0)
7371 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7373 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7375 (clobber (reg:CC FLAGS_REG))])]
7377 [(set_attr "type" "multi")
7378 (set_attr "mode" "<MODE>")])
7380 ;; Optimize division or modulo by constant power of 2, if the constant
7381 ;; materializes only after expansion.
7382 (define_insn_and_split "*udivmod<mode>4_pow2"
7383 [(set (match_operand:SWI48 0 "register_operand" "=r")
7384 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7385 (match_operand:SWI48 3 "const_int_operand" "n")))
7386 (set (match_operand:SWI48 1 "register_operand" "=r")
7387 (umod:SWI48 (match_dup 2) (match_dup 3)))
7388 (clobber (reg:CC FLAGS_REG))]
7389 "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
7390 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
7393 [(set (match_dup 1) (match_dup 2))
7394 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7395 (clobber (reg:CC FLAGS_REG))])
7396 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7397 (clobber (reg:CC FLAGS_REG))])]
7399 int v = exact_log2 (UINTVAL (operands[3]));
7400 operands[4] = GEN_INT (v);
7401 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7403 [(set_attr "type" "multi")
7404 (set_attr "mode" "<MODE>")])
7406 (define_insn "*udivmod<mode>4_noext"
7407 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7408 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7409 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7410 (set (match_operand:SWIM248 1 "register_operand" "=d")
7411 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7412 (use (match_operand:SWIM248 4 "register_operand" "1"))
7413 (clobber (reg:CC FLAGS_REG))]
7415 "div{<imodesuffix>}\t%3"
7416 [(set_attr "type" "idiv")
7417 (set_attr "mode" "<MODE>")])
7419 (define_expand "udivmodqi4"
7420 [(parallel [(set (match_operand:QI 0 "register_operand")
7422 (match_operand:QI 1 "register_operand")
7423 (match_operand:QI 2 "nonimmediate_operand")))
7424 (set (match_operand:QI 3 "register_operand")
7425 (umod:QI (match_dup 1) (match_dup 2)))
7426 (clobber (reg:CC FLAGS_REG))])]
7427 "TARGET_QIMODE_MATH"
7432 tmp0 = gen_reg_rtx (HImode);
7433 tmp1 = gen_reg_rtx (HImode);
7435 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7437 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7438 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7440 /* Extract remainder from AH. */
7441 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7442 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7443 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7445 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7446 set_unique_reg_note (insn, REG_EQUAL, mod);
7448 /* Extract quotient from AL. */
7449 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7451 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7452 set_unique_reg_note (insn, REG_EQUAL, div);
7457 (define_insn "udivmodhiqi3"
7458 [(set (match_operand:HI 0 "register_operand" "=a")
7463 (mod:HI (match_operand:HI 1 "register_operand" "0")
7465 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7469 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7470 (clobber (reg:CC FLAGS_REG))]
7471 "TARGET_QIMODE_MATH"
7473 [(set_attr "type" "idiv")
7474 (set_attr "mode" "QI")])
7476 ;; We cannot use div/idiv for double division, because it causes
7477 ;; "division by zero" on the overflow and that's not what we expect
7478 ;; from truncate. Because true (non truncating) double division is
7479 ;; never generated, we can't create this insn anyway.
7482 ; [(set (match_operand:SI 0 "register_operand" "=a")
7484 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7486 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7487 ; (set (match_operand:SI 3 "register_operand" "=d")
7489 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7490 ; (clobber (reg:CC FLAGS_REG))]
7492 ; "div{l}\t{%2, %0|%0, %2}"
7493 ; [(set_attr "type" "idiv")])
7495 ;;- Logical AND instructions
7497 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7498 ;; Note that this excludes ah.
7500 (define_expand "testsi_ccno_1"
7501 [(set (reg:CCNO FLAGS_REG)
7503 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7504 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7507 (define_expand "testqi_ccz_1"
7508 [(set (reg:CCZ FLAGS_REG)
7509 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7510 (match_operand:QI 1 "nonmemory_operand"))
7513 (define_expand "testdi_ccno_1"
7514 [(set (reg:CCNO FLAGS_REG)
7516 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7517 (match_operand:DI 1 "x86_64_szext_general_operand"))
7519 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7521 (define_insn "*testdi_1"
7522 [(set (reg FLAGS_REG)
7525 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7526 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7528 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7529 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7531 test{l}\t{%k1, %k0|%k0, %k1}
7532 test{l}\t{%k1, %k0|%k0, %k1}
7533 test{q}\t{%1, %0|%0, %1}
7534 test{q}\t{%1, %0|%0, %1}
7535 test{q}\t{%1, %0|%0, %1}"
7536 [(set_attr "type" "test")
7537 (set_attr "modrm" "0,1,0,1,1")
7538 (set_attr "mode" "SI,SI,DI,DI,DI")])
7540 (define_insn "*testqi_1_maybe_si"
7541 [(set (reg FLAGS_REG)
7544 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7545 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7547 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7548 && ix86_match_ccmode (insn,
7549 CONST_INT_P (operands[1])
7550 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7552 if (which_alternative == 3)
7554 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7555 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7556 return "test{l}\t{%1, %k0|%k0, %1}";
7558 return "test{b}\t{%1, %0|%0, %1}";
7560 [(set_attr "type" "test")
7561 (set_attr "modrm" "0,1,1,1")
7562 (set_attr "mode" "QI,QI,QI,SI")
7563 (set_attr "pent_pair" "uv,np,uv,np")])
7565 (define_insn "*test<mode>_1"
7566 [(set (reg FLAGS_REG)
7569 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7570 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7572 "ix86_match_ccmode (insn, CCNOmode)
7573 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7574 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7575 [(set_attr "type" "test")
7576 (set_attr "modrm" "0,1,1")
7577 (set_attr "mode" "<MODE>")
7578 (set_attr "pent_pair" "uv,np,uv")])
7580 (define_expand "testqi_ext_ccno_0"
7581 [(set (reg:CCNO FLAGS_REG)
7585 (match_operand 0 "ext_register_operand")
7588 (match_operand 1 "const_int_operand"))
7591 (define_insn "*testqi_ext_0"
7592 [(set (reg FLAGS_REG)
7596 (match_operand 0 "ext_register_operand" "Q")
7599 (match_operand 1 "const_int_operand" "n"))
7601 "ix86_match_ccmode (insn, CCNOmode)"
7602 "test{b}\t{%1, %h0|%h0, %1}"
7603 [(set_attr "type" "test")
7604 (set_attr "mode" "QI")
7605 (set_attr "length_immediate" "1")
7606 (set_attr "modrm" "1")
7607 (set_attr "pent_pair" "np")])
7609 (define_insn "*testqi_ext_1"
7610 [(set (reg FLAGS_REG)
7614 (match_operand 0 "ext_register_operand" "Q,Q")
7618 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7620 "ix86_match_ccmode (insn, CCNOmode)"
7621 "test{b}\t{%1, %h0|%h0, %1}"
7622 [(set_attr "isa" "*,nox64")
7623 (set_attr "type" "test")
7624 (set_attr "mode" "QI")])
7626 (define_insn "*testqi_ext_2"
7627 [(set (reg FLAGS_REG)
7631 (match_operand 0 "ext_register_operand" "Q")
7635 (match_operand 1 "ext_register_operand" "Q")
7639 "ix86_match_ccmode (insn, CCNOmode)"
7640 "test{b}\t{%h1, %h0|%h0, %h1}"
7641 [(set_attr "type" "test")
7642 (set_attr "mode" "QI")])
7644 ;; Combine likes to form bit extractions for some tests. Humor it.
7645 (define_insn "*testqi_ext_3"
7646 [(set (reg FLAGS_REG)
7647 (compare (zero_extract:SWI48
7648 (match_operand 0 "nonimmediate_operand" "rm")
7649 (match_operand 1 "const_int_operand" "n")
7650 (match_operand 2 "const_int_operand" "n"))
7652 "ix86_match_ccmode (insn, CCNOmode)
7653 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7654 || GET_MODE (operands[0]) == SImode
7655 || GET_MODE (operands[0]) == HImode
7656 || GET_MODE (operands[0]) == QImode)
7657 /* Ensure that resulting mask is zero or sign extended operand. */
7658 && INTVAL (operands[2]) >= 0
7659 && ((INTVAL (operands[1]) > 0
7660 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7661 || (<MODE>mode == DImode
7662 && INTVAL (operands[1]) > 32
7663 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7667 [(set (match_operand 0 "flags_reg_operand")
7668 (match_operator 1 "compare_operator"
7670 (match_operand 2 "nonimmediate_operand")
7671 (match_operand 3 "const_int_operand")
7672 (match_operand 4 "const_int_operand"))
7674 "ix86_match_ccmode (insn, CCNOmode)"
7675 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7677 rtx val = operands[2];
7678 HOST_WIDE_INT len = INTVAL (operands[3]);
7679 HOST_WIDE_INT pos = INTVAL (operands[4]);
7681 machine_mode mode, submode;
7683 mode = GET_MODE (val);
7686 /* ??? Combine likes to put non-volatile mem extractions in QImode
7687 no matter the size of the test. So find a mode that works. */
7688 if (! MEM_VOLATILE_P (val))
7690 mode = smallest_mode_for_size (pos + len, MODE_INT);
7691 val = adjust_address (val, mode, 0);
7694 else if (GET_CODE (val) == SUBREG
7695 && (submode = GET_MODE (SUBREG_REG (val)),
7696 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7697 && pos + len <= GET_MODE_BITSIZE (submode)
7698 && GET_MODE_CLASS (submode) == MODE_INT)
7700 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7702 val = SUBREG_REG (val);
7704 else if (mode == HImode && pos + len <= 8)
7706 /* Small HImode tests can be converted to QImode. */
7708 val = gen_lowpart (QImode, val);
7711 if (len == HOST_BITS_PER_WIDE_INT)
7714 mask = ((HOST_WIDE_INT)1 << len) - 1;
7717 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7720 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7721 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7722 ;; this is relatively important trick.
7723 ;; Do the conversion only post-reload to avoid limiting of the register class
7726 [(set (match_operand 0 "flags_reg_operand")
7727 (match_operator 1 "compare_operator"
7728 [(and (match_operand 2 "QIreg_operand")
7729 (match_operand 3 "const_int_operand"))
7732 && GET_MODE (operands[2]) != QImode
7733 && ((ix86_match_ccmode (insn, CCZmode)
7734 && !(INTVAL (operands[3]) & ~(255 << 8)))
7735 || (ix86_match_ccmode (insn, CCNOmode)
7736 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7739 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7743 operands[2] = gen_lowpart (SImode, operands[2]);
7744 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7748 [(set (match_operand 0 "flags_reg_operand")
7749 (match_operator 1 "compare_operator"
7750 [(and (match_operand 2 "nonimmediate_operand")
7751 (match_operand 3 "const_int_operand"))
7754 && GET_MODE (operands[2]) != QImode
7755 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7756 && ((ix86_match_ccmode (insn, CCZmode)
7757 && !(INTVAL (operands[3]) & ~255))
7758 || (ix86_match_ccmode (insn, CCNOmode)
7759 && !(INTVAL (operands[3]) & ~127)))"
7761 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7764 operands[2] = gen_lowpart (QImode, operands[2]);
7765 operands[3] = gen_lowpart (QImode, operands[3]);
7769 [(set (match_operand:SWI1248x 0 "mask_reg_operand")
7770 (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
7771 (match_operand:SWI1248x 2 "mask_reg_operand")))
7772 (clobber (reg:CC FLAGS_REG))]
7773 "TARGET_AVX512F && reload_completed"
7775 (any_logic:SWI1248x (match_dup 1)
7778 (define_insn "*k<logic><mode>"
7779 [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
7780 (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
7781 (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
7784 if (!TARGET_AVX512DQ && <MODE>mode == QImode)
7785 return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7787 return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
7789 [(set_attr "mode" "<MODE>")
7790 (set_attr "type" "msklog")
7791 (set_attr "prefix" "vex")])
7793 ;; %%% This used to optimize known byte-wide and operations to memory,
7794 ;; and sometimes to QImode registers. If this is considered useful,
7795 ;; it should be done with splitters.
7797 (define_expand "and<mode>3"
7798 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7799 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7800 (match_operand:SWIM 2 "<general_szext_operand>")))]
7803 machine_mode mode = <MODE>mode;
7804 rtx (*insn) (rtx, rtx);
7806 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7808 HOST_WIDE_INT ival = INTVAL (operands[2]);
7810 if (ival == (HOST_WIDE_INT) 0xffffffff)
7812 else if (ival == 0xffff)
7814 else if (ival == 0xff)
7818 if (mode == <MODE>mode)
7820 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7824 if (<MODE>mode == DImode)
7825 insn = (mode == SImode)
7826 ? gen_zero_extendsidi2
7828 ? gen_zero_extendhidi2
7829 : gen_zero_extendqidi2;
7830 else if (<MODE>mode == SImode)
7831 insn = (mode == HImode)
7832 ? gen_zero_extendhisi2
7833 : gen_zero_extendqisi2;
7834 else if (<MODE>mode == HImode)
7835 insn = gen_zero_extendqihi2;
7839 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7843 (define_insn "*anddi_1"
7844 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
7846 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
7847 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
7848 (clobber (reg:CC FLAGS_REG))]
7849 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7851 switch (get_attr_type (insn))
7857 return "kandq\t{%2, %1, %0|%0, %1, %2}";
7860 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7861 if (get_attr_mode (insn) == MODE_SI)
7862 return "and{l}\t{%k2, %k0|%k0, %k2}";
7864 return "and{q}\t{%2, %0|%0, %2}";
7867 [(set_attr "type" "alu,alu,alu,imovx,msklog")
7868 (set_attr "length_immediate" "*,*,*,0,0")
7869 (set (attr "prefix_rex")
7871 (and (eq_attr "type" "imovx")
7872 (and (match_test "INTVAL (operands[2]) == 0xff")
7873 (match_operand 1 "ext_QIreg_operand")))
7875 (const_string "*")))
7876 (set_attr "mode" "SI,DI,DI,SI,DI")])
7878 (define_insn "*andsi_1"
7879 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7880 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
7881 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
7882 (clobber (reg:CC FLAGS_REG))]
7883 "ix86_binary_operator_ok (AND, SImode, operands)"
7885 switch (get_attr_type (insn))
7891 return "kandd\t{%2, %1, %0|%0, %1, %2}";
7894 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7895 return "and{l}\t{%2, %0|%0, %2}";
7898 [(set_attr "type" "alu,alu,imovx,msklog")
7899 (set (attr "prefix_rex")
7901 (and (eq_attr "type" "imovx")
7902 (and (match_test "INTVAL (operands[2]) == 0xff")
7903 (match_operand 1 "ext_QIreg_operand")))
7905 (const_string "*")))
7906 (set_attr "length_immediate" "*,*,0,0")
7907 (set_attr "mode" "SI")])
7909 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7910 (define_insn "*andsi_1_zext"
7911 [(set (match_operand:DI 0 "register_operand" "=r")
7913 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7914 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7915 (clobber (reg:CC FLAGS_REG))]
7916 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7917 "and{l}\t{%2, %k0|%k0, %2}"
7918 [(set_attr "type" "alu")
7919 (set_attr "mode" "SI")])
7921 (define_insn "*andhi_1"
7922 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7923 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
7924 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
7925 (clobber (reg:CC FLAGS_REG))]
7926 "ix86_binary_operator_ok (AND, HImode, operands)"
7928 switch (get_attr_type (insn))
7934 return "kandw\t{%2, %1, %0|%0, %1, %2}";
7937 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7938 return "and{w}\t{%2, %0|%0, %2}";
7941 [(set_attr "type" "alu,alu,imovx,msklog")
7942 (set_attr "length_immediate" "*,*,0,*")
7943 (set (attr "prefix_rex")
7945 (and (eq_attr "type" "imovx")
7946 (match_operand 1 "ext_QIreg_operand"))
7948 (const_string "*")))
7949 (set_attr "mode" "HI,HI,SI,HI")])
7951 ;; %%% Potential partial reg stall on alternative 2. What to do?
7952 (define_insn "*andqi_1"
7953 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
7954 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
7955 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
7956 (clobber (reg:CC FLAGS_REG))]
7957 "ix86_binary_operator_ok (AND, QImode, operands)"
7959 switch (which_alternative)
7963 return "and{b}\t{%2, %0|%0, %2}";
7965 return "and{l}\t{%k2, %k0|%k0, %k2}";
7967 return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
7968 : "kandw\t{%2, %1, %0|%0, %1, %2}";
7973 [(set_attr "type" "alu,alu,alu,msklog")
7974 (set_attr "mode" "QI,QI,SI,HI")])
7976 (define_insn "*andqi_1_slp"
7977 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7978 (and:QI (match_dup 0)
7979 (match_operand:QI 1 "general_operand" "qn,qmn")))
7980 (clobber (reg:CC FLAGS_REG))]
7981 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7982 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7983 "and{b}\t{%1, %0|%0, %1}"
7984 [(set_attr "type" "alu1")
7985 (set_attr "mode" "QI")])
7987 (define_insn "kandn<mode>"
7988 [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
7991 (match_operand:SWI12 1 "register_operand" "r,0,k"))
7992 (match_operand:SWI12 2 "register_operand" "r,r,k")))
7993 (clobber (reg:CC FLAGS_REG))]
7996 switch (which_alternative)
7999 return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
8003 if (TARGET_AVX512DQ && <MODE>mode == QImode)
8004 return "kandnb\t{%2, %1, %0|%0, %1, %2}";
8006 return "kandnw\t{%2, %1, %0|%0, %1, %2}";
8011 [(set_attr "isa" "bmi,*,avx512f")
8012 (set_attr "type" "bitmanip,*,msklog")
8013 (set_attr "prefix" "*,*,vex")
8014 (set_attr "btver2_decode" "direct,*,*")
8015 (set_attr "mode" "<MODE>")])
8018 [(set (match_operand:SWI12 0 "general_reg_operand")
8022 (match_operand:SWI12 1 "general_reg_operand")))
8023 (clobber (reg:CC FLAGS_REG))]
8024 "TARGET_AVX512F && !TARGET_BMI && reload_completed"
8026 (not:HI (match_dup 0)))
8027 (parallel [(set (match_dup 0)
8028 (and:HI (match_dup 0)
8030 (clobber (reg:CC FLAGS_REG))])])
8032 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8034 [(set (match_operand:DI 0 "register_operand")
8035 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8036 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8037 (clobber (reg:CC FLAGS_REG))]
8039 [(parallel [(set (match_dup 0)
8040 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8041 (clobber (reg:CC FLAGS_REG))])]
8042 "operands[2] = gen_lowpart (SImode, operands[2]);")
8045 [(set (match_operand:SWI248 0 "register_operand")
8046 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8047 (match_operand:SWI248 2 "const_int_operand")))
8048 (clobber (reg:CC FLAGS_REG))]
8050 && true_regnum (operands[0]) != true_regnum (operands[1])"
8053 HOST_WIDE_INT ival = INTVAL (operands[2]);
8055 rtx (*insn) (rtx, rtx);
8057 if (ival == (HOST_WIDE_INT) 0xffffffff)
8059 else if (ival == 0xffff)
8063 gcc_assert (ival == 0xff);
8067 if (<MODE>mode == DImode)
8068 insn = (mode == SImode)
8069 ? gen_zero_extendsidi2
8071 ? gen_zero_extendhidi2
8072 : gen_zero_extendqidi2;
8075 if (<MODE>mode != SImode)
8076 /* Zero extend to SImode to avoid partial register stalls. */
8077 operands[0] = gen_lowpart (SImode, operands[0]);
8079 insn = (mode == HImode)
8080 ? gen_zero_extendhisi2
8081 : gen_zero_extendqisi2;
8083 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8088 [(set (match_operand:SWI48 0 "register_operand")
8089 (and:SWI48 (match_dup 0)
8090 (const_int -65536)))
8091 (clobber (reg:CC FLAGS_REG))]
8092 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8093 || optimize_function_for_size_p (cfun)"
8094 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8095 "operands[1] = gen_lowpart (HImode, operands[0]);")
8098 [(set (match_operand:SWI248 0 "any_QIreg_operand")
8099 (and:SWI248 (match_dup 0)
8101 (clobber (reg:CC FLAGS_REG))]
8102 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8103 && reload_completed"
8104 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8105 "operands[1] = gen_lowpart (QImode, operands[0]);")
8108 [(set (match_operand:SWI248 0 "QIreg_operand")
8109 (and:SWI248 (match_dup 0)
8110 (const_int -65281)))
8111 (clobber (reg:CC FLAGS_REG))]
8112 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8113 && reload_completed"
8114 [(parallel [(set (zero_extract:SI (match_dup 0)
8118 (zero_extract:SI (match_dup 0)
8121 (zero_extract:SI (match_dup 0)
8124 (clobber (reg:CC FLAGS_REG))])]
8125 "operands[0] = gen_lowpart (SImode, operands[0]);")
8127 (define_insn "*anddi_2"
8128 [(set (reg FLAGS_REG)
8131 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8132 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8134 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8135 (and:DI (match_dup 1) (match_dup 2)))]
8137 && ix86_match_ccmode
8139 /* If we are going to emit andl instead of andq, and the operands[2]
8140 constant might have the SImode sign bit set, make sure the sign
8141 flag isn't tested, because the instruction will set the sign flag
8142 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8143 conservatively assume it might have bit 31 set. */
8144 (satisfies_constraint_Z (operands[2])
8145 && (!CONST_INT_P (operands[2])
8146 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8147 ? CCZmode : CCNOmode)
8148 && ix86_binary_operator_ok (AND, DImode, operands)"
8150 and{l}\t{%k2, %k0|%k0, %k2}
8151 and{q}\t{%2, %0|%0, %2}
8152 and{q}\t{%2, %0|%0, %2}"
8153 [(set_attr "type" "alu")
8154 (set_attr "mode" "SI,DI,DI")])
8156 (define_insn "*andqi_2_maybe_si"
8157 [(set (reg FLAGS_REG)
8159 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8160 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8162 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8163 (and:QI (match_dup 1) (match_dup 2)))]
8164 "ix86_binary_operator_ok (AND, QImode, operands)
8165 && ix86_match_ccmode (insn,
8166 CONST_INT_P (operands[2])
8167 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8169 if (which_alternative == 2)
8171 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8172 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8173 return "and{l}\t{%2, %k0|%k0, %2}";
8175 return "and{b}\t{%2, %0|%0, %2}";
8177 [(set_attr "type" "alu")
8178 (set_attr "mode" "QI,QI,SI")])
8180 (define_insn "*and<mode>_2"
8181 [(set (reg FLAGS_REG)
8182 (compare (and:SWI124
8183 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8184 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8186 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8187 (and:SWI124 (match_dup 1) (match_dup 2)))]
8188 "ix86_match_ccmode (insn, CCNOmode)
8189 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8190 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8191 [(set_attr "type" "alu")
8192 (set_attr "mode" "<MODE>")])
8194 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8195 (define_insn "*andsi_2_zext"
8196 [(set (reg FLAGS_REG)
8198 (match_operand:SI 1 "nonimmediate_operand" "%0")
8199 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8201 (set (match_operand:DI 0 "register_operand" "=r")
8202 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8203 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8204 && ix86_binary_operator_ok (AND, SImode, operands)"
8205 "and{l}\t{%2, %k0|%k0, %2}"
8206 [(set_attr "type" "alu")
8207 (set_attr "mode" "SI")])
8209 (define_insn "*andqi_2_slp"
8210 [(set (reg FLAGS_REG)
8212 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8213 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8215 (set (strict_low_part (match_dup 0))
8216 (and:QI (match_dup 0) (match_dup 1)))]
8217 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8218 && ix86_match_ccmode (insn, CCNOmode)
8219 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8220 "and{b}\t{%1, %0|%0, %1}"
8221 [(set_attr "type" "alu1")
8222 (set_attr "mode" "QI")])
8224 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8225 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8226 ;; for a QImode operand, which of course failed.
8227 (define_insn "andqi_ext_0"
8228 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8233 (match_operand 1 "ext_register_operand" "0")
8236 (match_operand 2 "const_int_operand" "n")))
8237 (clobber (reg:CC FLAGS_REG))]
8239 "and{b}\t{%2, %h0|%h0, %2}"
8240 [(set_attr "type" "alu")
8241 (set_attr "length_immediate" "1")
8242 (set_attr "modrm" "1")
8243 (set_attr "mode" "QI")])
8245 ;; Generated by peephole translating test to and. This shows up
8246 ;; often in fp comparisons.
8247 (define_insn "*andqi_ext_0_cc"
8248 [(set (reg FLAGS_REG)
8252 (match_operand 1 "ext_register_operand" "0")
8255 (match_operand 2 "const_int_operand" "n"))
8257 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8266 "ix86_match_ccmode (insn, CCNOmode)"
8267 "and{b}\t{%2, %h0|%h0, %2}"
8268 [(set_attr "type" "alu")
8269 (set_attr "length_immediate" "1")
8270 (set_attr "modrm" "1")
8271 (set_attr "mode" "QI")])
8273 (define_insn "*andqi_ext_1"
8274 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8279 (match_operand 1 "ext_register_operand" "0,0")
8283 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8284 (clobber (reg:CC FLAGS_REG))]
8286 "and{b}\t{%2, %h0|%h0, %2}"
8287 [(set_attr "isa" "*,nox64")
8288 (set_attr "type" "alu")
8289 (set_attr "length_immediate" "0")
8290 (set_attr "mode" "QI")])
8292 (define_insn "*andqi_ext_2"
8293 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8298 (match_operand 1 "ext_register_operand" "%0")
8302 (match_operand 2 "ext_register_operand" "Q")
8305 (clobber (reg:CC FLAGS_REG))]
8307 "and{b}\t{%h2, %h0|%h0, %h2}"
8308 [(set_attr "type" "alu")
8309 (set_attr "length_immediate" "0")
8310 (set_attr "mode" "QI")])
8312 ;; Convert wide AND instructions with immediate operand to shorter QImode
8313 ;; equivalents when possible.
8314 ;; Don't do the splitting with memory operands, since it introduces risk
8315 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8316 ;; for size, but that can (should?) be handled by generic code instead.
8318 [(set (match_operand 0 "QIreg_operand")
8319 (and (match_operand 1 "register_operand")
8320 (match_operand 2 "const_int_operand")))
8321 (clobber (reg:CC FLAGS_REG))]
8323 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8324 && !(~INTVAL (operands[2]) & ~(255 << 8))
8325 && GET_MODE (operands[0]) != QImode"
8326 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8327 (and:SI (zero_extract:SI (match_dup 1)
8328 (const_int 8) (const_int 8))
8330 (clobber (reg:CC FLAGS_REG))])]
8332 operands[0] = gen_lowpart (SImode, operands[0]);
8333 operands[1] = gen_lowpart (SImode, operands[1]);
8334 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8337 ;; Since AND can be encoded with sign extended immediate, this is only
8338 ;; profitable when 7th bit is not set.
8340 [(set (match_operand 0 "any_QIreg_operand")
8341 (and (match_operand 1 "general_operand")
8342 (match_operand 2 "const_int_operand")))
8343 (clobber (reg:CC FLAGS_REG))]
8345 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8346 && !(~INTVAL (operands[2]) & ~255)
8347 && !(INTVAL (operands[2]) & 128)
8348 && GET_MODE (operands[0]) != QImode"
8349 [(parallel [(set (strict_low_part (match_dup 0))
8350 (and:QI (match_dup 1)
8352 (clobber (reg:CC FLAGS_REG))])]
8354 operands[0] = gen_lowpart (QImode, operands[0]);
8355 operands[1] = gen_lowpart (QImode, operands[1]);
8356 operands[2] = gen_lowpart (QImode, operands[2]);
8359 ;; Logical inclusive and exclusive OR instructions
8361 ;; %%% This used to optimize known byte-wide and operations to memory.
8362 ;; If this is considered useful, it should be done with splitters.
8364 (define_expand "<code><mode>3"
8365 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8366 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8367 (match_operand:SWIM 2 "<general_operand>")))]
8369 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8371 (define_insn "*<code><mode>_1"
8372 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8374 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8375 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8376 (clobber (reg:CC FLAGS_REG))]
8377 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8379 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8380 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8381 k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8382 [(set_attr "type" "alu,alu,msklog")
8383 (set_attr "mode" "<MODE>")])
8385 (define_insn "*<code>hi_1"
8386 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8388 (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8389 (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8390 (clobber (reg:CC FLAGS_REG))]
8391 "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8393 <logic>{w}\t{%2, %0|%0, %2}
8394 <logic>{w}\t{%2, %0|%0, %2}
8395 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8396 [(set_attr "type" "alu,alu,msklog")
8397 (set_attr "mode" "HI")])
8399 ;; %%% Potential partial reg stall on alternative 2. What to do?
8400 (define_insn "*<code>qi_1"
8401 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8402 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8403 (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8404 (clobber (reg:CC FLAGS_REG))]
8405 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8407 <logic>{b}\t{%2, %0|%0, %2}
8408 <logic>{b}\t{%2, %0|%0, %2}
8409 <logic>{l}\t{%k2, %k0|%k0, %k2}
8410 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8411 [(set_attr "type" "alu,alu,alu,msklog")
8412 (set_attr "mode" "QI,QI,SI,HI")])
8414 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8415 (define_insn "*<code>si_1_zext"
8416 [(set (match_operand:DI 0 "register_operand" "=r")
8418 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8419 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8420 (clobber (reg:CC FLAGS_REG))]
8421 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8422 "<logic>{l}\t{%2, %k0|%k0, %2}"
8423 [(set_attr "type" "alu")
8424 (set_attr "mode" "SI")])
8426 (define_insn "*<code>si_1_zext_imm"
8427 [(set (match_operand:DI 0 "register_operand" "=r")
8429 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8430 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8431 (clobber (reg:CC FLAGS_REG))]
8432 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8433 "<logic>{l}\t{%2, %k0|%k0, %2}"
8434 [(set_attr "type" "alu")
8435 (set_attr "mode" "SI")])
8437 (define_insn "*<code>qi_1_slp"
8438 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8439 (any_or:QI (match_dup 0)
8440 (match_operand:QI 1 "general_operand" "qmn,qn")))
8441 (clobber (reg:CC FLAGS_REG))]
8442 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8443 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8444 "<logic>{b}\t{%1, %0|%0, %1}"
8445 [(set_attr "type" "alu1")
8446 (set_attr "mode" "QI")])
8448 (define_insn "*<code><mode>_2"
8449 [(set (reg FLAGS_REG)
8450 (compare (any_or:SWI
8451 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8452 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8454 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8455 (any_or:SWI (match_dup 1) (match_dup 2)))]
8456 "ix86_match_ccmode (insn, CCNOmode)
8457 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8458 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8459 [(set_attr "type" "alu")
8460 (set_attr "mode" "<MODE>")])
8462 (define_insn "kxnor<mode>"
8463 [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8466 (match_operand:SWI12 1 "register_operand" "0,k")
8467 (match_operand:SWI12 2 "register_operand" "r,k"))))
8468 (clobber (reg:CC FLAGS_REG))]
8471 if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8472 return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8473 return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8475 [(set_attr "type" "*,msklog")
8476 (set_attr "prefix" "*,vex")
8477 (set_attr "mode" "<MODE>")])
8479 (define_insn "kxnor<mode>"
8480 [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8483 (match_operand:SWI48x 1 "register_operand" "0,k")
8484 (match_operand:SWI48x 2 "register_operand" "r,k"))))
8485 (clobber (reg:CC FLAGS_REG))]
8489 kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8490 [(set_attr "type" "*,msklog")
8491 (set_attr "prefix" "*,vex")
8492 (set_attr "mode" "<MODE>")])
8495 [(set (match_operand:SWI1248x 0 "general_reg_operand")
8499 (match_operand:SWI1248x 1 "general_reg_operand"))))
8500 (clobber (reg:CC FLAGS_REG))]
8501 "TARGET_AVX512F && reload_completed"
8502 [(parallel [(set (match_dup 0)
8503 (xor:HI (match_dup 0)
8505 (clobber (reg:CC FLAGS_REG))])
8507 (not:HI (match_dup 0)))])
8509 ;;There are kortrest[bdq] but no intrinsics for them.
8510 ;;We probably don't need to implement them.
8511 (define_insn "kortestzhi"
8512 [(set (reg:CCZ FLAGS_REG)
8515 (match_operand:HI 0 "register_operand" "k")
8516 (match_operand:HI 1 "register_operand" "k"))
8518 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8519 "kortestw\t{%1, %0|%0, %1}"
8520 [(set_attr "mode" "HI")
8521 (set_attr "type" "msklog")
8522 (set_attr "prefix" "vex")])
8524 (define_insn "kortestchi"
8525 [(set (reg:CCC FLAGS_REG)
8528 (match_operand:HI 0 "register_operand" "k")
8529 (match_operand:HI 1 "register_operand" "k"))
8531 "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8532 "kortestw\t{%1, %0|%0, %1}"
8533 [(set_attr "mode" "HI")
8534 (set_attr "type" "msklog")
8535 (set_attr "prefix" "vex")])
8537 (define_insn "kunpckhi"
8538 [(set (match_operand:HI 0 "register_operand" "=k")
8541 (match_operand:HI 1 "register_operand" "k")
8543 (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8545 "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8546 [(set_attr "mode" "HI")
8547 (set_attr "type" "msklog")
8548 (set_attr "prefix" "vex")])
8550 (define_insn "kunpcksi"
8551 [(set (match_operand:SI 0 "register_operand" "=k")
8554 (match_operand:SI 1 "register_operand" "k")
8556 (zero_extend:SI (subreg:HI (match_operand:SI 2 "register_operand" "k") 0))))]
8558 "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8559 [(set_attr "mode" "SI")])
8561 (define_insn "kunpckdi"
8562 [(set (match_operand:DI 0 "register_operand" "=k")
8565 (match_operand:DI 1 "register_operand" "k")
8567 (zero_extend:DI (subreg:SI (match_operand:DI 2 "register_operand" "k") 0))))]
8569 "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8570 [(set_attr "mode" "DI")])
8572 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8573 ;; ??? Special case for immediate operand is missing - it is tricky.
8574 (define_insn "*<code>si_2_zext"
8575 [(set (reg FLAGS_REG)
8576 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8577 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8579 (set (match_operand:DI 0 "register_operand" "=r")
8580 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8581 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8582 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8583 "<logic>{l}\t{%2, %k0|%k0, %2}"
8584 [(set_attr "type" "alu")
8585 (set_attr "mode" "SI")])
8587 (define_insn "*<code>si_2_zext_imm"
8588 [(set (reg FLAGS_REG)
8590 (match_operand:SI 1 "nonimmediate_operand" "%0")
8591 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8593 (set (match_operand:DI 0 "register_operand" "=r")
8594 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8595 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8596 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8597 "<logic>{l}\t{%2, %k0|%k0, %2}"
8598 [(set_attr "type" "alu")
8599 (set_attr "mode" "SI")])
8601 (define_insn "*<code>qi_2_slp"
8602 [(set (reg FLAGS_REG)
8603 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8604 (match_operand:QI 1 "general_operand" "qmn,qn"))
8606 (set (strict_low_part (match_dup 0))
8607 (any_or:QI (match_dup 0) (match_dup 1)))]
8608 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8609 && ix86_match_ccmode (insn, CCNOmode)
8610 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8611 "<logic>{b}\t{%1, %0|%0, %1}"
8612 [(set_attr "type" "alu1")
8613 (set_attr "mode" "QI")])
8615 (define_insn "*<code><mode>_3"
8616 [(set (reg FLAGS_REG)
8617 (compare (any_or:SWI
8618 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8619 (match_operand:SWI 2 "<general_operand>" "<g>"))
8621 (clobber (match_scratch:SWI 0 "=<r>"))]
8622 "ix86_match_ccmode (insn, CCNOmode)
8623 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8624 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8625 [(set_attr "type" "alu")
8626 (set_attr "mode" "<MODE>")])
8628 (define_insn "*<code>qi_ext_0"
8629 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8634 (match_operand 1 "ext_register_operand" "0")
8637 (match_operand 2 "const_int_operand" "n")))
8638 (clobber (reg:CC FLAGS_REG))]
8639 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8640 "<logic>{b}\t{%2, %h0|%h0, %2}"
8641 [(set_attr "type" "alu")
8642 (set_attr "length_immediate" "1")
8643 (set_attr "modrm" "1")
8644 (set_attr "mode" "QI")])
8646 (define_insn "*<code>qi_ext_1"
8647 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8652 (match_operand 1 "ext_register_operand" "0,0")
8656 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8657 (clobber (reg:CC FLAGS_REG))]
8658 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8659 "<logic>{b}\t{%2, %h0|%h0, %2}"
8660 [(set_attr "isa" "*,nox64")
8661 (set_attr "type" "alu")
8662 (set_attr "length_immediate" "0")
8663 (set_attr "mode" "QI")])
8665 (define_insn "*<code>qi_ext_2"
8666 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8670 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8673 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8676 (clobber (reg:CC FLAGS_REG))]
8677 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8678 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8679 [(set_attr "type" "alu")
8680 (set_attr "length_immediate" "0")
8681 (set_attr "mode" "QI")])
8684 [(set (match_operand 0 "QIreg_operand")
8685 (any_or (match_operand 1 "register_operand")
8686 (match_operand 2 "const_int_operand")))
8687 (clobber (reg:CC FLAGS_REG))]
8689 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8690 && !(INTVAL (operands[2]) & ~(255 << 8))
8691 && GET_MODE (operands[0]) != QImode"
8692 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8693 (any_or:SI (zero_extract:SI (match_dup 1)
8694 (const_int 8) (const_int 8))
8696 (clobber (reg:CC FLAGS_REG))])]
8698 operands[0] = gen_lowpart (SImode, operands[0]);
8699 operands[1] = gen_lowpart (SImode, operands[1]);
8700 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8703 ;; Since OR can be encoded with sign extended immediate, this is only
8704 ;; profitable when 7th bit is set.
8706 [(set (match_operand 0 "any_QIreg_operand")
8707 (any_or (match_operand 1 "general_operand")
8708 (match_operand 2 "const_int_operand")))
8709 (clobber (reg:CC FLAGS_REG))]
8711 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8712 && !(INTVAL (operands[2]) & ~255)
8713 && (INTVAL (operands[2]) & 128)
8714 && GET_MODE (operands[0]) != QImode"
8715 [(parallel [(set (strict_low_part (match_dup 0))
8716 (any_or:QI (match_dup 1)
8718 (clobber (reg:CC FLAGS_REG))])]
8720 operands[0] = gen_lowpart (QImode, operands[0]);
8721 operands[1] = gen_lowpart (QImode, operands[1]);
8722 operands[2] = gen_lowpart (QImode, operands[2]);
8725 (define_expand "xorqi_cc_ext_1"
8727 (set (reg:CCNO FLAGS_REG)
8731 (match_operand 1 "ext_register_operand")
8734 (match_operand:QI 2 "const_int_operand"))
8736 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8746 (define_insn "*xorqi_cc_ext_1"
8747 [(set (reg FLAGS_REG)
8751 (match_operand 1 "ext_register_operand" "0,0")
8754 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8756 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8765 "ix86_match_ccmode (insn, CCNOmode)"
8766 "xor{b}\t{%2, %h0|%h0, %2}"
8767 [(set_attr "isa" "*,nox64")
8768 (set_attr "type" "alu")
8769 (set_attr "modrm" "1")
8770 (set_attr "mode" "QI")])
8772 ;; Negation instructions
8774 (define_expand "neg<mode>2"
8775 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8776 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8778 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8780 (define_insn_and_split "*neg<dwi>2_doubleword"
8781 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8782 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8783 (clobber (reg:CC FLAGS_REG))]
8784 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8788 [(set (reg:CCZ FLAGS_REG)
8789 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8790 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8793 (plus:DWIH (match_dup 3)
8794 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8796 (clobber (reg:CC FLAGS_REG))])
8799 (neg:DWIH (match_dup 2)))
8800 (clobber (reg:CC FLAGS_REG))])]
8801 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8803 (define_insn "*neg<mode>2_1"
8804 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8805 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8806 (clobber (reg:CC FLAGS_REG))]
8807 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8808 "neg{<imodesuffix>}\t%0"
8809 [(set_attr "type" "negnot")
8810 (set_attr "mode" "<MODE>")])
8812 ;; Combine is quite creative about this pattern.
8813 (define_insn "*negsi2_1_zext"
8814 [(set (match_operand:DI 0 "register_operand" "=r")
8816 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8819 (clobber (reg:CC FLAGS_REG))]
8820 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8822 [(set_attr "type" "negnot")
8823 (set_attr "mode" "SI")])
8825 ;; The problem with neg is that it does not perform (compare x 0),
8826 ;; it really performs (compare 0 x), which leaves us with the zero
8827 ;; flag being the only useful item.
8829 (define_insn "*neg<mode>2_cmpz"
8830 [(set (reg:CCZ FLAGS_REG)
8832 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8834 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8835 (neg:SWI (match_dup 1)))]
8836 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8837 "neg{<imodesuffix>}\t%0"
8838 [(set_attr "type" "negnot")
8839 (set_attr "mode" "<MODE>")])
8841 (define_insn "*negsi2_cmpz_zext"
8842 [(set (reg:CCZ FLAGS_REG)
8846 (match_operand:DI 1 "register_operand" "0")
8850 (set (match_operand:DI 0 "register_operand" "=r")
8851 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8854 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8856 [(set_attr "type" "negnot")
8857 (set_attr "mode" "SI")])
8859 ;; Negate with jump on overflow.
8860 (define_expand "negv<mode>3"
8861 [(parallel [(set (reg:CCO FLAGS_REG)
8862 (ne:CCO (match_operand:SWI 1 "register_operand")
8864 (set (match_operand:SWI 0 "register_operand")
8865 (neg:SWI (match_dup 1)))])
8866 (set (pc) (if_then_else
8867 (eq (reg:CCO FLAGS_REG) (const_int 0))
8868 (label_ref (match_operand 2))
8873 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8877 (define_insn "*negv<mode>3"
8878 [(set (reg:CCO FLAGS_REG)
8879 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8880 (match_operand:SWI 2 "const_int_operand")))
8881 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8882 (neg:SWI (match_dup 1)))]
8883 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8884 && mode_signbit_p (<MODE>mode, operands[2])"
8885 "neg{<imodesuffix>}\t%0"
8886 [(set_attr "type" "negnot")
8887 (set_attr "mode" "<MODE>")])
8889 ;; Changing of sign for FP values is doable using integer unit too.
8891 (define_expand "<code><mode>2"
8892 [(set (match_operand:X87MODEF 0 "register_operand")
8893 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8894 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8895 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8897 (define_insn "*absneg<mode>2_mixed"
8898 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8899 (match_operator:MODEF 3 "absneg_operator"
8900 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8901 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8902 (clobber (reg:CC FLAGS_REG))]
8903 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8905 [(set (attr "enabled")
8906 (cond [(eq_attr "alternative" "2")
8907 (symbol_ref "TARGET_MIX_SSE_I387")
8909 (symbol_ref "true")))])
8911 (define_insn "*absneg<mode>2_i387"
8912 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8913 (match_operator:X87MODEF 3 "absneg_operator"
8914 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8915 (use (match_operand 2))
8916 (clobber (reg:CC FLAGS_REG))]
8917 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8920 (define_expand "<code>tf2"
8921 [(set (match_operand:TF 0 "register_operand")
8922 (absneg:TF (match_operand:TF 1 "register_operand")))]
8924 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8926 (define_insn "*absnegtf2_sse"
8927 [(set (match_operand:TF 0 "register_operand" "=x,x")
8928 (match_operator:TF 3 "absneg_operator"
8929 [(match_operand:TF 1 "register_operand" "0,x")]))
8930 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8931 (clobber (reg:CC FLAGS_REG))]
8935 ;; Splitters for fp abs and neg.
8938 [(set (match_operand 0 "fp_register_operand")
8939 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8940 (use (match_operand 2))
8941 (clobber (reg:CC FLAGS_REG))]
8943 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8946 [(set (match_operand 0 "register_operand")
8947 (match_operator 3 "absneg_operator"
8948 [(match_operand 1 "register_operand")]))
8949 (use (match_operand 2 "nonimmediate_operand"))
8950 (clobber (reg:CC FLAGS_REG))]
8951 "reload_completed && SSE_REG_P (operands[0])"
8952 [(set (match_dup 0) (match_dup 3))]
8954 machine_mode mode = GET_MODE (operands[0]);
8955 machine_mode vmode = GET_MODE (operands[2]);
8958 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8959 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8960 if (operands_match_p (operands[0], operands[2]))
8961 std::swap (operands[1], operands[2]);
8962 if (GET_CODE (operands[3]) == ABS)
8963 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8965 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8970 [(set (match_operand:SF 0 "register_operand")
8971 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8972 (use (match_operand:V4SF 2))
8973 (clobber (reg:CC FLAGS_REG))]
8975 [(parallel [(set (match_dup 0) (match_dup 1))
8976 (clobber (reg:CC FLAGS_REG))])]
8979 operands[0] = gen_lowpart (SImode, operands[0]);
8980 if (GET_CODE (operands[1]) == ABS)
8982 tmp = gen_int_mode (0x7fffffff, SImode);
8983 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8987 tmp = gen_int_mode (0x80000000, SImode);
8988 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8994 [(set (match_operand:DF 0 "register_operand")
8995 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8996 (use (match_operand 2))
8997 (clobber (reg:CC FLAGS_REG))]
8999 [(parallel [(set (match_dup 0) (match_dup 1))
9000 (clobber (reg:CC FLAGS_REG))])]
9005 tmp = gen_lowpart (DImode, operands[0]);
9006 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9009 if (GET_CODE (operands[1]) == ABS)
9012 tmp = gen_rtx_NOT (DImode, tmp);
9016 operands[0] = gen_highpart (SImode, operands[0]);
9017 if (GET_CODE (operands[1]) == ABS)
9019 tmp = gen_int_mode (0x7fffffff, SImode);
9020 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9024 tmp = gen_int_mode (0x80000000, SImode);
9025 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9032 [(set (match_operand:XF 0 "register_operand")
9033 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9034 (use (match_operand 2))
9035 (clobber (reg:CC FLAGS_REG))]
9037 [(parallel [(set (match_dup 0) (match_dup 1))
9038 (clobber (reg:CC FLAGS_REG))])]
9041 operands[0] = gen_rtx_REG (SImode,
9042 true_regnum (operands[0])
9043 + (TARGET_64BIT ? 1 : 2));
9044 if (GET_CODE (operands[1]) == ABS)
9046 tmp = GEN_INT (0x7fff);
9047 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9051 tmp = GEN_INT (0x8000);
9052 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9057 ;; Conditionalize these after reload. If they match before reload, we
9058 ;; lose the clobber and ability to use integer instructions.
9060 (define_insn "*<code><mode>2_1"
9061 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9062 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9064 && (reload_completed
9065 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9066 "f<absneg_mnemonic>"
9067 [(set_attr "type" "fsgn")
9068 (set_attr "mode" "<MODE>")])
9070 (define_insn "*<code>extendsfdf2"
9071 [(set (match_operand:DF 0 "register_operand" "=f")
9072 (absneg:DF (float_extend:DF
9073 (match_operand:SF 1 "register_operand" "0"))))]
9074 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9075 "f<absneg_mnemonic>"
9076 [(set_attr "type" "fsgn")
9077 (set_attr "mode" "DF")])
9079 (define_insn "*<code>extendsfxf2"
9080 [(set (match_operand:XF 0 "register_operand" "=f")
9081 (absneg:XF (float_extend:XF
9082 (match_operand:SF 1 "register_operand" "0"))))]
9084 "f<absneg_mnemonic>"
9085 [(set_attr "type" "fsgn")
9086 (set_attr "mode" "XF")])
9088 (define_insn "*<code>extenddfxf2"
9089 [(set (match_operand:XF 0 "register_operand" "=f")
9090 (absneg:XF (float_extend:XF
9091 (match_operand:DF 1 "register_operand" "0"))))]
9093 "f<absneg_mnemonic>"
9094 [(set_attr "type" "fsgn")
9095 (set_attr "mode" "XF")])
9097 ;; Copysign instructions
9099 (define_mode_iterator CSGNMODE [SF DF TF])
9100 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9102 (define_expand "copysign<mode>3"
9103 [(match_operand:CSGNMODE 0 "register_operand")
9104 (match_operand:CSGNMODE 1 "nonmemory_operand")
9105 (match_operand:CSGNMODE 2 "register_operand")]
9106 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9107 || (TARGET_SSE && (<MODE>mode == TFmode))"
9108 "ix86_expand_copysign (operands); DONE;")
9110 (define_insn_and_split "copysign<mode>3_const"
9111 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9113 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9114 (match_operand:CSGNMODE 2 "register_operand" "0")
9115 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9117 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9118 || (TARGET_SSE && (<MODE>mode == TFmode))"
9120 "&& reload_completed"
9122 "ix86_split_copysign_const (operands); DONE;")
9124 (define_insn "copysign<mode>3_var"
9125 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9127 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9128 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9129 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9130 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9132 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9133 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9134 || (TARGET_SSE && (<MODE>mode == TFmode))"
9138 [(set (match_operand:CSGNMODE 0 "register_operand")
9140 [(match_operand:CSGNMODE 2 "register_operand")
9141 (match_operand:CSGNMODE 3 "register_operand")
9142 (match_operand:<CSGNVMODE> 4)
9143 (match_operand:<CSGNVMODE> 5)]
9145 (clobber (match_scratch:<CSGNVMODE> 1))]
9146 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9147 || (TARGET_SSE && (<MODE>mode == TFmode)))
9148 && reload_completed"
9150 "ix86_split_copysign_var (operands); DONE;")
9152 ;; One complement instructions
9154 (define_expand "one_cmpl<mode>2"
9155 [(set (match_operand:SWIM 0 "nonimmediate_operand")
9156 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9158 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9160 (define_insn "*one_cmpl<mode>2_1"
9161 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
9162 (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
9163 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9165 not{<imodesuffix>}\t%0
9166 knot<mskmodesuffix>\t{%1, %0|%0, %1}"
9167 [(set_attr "isa" "*,avx512bw")
9168 (set_attr "type" "negnot,msklog")
9169 (set_attr "prefix" "*,vex")
9170 (set_attr "mode" "<MODE>")])
9172 (define_insn "*one_cmplhi2_1"
9173 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
9174 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
9175 "ix86_unary_operator_ok (NOT, HImode, operands)"
9178 knotw\t{%1, %0|%0, %1}"
9179 [(set_attr "isa" "*,avx512f")
9180 (set_attr "type" "negnot,msklog")
9181 (set_attr "prefix" "*,vex")
9182 (set_attr "mode" "HI")])
9184 ;; %%% Potential partial reg stall on alternative 1. What to do?
9185 (define_insn "*one_cmplqi2_1"
9186 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
9187 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
9188 "ix86_unary_operator_ok (NOT, QImode, operands)"
9190 switch (which_alternative)
9193 return "not{b}\t%0";
9195 return "not{l}\t%k0";
9197 if (TARGET_AVX512DQ)
9198 return "knotb\t{%1, %0|%0, %1}";
9199 return "knotw\t{%1, %0|%0, %1}";
9204 [(set_attr "isa" "*,*,avx512f")
9205 (set_attr "type" "negnot,negnot,msklog")
9206 (set_attr "prefix" "*,*,vex")
9207 (set_attr "mode" "QI,SI,QI")])
9209 ;; ??? Currently never generated - xor is used instead.
9210 (define_insn "*one_cmplsi2_1_zext"
9211 [(set (match_operand:DI 0 "register_operand" "=r")
9213 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9214 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9216 [(set_attr "type" "negnot")
9217 (set_attr "mode" "SI")])
9219 (define_insn "*one_cmpl<mode>2_2"
9220 [(set (reg FLAGS_REG)
9221 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9223 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9224 (not:SWI (match_dup 1)))]
9225 "ix86_match_ccmode (insn, CCNOmode)
9226 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9228 [(set_attr "type" "alu1")
9229 (set_attr "mode" "<MODE>")])
9232 [(set (match_operand 0 "flags_reg_operand")
9233 (match_operator 2 "compare_operator"
9234 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9236 (set (match_operand:SWI 1 "nonimmediate_operand")
9237 (not:SWI (match_dup 3)))]
9238 "ix86_match_ccmode (insn, CCNOmode)"
9239 [(parallel [(set (match_dup 0)
9240 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9243 (xor:SWI (match_dup 3) (const_int -1)))])])
9245 ;; ??? Currently never generated - xor is used instead.
9246 (define_insn "*one_cmplsi2_2_zext"
9247 [(set (reg FLAGS_REG)
9248 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9250 (set (match_operand:DI 0 "register_operand" "=r")
9251 (zero_extend:DI (not:SI (match_dup 1))))]
9252 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9253 && ix86_unary_operator_ok (NOT, SImode, operands)"
9255 [(set_attr "type" "alu1")
9256 (set_attr "mode" "SI")])
9259 [(set (match_operand 0 "flags_reg_operand")
9260 (match_operator 2 "compare_operator"
9261 [(not:SI (match_operand:SI 3 "register_operand"))
9263 (set (match_operand:DI 1 "register_operand")
9264 (zero_extend:DI (not:SI (match_dup 3))))]
9265 "ix86_match_ccmode (insn, CCNOmode)"
9266 [(parallel [(set (match_dup 0)
9267 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9270 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9272 ;; Shift instructions
9274 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9275 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9276 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9277 ;; from the assembler input.
9279 ;; This instruction shifts the target reg/mem as usual, but instead of
9280 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9281 ;; is a left shift double, bits are taken from the high order bits of
9282 ;; reg, else if the insn is a shift right double, bits are taken from the
9283 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9284 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9286 ;; Since sh[lr]d does not change the `reg' operand, that is done
9287 ;; separately, making all shifts emit pairs of shift double and normal
9288 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9289 ;; support a 63 bit shift, each shift where the count is in a reg expands
9290 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9292 ;; If the shift count is a constant, we need never emit more than one
9293 ;; shift pair, instead using moves and sign extension for counts greater
9296 (define_expand "ashl<mode>3"
9297 [(set (match_operand:SDWIM 0 "<shift_operand>")
9298 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9299 (match_operand:QI 2 "nonmemory_operand")))]
9301 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9303 (define_insn "*ashl<mode>3_doubleword"
9304 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9305 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9306 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9307 (clobber (reg:CC FLAGS_REG))]
9310 [(set_attr "type" "multi")])
9313 [(set (match_operand:DWI 0 "register_operand")
9314 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9315 (match_operand:QI 2 "nonmemory_operand")))
9316 (clobber (reg:CC FLAGS_REG))]
9317 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9319 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9321 ;; By default we don't ask for a scratch register, because when DWImode
9322 ;; values are manipulated, registers are already at a premium. But if
9323 ;; we have one handy, we won't turn it away.
9326 [(match_scratch:DWIH 3 "r")
9327 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9329 (match_operand:<DWI> 1 "nonmemory_operand")
9330 (match_operand:QI 2 "nonmemory_operand")))
9331 (clobber (reg:CC FLAGS_REG))])
9335 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9337 (define_insn "x86_64_shld"
9338 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9339 (ior:DI (ashift:DI (match_dup 0)
9340 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9341 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9342 (minus:QI (const_int 64) (match_dup 2)))))
9343 (clobber (reg:CC FLAGS_REG))]
9345 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9346 [(set_attr "type" "ishift")
9347 (set_attr "prefix_0f" "1")
9348 (set_attr "mode" "DI")
9349 (set_attr "athlon_decode" "vector")
9350 (set_attr "amdfam10_decode" "vector")
9351 (set_attr "bdver1_decode" "vector")])
9353 (define_insn "x86_shld"
9354 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9355 (ior:SI (ashift:SI (match_dup 0)
9356 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9357 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9358 (minus:QI (const_int 32) (match_dup 2)))))
9359 (clobber (reg:CC FLAGS_REG))]
9361 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9362 [(set_attr "type" "ishift")
9363 (set_attr "prefix_0f" "1")
9364 (set_attr "mode" "SI")
9365 (set_attr "pent_pair" "np")
9366 (set_attr "athlon_decode" "vector")
9367 (set_attr "amdfam10_decode" "vector")
9368 (set_attr "bdver1_decode" "vector")])
9370 (define_expand "x86_shift<mode>_adj_1"
9371 [(set (reg:CCZ FLAGS_REG)
9372 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9375 (set (match_operand:SWI48 0 "register_operand")
9376 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9377 (match_operand:SWI48 1 "register_operand")
9380 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9381 (match_operand:SWI48 3 "register_operand")
9384 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9386 (define_expand "x86_shift<mode>_adj_2"
9387 [(use (match_operand:SWI48 0 "register_operand"))
9388 (use (match_operand:SWI48 1 "register_operand"))
9389 (use (match_operand:QI 2 "register_operand"))]
9392 rtx_code_label *label = gen_label_rtx ();
9395 emit_insn (gen_testqi_ccz_1 (operands[2],
9396 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9398 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9399 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9400 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9401 gen_rtx_LABEL_REF (VOIDmode, label),
9403 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
9404 JUMP_LABEL (tmp) = label;
9406 emit_move_insn (operands[0], operands[1]);
9407 ix86_expand_clear (operands[1]);
9410 LABEL_NUSES (label) = 1;
9415 ;; Avoid useless masking of count operand.
9416 (define_insn "*ashl<mode>3_mask"
9417 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9419 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9422 (match_operand:SI 2 "register_operand" "c")
9423 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9424 (clobber (reg:CC FLAGS_REG))]
9425 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9426 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9427 == GET_MODE_BITSIZE (<MODE>mode)-1"
9429 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9431 [(set_attr "type" "ishift")
9432 (set_attr "mode" "<MODE>")])
9434 (define_insn "*bmi2_ashl<mode>3_1"
9435 [(set (match_operand:SWI48 0 "register_operand" "=r")
9436 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9437 (match_operand:SWI48 2 "register_operand" "r")))]
9439 "shlx\t{%2, %1, %0|%0, %1, %2}"
9440 [(set_attr "type" "ishiftx")
9441 (set_attr "mode" "<MODE>")])
9443 (define_insn "*ashl<mode>3_1"
9444 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9445 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9446 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9447 (clobber (reg:CC FLAGS_REG))]
9448 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9450 switch (get_attr_type (insn))
9457 gcc_assert (operands[2] == const1_rtx);
9458 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9459 return "add{<imodesuffix>}\t%0, %0";
9462 if (operands[2] == const1_rtx
9463 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9464 return "sal{<imodesuffix>}\t%0";
9466 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9469 [(set_attr "isa" "*,*,bmi2")
9471 (cond [(eq_attr "alternative" "1")
9472 (const_string "lea")
9473 (eq_attr "alternative" "2")
9474 (const_string "ishiftx")
9475 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9476 (match_operand 0 "register_operand"))
9477 (match_operand 2 "const1_operand"))
9478 (const_string "alu")
9480 (const_string "ishift")))
9481 (set (attr "length_immediate")
9483 (ior (eq_attr "type" "alu")
9484 (and (eq_attr "type" "ishift")
9485 (and (match_operand 2 "const1_operand")
9486 (ior (match_test "TARGET_SHIFT1")
9487 (match_test "optimize_function_for_size_p (cfun)")))))
9489 (const_string "*")))
9490 (set_attr "mode" "<MODE>")])
9492 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9494 [(set (match_operand:SWI48 0 "register_operand")
9495 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9496 (match_operand:QI 2 "register_operand")))
9497 (clobber (reg:CC FLAGS_REG))]
9498 "TARGET_BMI2 && reload_completed"
9500 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9501 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9503 (define_insn "*bmi2_ashlsi3_1_zext"
9504 [(set (match_operand:DI 0 "register_operand" "=r")
9506 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9507 (match_operand:SI 2 "register_operand" "r"))))]
9508 "TARGET_64BIT && TARGET_BMI2"
9509 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9510 [(set_attr "type" "ishiftx")
9511 (set_attr "mode" "SI")])
9513 (define_insn "*ashlsi3_1_zext"
9514 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9516 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9517 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9518 (clobber (reg:CC FLAGS_REG))]
9519 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9521 switch (get_attr_type (insn))
9528 gcc_assert (operands[2] == const1_rtx);
9529 return "add{l}\t%k0, %k0";
9532 if (operands[2] == const1_rtx
9533 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9534 return "sal{l}\t%k0";
9536 return "sal{l}\t{%2, %k0|%k0, %2}";
9539 [(set_attr "isa" "*,*,bmi2")
9541 (cond [(eq_attr "alternative" "1")
9542 (const_string "lea")
9543 (eq_attr "alternative" "2")
9544 (const_string "ishiftx")
9545 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9546 (match_operand 2 "const1_operand"))
9547 (const_string "alu")
9549 (const_string "ishift")))
9550 (set (attr "length_immediate")
9552 (ior (eq_attr "type" "alu")
9553 (and (eq_attr "type" "ishift")
9554 (and (match_operand 2 "const1_operand")
9555 (ior (match_test "TARGET_SHIFT1")
9556 (match_test "optimize_function_for_size_p (cfun)")))))
9558 (const_string "*")))
9559 (set_attr "mode" "SI")])
9561 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9563 [(set (match_operand:DI 0 "register_operand")
9565 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9566 (match_operand:QI 2 "register_operand"))))
9567 (clobber (reg:CC FLAGS_REG))]
9568 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9570 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9571 "operands[2] = gen_lowpart (SImode, operands[2]);")
9573 (define_insn "*ashlhi3_1"
9574 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9575 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9576 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9577 (clobber (reg:CC FLAGS_REG))]
9578 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9580 switch (get_attr_type (insn))
9586 gcc_assert (operands[2] == const1_rtx);
9587 return "add{w}\t%0, %0";
9590 if (operands[2] == const1_rtx
9591 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9592 return "sal{w}\t%0";
9594 return "sal{w}\t{%2, %0|%0, %2}";
9598 (cond [(eq_attr "alternative" "1")
9599 (const_string "lea")
9600 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9601 (match_operand 0 "register_operand"))
9602 (match_operand 2 "const1_operand"))
9603 (const_string "alu")
9605 (const_string "ishift")))
9606 (set (attr "length_immediate")
9608 (ior (eq_attr "type" "alu")
9609 (and (eq_attr "type" "ishift")
9610 (and (match_operand 2 "const1_operand")
9611 (ior (match_test "TARGET_SHIFT1")
9612 (match_test "optimize_function_for_size_p (cfun)")))))
9614 (const_string "*")))
9615 (set_attr "mode" "HI,SI")])
9617 ;; %%% Potential partial reg stall on alternative 1. What to do?
9618 (define_insn "*ashlqi3_1"
9619 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9620 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9621 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9622 (clobber (reg:CC FLAGS_REG))]
9623 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9625 switch (get_attr_type (insn))
9631 gcc_assert (operands[2] == const1_rtx);
9632 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
9633 return "add{l}\t%k0, %k0";
9635 return "add{b}\t%0, %0";
9638 if (operands[2] == const1_rtx
9639 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9641 if (get_attr_mode (insn) == MODE_SI)
9642 return "sal{l}\t%k0";
9644 return "sal{b}\t%0";
9648 if (get_attr_mode (insn) == MODE_SI)
9649 return "sal{l}\t{%2, %k0|%k0, %2}";
9651 return "sal{b}\t{%2, %0|%0, %2}";
9656 (cond [(eq_attr "alternative" "2")
9657 (const_string "lea")
9658 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9659 (match_operand 0 "register_operand"))
9660 (match_operand 2 "const1_operand"))
9661 (const_string "alu")
9663 (const_string "ishift")))
9664 (set (attr "length_immediate")
9666 (ior (eq_attr "type" "alu")
9667 (and (eq_attr "type" "ishift")
9668 (and (match_operand 2 "const1_operand")
9669 (ior (match_test "TARGET_SHIFT1")
9670 (match_test "optimize_function_for_size_p (cfun)")))))
9672 (const_string "*")))
9673 (set_attr "mode" "QI,SI,SI")])
9675 (define_insn "*ashlqi3_1_slp"
9676 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9677 (ashift:QI (match_dup 0)
9678 (match_operand:QI 1 "nonmemory_operand" "cI")))
9679 (clobber (reg:CC FLAGS_REG))]
9680 "(optimize_function_for_size_p (cfun)
9681 || !TARGET_PARTIAL_FLAG_REG_STALL
9682 || (operands[1] == const1_rtx
9684 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9686 switch (get_attr_type (insn))
9689 gcc_assert (operands[1] == const1_rtx);
9690 return "add{b}\t%0, %0";
9693 if (operands[1] == const1_rtx
9694 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9695 return "sal{b}\t%0";
9697 return "sal{b}\t{%1, %0|%0, %1}";
9701 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9702 (match_operand 0 "register_operand"))
9703 (match_operand 1 "const1_operand"))
9704 (const_string "alu")
9706 (const_string "ishift1")))
9707 (set (attr "length_immediate")
9709 (ior (eq_attr "type" "alu")
9710 (and (eq_attr "type" "ishift1")
9711 (and (match_operand 1 "const1_operand")
9712 (ior (match_test "TARGET_SHIFT1")
9713 (match_test "optimize_function_for_size_p (cfun)")))))
9715 (const_string "*")))
9716 (set_attr "mode" "QI")])
9718 ;; Convert ashift to the lea pattern to avoid flags dependency.
9720 [(set (match_operand 0 "register_operand")
9721 (ashift (match_operand 1 "index_register_operand")
9722 (match_operand:QI 2 "const_int_operand")))
9723 (clobber (reg:CC FLAGS_REG))]
9724 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9726 && true_regnum (operands[0]) != true_regnum (operands[1])"
9729 machine_mode mode = GET_MODE (operands[0]);
9732 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9735 operands[0] = gen_lowpart (mode, operands[0]);
9736 operands[1] = gen_lowpart (mode, operands[1]);
9739 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9741 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9743 emit_insn (gen_rtx_SET (operands[0], pat));
9747 ;; Convert ashift to the lea pattern to avoid flags dependency.
9749 [(set (match_operand:DI 0 "register_operand")
9751 (ashift:SI (match_operand:SI 1 "index_register_operand")
9752 (match_operand:QI 2 "const_int_operand"))))
9753 (clobber (reg:CC FLAGS_REG))]
9754 "TARGET_64BIT && reload_completed
9755 && true_regnum (operands[0]) != true_regnum (operands[1])"
9757 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9759 operands[1] = gen_lowpart (SImode, operands[1]);
9760 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9763 ;; This pattern can't accept a variable shift count, since shifts by
9764 ;; zero don't affect the flags. We assume that shifts by constant
9765 ;; zero are optimized away.
9766 (define_insn "*ashl<mode>3_cmp"
9767 [(set (reg FLAGS_REG)
9769 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9770 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9772 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9773 (ashift:SWI (match_dup 1) (match_dup 2)))]
9774 "(optimize_function_for_size_p (cfun)
9775 || !TARGET_PARTIAL_FLAG_REG_STALL
9776 || (operands[2] == const1_rtx
9778 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9779 && ix86_match_ccmode (insn, CCGOCmode)
9780 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9782 switch (get_attr_type (insn))
9785 gcc_assert (operands[2] == const1_rtx);
9786 return "add{<imodesuffix>}\t%0, %0";
9789 if (operands[2] == const1_rtx
9790 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9791 return "sal{<imodesuffix>}\t%0";
9793 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9797 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9798 (match_operand 0 "register_operand"))
9799 (match_operand 2 "const1_operand"))
9800 (const_string "alu")
9802 (const_string "ishift")))
9803 (set (attr "length_immediate")
9805 (ior (eq_attr "type" "alu")
9806 (and (eq_attr "type" "ishift")
9807 (and (match_operand 2 "const1_operand")
9808 (ior (match_test "TARGET_SHIFT1")
9809 (match_test "optimize_function_for_size_p (cfun)")))))
9811 (const_string "*")))
9812 (set_attr "mode" "<MODE>")])
9814 (define_insn "*ashlsi3_cmp_zext"
9815 [(set (reg FLAGS_REG)
9817 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9818 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9820 (set (match_operand:DI 0 "register_operand" "=r")
9821 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9823 && (optimize_function_for_size_p (cfun)
9824 || !TARGET_PARTIAL_FLAG_REG_STALL
9825 || (operands[2] == const1_rtx
9827 || TARGET_DOUBLE_WITH_ADD)))
9828 && ix86_match_ccmode (insn, CCGOCmode)
9829 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9831 switch (get_attr_type (insn))
9834 gcc_assert (operands[2] == const1_rtx);
9835 return "add{l}\t%k0, %k0";
9838 if (operands[2] == const1_rtx
9839 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9840 return "sal{l}\t%k0";
9842 return "sal{l}\t{%2, %k0|%k0, %2}";
9846 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9847 (match_operand 2 "const1_operand"))
9848 (const_string "alu")
9850 (const_string "ishift")))
9851 (set (attr "length_immediate")
9853 (ior (eq_attr "type" "alu")
9854 (and (eq_attr "type" "ishift")
9855 (and (match_operand 2 "const1_operand")
9856 (ior (match_test "TARGET_SHIFT1")
9857 (match_test "optimize_function_for_size_p (cfun)")))))
9859 (const_string "*")))
9860 (set_attr "mode" "SI")])
9862 (define_insn "*ashl<mode>3_cconly"
9863 [(set (reg FLAGS_REG)
9865 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9866 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9868 (clobber (match_scratch:SWI 0 "=<r>"))]
9869 "(optimize_function_for_size_p (cfun)
9870 || !TARGET_PARTIAL_FLAG_REG_STALL
9871 || (operands[2] == const1_rtx
9873 || TARGET_DOUBLE_WITH_ADD)))
9874 && ix86_match_ccmode (insn, CCGOCmode)"
9876 switch (get_attr_type (insn))
9879 gcc_assert (operands[2] == const1_rtx);
9880 return "add{<imodesuffix>}\t%0, %0";
9883 if (operands[2] == const1_rtx
9884 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9885 return "sal{<imodesuffix>}\t%0";
9887 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9891 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9892 (match_operand 0 "register_operand"))
9893 (match_operand 2 "const1_operand"))
9894 (const_string "alu")
9896 (const_string "ishift")))
9897 (set (attr "length_immediate")
9899 (ior (eq_attr "type" "alu")
9900 (and (eq_attr "type" "ishift")
9901 (and (match_operand 2 "const1_operand")
9902 (ior (match_test "TARGET_SHIFT1")
9903 (match_test "optimize_function_for_size_p (cfun)")))))
9905 (const_string "*")))
9906 (set_attr "mode" "<MODE>")])
9908 ;; See comment above `ashl<mode>3' about how this works.
9910 (define_expand "<shift_insn><mode>3"
9911 [(set (match_operand:SDWIM 0 "<shift_operand>")
9912 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9913 (match_operand:QI 2 "nonmemory_operand")))]
9915 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9917 ;; Avoid useless masking of count operand.
9918 (define_insn "*<shift_insn><mode>3_mask"
9919 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9921 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9924 (match_operand:SI 2 "register_operand" "c")
9925 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9926 (clobber (reg:CC FLAGS_REG))]
9927 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9928 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9929 == GET_MODE_BITSIZE (<MODE>mode)-1"
9931 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9933 [(set_attr "type" "ishift")
9934 (set_attr "mode" "<MODE>")])
9936 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9937 [(set (match_operand:DWI 0 "register_operand" "=r")
9938 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9939 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9940 (clobber (reg:CC FLAGS_REG))]
9943 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9945 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9946 [(set_attr "type" "multi")])
9948 ;; By default we don't ask for a scratch register, because when DWImode
9949 ;; values are manipulated, registers are already at a premium. But if
9950 ;; we have one handy, we won't turn it away.
9953 [(match_scratch:DWIH 3 "r")
9954 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9956 (match_operand:<DWI> 1 "register_operand")
9957 (match_operand:QI 2 "nonmemory_operand")))
9958 (clobber (reg:CC FLAGS_REG))])
9962 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9964 (define_insn "x86_64_shrd"
9965 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9966 (ior:DI (lshiftrt:DI (match_dup 0)
9967 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9968 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9969 (minus:QI (const_int 64) (match_dup 2)))))
9970 (clobber (reg:CC FLAGS_REG))]
9972 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9973 [(set_attr "type" "ishift")
9974 (set_attr "prefix_0f" "1")
9975 (set_attr "mode" "DI")
9976 (set_attr "athlon_decode" "vector")
9977 (set_attr "amdfam10_decode" "vector")
9978 (set_attr "bdver1_decode" "vector")])
9980 (define_insn "x86_shrd"
9981 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9982 (ior:SI (lshiftrt:SI (match_dup 0)
9983 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9984 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9985 (minus:QI (const_int 32) (match_dup 2)))))
9986 (clobber (reg:CC FLAGS_REG))]
9988 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9989 [(set_attr "type" "ishift")
9990 (set_attr "prefix_0f" "1")
9991 (set_attr "mode" "SI")
9992 (set_attr "pent_pair" "np")
9993 (set_attr "athlon_decode" "vector")
9994 (set_attr "amdfam10_decode" "vector")
9995 (set_attr "bdver1_decode" "vector")])
9997 (define_insn "ashrdi3_cvt"
9998 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9999 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10000 (match_operand:QI 2 "const_int_operand")))
10001 (clobber (reg:CC FLAGS_REG))]
10002 "TARGET_64BIT && INTVAL (operands[2]) == 63
10003 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10004 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10007 sar{q}\t{%2, %0|%0, %2}"
10008 [(set_attr "type" "imovx,ishift")
10009 (set_attr "prefix_0f" "0,*")
10010 (set_attr "length_immediate" "0,*")
10011 (set_attr "modrm" "0,1")
10012 (set_attr "mode" "DI")])
10014 (define_insn "ashrsi3_cvt"
10015 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10016 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10017 (match_operand:QI 2 "const_int_operand")))
10018 (clobber (reg:CC FLAGS_REG))]
10019 "INTVAL (operands[2]) == 31
10020 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10021 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10024 sar{l}\t{%2, %0|%0, %2}"
10025 [(set_attr "type" "imovx,ishift")
10026 (set_attr "prefix_0f" "0,*")
10027 (set_attr "length_immediate" "0,*")
10028 (set_attr "modrm" "0,1")
10029 (set_attr "mode" "SI")])
10031 (define_insn "*ashrsi3_cvt_zext"
10032 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10034 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10035 (match_operand:QI 2 "const_int_operand"))))
10036 (clobber (reg:CC FLAGS_REG))]
10037 "TARGET_64BIT && INTVAL (operands[2]) == 31
10038 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10039 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10042 sar{l}\t{%2, %k0|%k0, %2}"
10043 [(set_attr "type" "imovx,ishift")
10044 (set_attr "prefix_0f" "0,*")
10045 (set_attr "length_immediate" "0,*")
10046 (set_attr "modrm" "0,1")
10047 (set_attr "mode" "SI")])
10049 (define_expand "x86_shift<mode>_adj_3"
10050 [(use (match_operand:SWI48 0 "register_operand"))
10051 (use (match_operand:SWI48 1 "register_operand"))
10052 (use (match_operand:QI 2 "register_operand"))]
10055 rtx_code_label *label = gen_label_rtx ();
10058 emit_insn (gen_testqi_ccz_1 (operands[2],
10059 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10061 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10062 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10063 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10064 gen_rtx_LABEL_REF (VOIDmode, label),
10066 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10067 JUMP_LABEL (tmp) = label;
10069 emit_move_insn (operands[0], operands[1]);
10070 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10071 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10072 emit_label (label);
10073 LABEL_NUSES (label) = 1;
10078 (define_insn "*bmi2_<shift_insn><mode>3_1"
10079 [(set (match_operand:SWI48 0 "register_operand" "=r")
10080 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10081 (match_operand:SWI48 2 "register_operand" "r")))]
10083 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10084 [(set_attr "type" "ishiftx")
10085 (set_attr "mode" "<MODE>")])
10087 (define_insn "*<shift_insn><mode>3_1"
10088 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10090 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10091 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10092 (clobber (reg:CC FLAGS_REG))]
10093 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10095 switch (get_attr_type (insn))
10101 if (operands[2] == const1_rtx
10102 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10103 return "<shift>{<imodesuffix>}\t%0";
10105 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10108 [(set_attr "isa" "*,bmi2")
10109 (set_attr "type" "ishift,ishiftx")
10110 (set (attr "length_immediate")
10112 (and (match_operand 2 "const1_operand")
10113 (ior (match_test "TARGET_SHIFT1")
10114 (match_test "optimize_function_for_size_p (cfun)")))
10116 (const_string "*")))
10117 (set_attr "mode" "<MODE>")])
10119 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10121 [(set (match_operand:SWI48 0 "register_operand")
10122 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10123 (match_operand:QI 2 "register_operand")))
10124 (clobber (reg:CC FLAGS_REG))]
10125 "TARGET_BMI2 && reload_completed"
10126 [(set (match_dup 0)
10127 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10128 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10130 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10131 [(set (match_operand:DI 0 "register_operand" "=r")
10133 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10134 (match_operand:SI 2 "register_operand" "r"))))]
10135 "TARGET_64BIT && TARGET_BMI2"
10136 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10137 [(set_attr "type" "ishiftx")
10138 (set_attr "mode" "SI")])
10140 (define_insn "*<shift_insn>si3_1_zext"
10141 [(set (match_operand:DI 0 "register_operand" "=r,r")
10143 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10144 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10145 (clobber (reg:CC FLAGS_REG))]
10146 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10148 switch (get_attr_type (insn))
10154 if (operands[2] == const1_rtx
10155 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10156 return "<shift>{l}\t%k0";
10158 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10161 [(set_attr "isa" "*,bmi2")
10162 (set_attr "type" "ishift,ishiftx")
10163 (set (attr "length_immediate")
10165 (and (match_operand 2 "const1_operand")
10166 (ior (match_test "TARGET_SHIFT1")
10167 (match_test "optimize_function_for_size_p (cfun)")))
10169 (const_string "*")))
10170 (set_attr "mode" "SI")])
10172 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10174 [(set (match_operand:DI 0 "register_operand")
10176 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10177 (match_operand:QI 2 "register_operand"))))
10178 (clobber (reg:CC FLAGS_REG))]
10179 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10180 [(set (match_dup 0)
10181 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10182 "operands[2] = gen_lowpart (SImode, operands[2]);")
10184 (define_insn "*<shift_insn><mode>3_1"
10185 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10187 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10188 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10189 (clobber (reg:CC FLAGS_REG))]
10190 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10192 if (operands[2] == const1_rtx
10193 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10194 return "<shift>{<imodesuffix>}\t%0";
10196 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10198 [(set_attr "type" "ishift")
10199 (set (attr "length_immediate")
10201 (and (match_operand 2 "const1_operand")
10202 (ior (match_test "TARGET_SHIFT1")
10203 (match_test "optimize_function_for_size_p (cfun)")))
10205 (const_string "*")))
10206 (set_attr "mode" "<MODE>")])
10208 (define_insn "*<shift_insn>qi3_1_slp"
10209 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10210 (any_shiftrt:QI (match_dup 0)
10211 (match_operand:QI 1 "nonmemory_operand" "cI")))
10212 (clobber (reg:CC FLAGS_REG))]
10213 "(optimize_function_for_size_p (cfun)
10214 || !TARGET_PARTIAL_REG_STALL
10215 || (operands[1] == const1_rtx
10216 && TARGET_SHIFT1))"
10218 if (operands[1] == const1_rtx
10219 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10220 return "<shift>{b}\t%0";
10222 return "<shift>{b}\t{%1, %0|%0, %1}";
10224 [(set_attr "type" "ishift1")
10225 (set (attr "length_immediate")
10227 (and (match_operand 1 "const1_operand")
10228 (ior (match_test "TARGET_SHIFT1")
10229 (match_test "optimize_function_for_size_p (cfun)")))
10231 (const_string "*")))
10232 (set_attr "mode" "QI")])
10234 ;; This pattern can't accept a variable shift count, since shifts by
10235 ;; zero don't affect the flags. We assume that shifts by constant
10236 ;; zero are optimized away.
10237 (define_insn "*<shift_insn><mode>3_cmp"
10238 [(set (reg FLAGS_REG)
10241 (match_operand:SWI 1 "nonimmediate_operand" "0")
10242 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10244 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10245 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10246 "(optimize_function_for_size_p (cfun)
10247 || !TARGET_PARTIAL_FLAG_REG_STALL
10248 || (operands[2] == const1_rtx
10250 && ix86_match_ccmode (insn, CCGOCmode)
10251 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10253 if (operands[2] == const1_rtx
10254 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10255 return "<shift>{<imodesuffix>}\t%0";
10257 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10259 [(set_attr "type" "ishift")
10260 (set (attr "length_immediate")
10262 (and (match_operand 2 "const1_operand")
10263 (ior (match_test "TARGET_SHIFT1")
10264 (match_test "optimize_function_for_size_p (cfun)")))
10266 (const_string "*")))
10267 (set_attr "mode" "<MODE>")])
10269 (define_insn "*<shift_insn>si3_cmp_zext"
10270 [(set (reg FLAGS_REG)
10272 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10273 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10275 (set (match_operand:DI 0 "register_operand" "=r")
10276 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10278 && (optimize_function_for_size_p (cfun)
10279 || !TARGET_PARTIAL_FLAG_REG_STALL
10280 || (operands[2] == const1_rtx
10282 && ix86_match_ccmode (insn, CCGOCmode)
10283 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10285 if (operands[2] == const1_rtx
10286 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10287 return "<shift>{l}\t%k0";
10289 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10291 [(set_attr "type" "ishift")
10292 (set (attr "length_immediate")
10294 (and (match_operand 2 "const1_operand")
10295 (ior (match_test "TARGET_SHIFT1")
10296 (match_test "optimize_function_for_size_p (cfun)")))
10298 (const_string "*")))
10299 (set_attr "mode" "SI")])
10301 (define_insn "*<shift_insn><mode>3_cconly"
10302 [(set (reg FLAGS_REG)
10305 (match_operand:SWI 1 "register_operand" "0")
10306 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10308 (clobber (match_scratch:SWI 0 "=<r>"))]
10309 "(optimize_function_for_size_p (cfun)
10310 || !TARGET_PARTIAL_FLAG_REG_STALL
10311 || (operands[2] == const1_rtx
10313 && ix86_match_ccmode (insn, CCGOCmode)"
10315 if (operands[2] == const1_rtx
10316 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10317 return "<shift>{<imodesuffix>}\t%0";
10319 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10321 [(set_attr "type" "ishift")
10322 (set (attr "length_immediate")
10324 (and (match_operand 2 "const1_operand")
10325 (ior (match_test "TARGET_SHIFT1")
10326 (match_test "optimize_function_for_size_p (cfun)")))
10328 (const_string "*")))
10329 (set_attr "mode" "<MODE>")])
10331 ;; Rotate instructions
10333 (define_expand "<rotate_insn>ti3"
10334 [(set (match_operand:TI 0 "register_operand")
10335 (any_rotate:TI (match_operand:TI 1 "register_operand")
10336 (match_operand:QI 2 "nonmemory_operand")))]
10339 if (const_1_to_63_operand (operands[2], VOIDmode))
10340 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10341 (operands[0], operands[1], operands[2]));
10348 (define_expand "<rotate_insn>di3"
10349 [(set (match_operand:DI 0 "shiftdi_operand")
10350 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10351 (match_operand:QI 2 "nonmemory_operand")))]
10355 ix86_expand_binary_operator (<CODE>, DImode, operands);
10356 else if (const_1_to_31_operand (operands[2], VOIDmode))
10357 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10358 (operands[0], operands[1], operands[2]));
10365 (define_expand "<rotate_insn><mode>3"
10366 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10367 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10368 (match_operand:QI 2 "nonmemory_operand")))]
10370 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10372 ;; Avoid useless masking of count operand.
10373 (define_insn "*<rotate_insn><mode>3_mask"
10374 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10376 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10379 (match_operand:SI 2 "register_operand" "c")
10380 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10381 (clobber (reg:CC FLAGS_REG))]
10382 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10383 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10384 == GET_MODE_BITSIZE (<MODE>mode)-1"
10386 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10388 [(set_attr "type" "rotate")
10389 (set_attr "mode" "<MODE>")])
10391 ;; Implement rotation using two double-precision
10392 ;; shift instructions and a scratch register.
10394 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10395 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10396 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10397 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10398 (clobber (reg:CC FLAGS_REG))
10399 (clobber (match_scratch:DWIH 3 "=&r"))]
10403 [(set (match_dup 3) (match_dup 4))
10405 [(set (match_dup 4)
10406 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10407 (lshiftrt:DWIH (match_dup 5)
10408 (minus:QI (match_dup 6) (match_dup 2)))))
10409 (clobber (reg:CC FLAGS_REG))])
10411 [(set (match_dup 5)
10412 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10413 (lshiftrt:DWIH (match_dup 3)
10414 (minus:QI (match_dup 6) (match_dup 2)))))
10415 (clobber (reg:CC FLAGS_REG))])]
10417 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10419 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10422 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10423 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10424 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10425 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10426 (clobber (reg:CC FLAGS_REG))
10427 (clobber (match_scratch:DWIH 3 "=&r"))]
10431 [(set (match_dup 3) (match_dup 4))
10433 [(set (match_dup 4)
10434 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10435 (ashift:DWIH (match_dup 5)
10436 (minus:QI (match_dup 6) (match_dup 2)))))
10437 (clobber (reg:CC FLAGS_REG))])
10439 [(set (match_dup 5)
10440 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10441 (ashift:DWIH (match_dup 3)
10442 (minus:QI (match_dup 6) (match_dup 2)))))
10443 (clobber (reg:CC FLAGS_REG))])]
10445 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10447 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10450 (define_insn "*bmi2_rorx<mode>3_1"
10451 [(set (match_operand:SWI48 0 "register_operand" "=r")
10452 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10453 (match_operand:QI 2 "immediate_operand" "<S>")))]
10455 "rorx\t{%2, %1, %0|%0, %1, %2}"
10456 [(set_attr "type" "rotatex")
10457 (set_attr "mode" "<MODE>")])
10459 (define_insn "*<rotate_insn><mode>3_1"
10460 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10462 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10463 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10464 (clobber (reg:CC FLAGS_REG))]
10465 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10467 switch (get_attr_type (insn))
10473 if (operands[2] == const1_rtx
10474 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10475 return "<rotate>{<imodesuffix>}\t%0";
10477 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10480 [(set_attr "isa" "*,bmi2")
10481 (set_attr "type" "rotate,rotatex")
10482 (set (attr "length_immediate")
10484 (and (eq_attr "type" "rotate")
10485 (and (match_operand 2 "const1_operand")
10486 (ior (match_test "TARGET_SHIFT1")
10487 (match_test "optimize_function_for_size_p (cfun)"))))
10489 (const_string "*")))
10490 (set_attr "mode" "<MODE>")])
10492 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10494 [(set (match_operand:SWI48 0 "register_operand")
10495 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10496 (match_operand:QI 2 "immediate_operand")))
10497 (clobber (reg:CC FLAGS_REG))]
10498 "TARGET_BMI2 && reload_completed"
10499 [(set (match_dup 0)
10500 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10503 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10507 [(set (match_operand:SWI48 0 "register_operand")
10508 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10509 (match_operand:QI 2 "immediate_operand")))
10510 (clobber (reg:CC FLAGS_REG))]
10511 "TARGET_BMI2 && reload_completed"
10512 [(set (match_dup 0)
10513 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10515 (define_insn "*bmi2_rorxsi3_1_zext"
10516 [(set (match_operand:DI 0 "register_operand" "=r")
10518 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10519 (match_operand:QI 2 "immediate_operand" "I"))))]
10520 "TARGET_64BIT && TARGET_BMI2"
10521 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10522 [(set_attr "type" "rotatex")
10523 (set_attr "mode" "SI")])
10525 (define_insn "*<rotate_insn>si3_1_zext"
10526 [(set (match_operand:DI 0 "register_operand" "=r,r")
10528 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10529 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10530 (clobber (reg:CC FLAGS_REG))]
10531 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10533 switch (get_attr_type (insn))
10539 if (operands[2] == const1_rtx
10540 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10541 return "<rotate>{l}\t%k0";
10543 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10546 [(set_attr "isa" "*,bmi2")
10547 (set_attr "type" "rotate,rotatex")
10548 (set (attr "length_immediate")
10550 (and (eq_attr "type" "rotate")
10551 (and (match_operand 2 "const1_operand")
10552 (ior (match_test "TARGET_SHIFT1")
10553 (match_test "optimize_function_for_size_p (cfun)"))))
10555 (const_string "*")))
10556 (set_attr "mode" "SI")])
10558 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10560 [(set (match_operand:DI 0 "register_operand")
10562 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10563 (match_operand:QI 2 "immediate_operand"))))
10564 (clobber (reg:CC FLAGS_REG))]
10565 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10566 [(set (match_dup 0)
10567 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10570 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10574 [(set (match_operand:DI 0 "register_operand")
10576 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10577 (match_operand:QI 2 "immediate_operand"))))
10578 (clobber (reg:CC FLAGS_REG))]
10579 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10580 [(set (match_dup 0)
10581 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10583 (define_insn "*<rotate_insn><mode>3_1"
10584 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10585 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10586 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10587 (clobber (reg:CC FLAGS_REG))]
10588 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10590 if (operands[2] == const1_rtx
10591 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10592 return "<rotate>{<imodesuffix>}\t%0";
10594 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10596 [(set_attr "type" "rotate")
10597 (set (attr "length_immediate")
10599 (and (match_operand 2 "const1_operand")
10600 (ior (match_test "TARGET_SHIFT1")
10601 (match_test "optimize_function_for_size_p (cfun)")))
10603 (const_string "*")))
10604 (set_attr "mode" "<MODE>")])
10606 (define_insn "*<rotate_insn>qi3_1_slp"
10607 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10608 (any_rotate:QI (match_dup 0)
10609 (match_operand:QI 1 "nonmemory_operand" "cI")))
10610 (clobber (reg:CC FLAGS_REG))]
10611 "(optimize_function_for_size_p (cfun)
10612 || !TARGET_PARTIAL_REG_STALL
10613 || (operands[1] == const1_rtx
10614 && TARGET_SHIFT1))"
10616 if (operands[1] == const1_rtx
10617 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10618 return "<rotate>{b}\t%0";
10620 return "<rotate>{b}\t{%1, %0|%0, %1}";
10622 [(set_attr "type" "rotate1")
10623 (set (attr "length_immediate")
10625 (and (match_operand 1 "const1_operand")
10626 (ior (match_test "TARGET_SHIFT1")
10627 (match_test "optimize_function_for_size_p (cfun)")))
10629 (const_string "*")))
10630 (set_attr "mode" "QI")])
10633 [(set (match_operand:HI 0 "register_operand")
10634 (any_rotate:HI (match_dup 0) (const_int 8)))
10635 (clobber (reg:CC FLAGS_REG))]
10637 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10638 [(parallel [(set (strict_low_part (match_dup 0))
10639 (bswap:HI (match_dup 0)))
10640 (clobber (reg:CC FLAGS_REG))])])
10642 ;; Bit set / bit test instructions
10644 ;; %%% bts, btr, btc, bt.
10645 ;; In general these instructions are *slow* when applied to memory,
10646 ;; since they enforce atomic operation. When applied to registers,
10647 ;; it depends on the cpu implementation. They're never faster than
10648 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10649 ;; no point. But in 64-bit, we can't hold the relevant immediates
10650 ;; within the instruction itself, so operating on bits in the high
10651 ;; 32-bits of a register becomes easier.
10653 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10654 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10655 ;; negdf respectively, so they can never be disabled entirely.
10657 (define_insn "*btsq"
10658 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10660 (match_operand 1 "const_0_to_63_operand" "J"))
10662 (clobber (reg:CC FLAGS_REG))]
10663 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10664 "bts{q}\t{%1, %0|%0, %1}"
10665 [(set_attr "type" "alu1")
10666 (set_attr "prefix_0f" "1")
10667 (set_attr "mode" "DI")])
10669 (define_insn "*btrq"
10670 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10672 (match_operand 1 "const_0_to_63_operand" "J"))
10674 (clobber (reg:CC FLAGS_REG))]
10675 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10676 "btr{q}\t{%1, %0|%0, %1}"
10677 [(set_attr "type" "alu1")
10678 (set_attr "prefix_0f" "1")
10679 (set_attr "mode" "DI")])
10681 (define_insn "*btcq"
10682 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10684 (match_operand 1 "const_0_to_63_operand" "J"))
10685 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10686 (clobber (reg:CC FLAGS_REG))]
10687 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10688 "btc{q}\t{%1, %0|%0, %1}"
10689 [(set_attr "type" "alu1")
10690 (set_attr "prefix_0f" "1")
10691 (set_attr "mode" "DI")])
10693 ;; Allow Nocona to avoid these instructions if a register is available.
10696 [(match_scratch:DI 2 "r")
10697 (parallel [(set (zero_extract:DI
10698 (match_operand:DI 0 "register_operand")
10700 (match_operand 1 "const_0_to_63_operand"))
10702 (clobber (reg:CC FLAGS_REG))])]
10703 "TARGET_64BIT && !TARGET_USE_BT"
10706 int i = INTVAL (operands[1]);
10708 rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
10712 emit_move_insn (operands[2], op1);
10716 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10721 [(match_scratch:DI 2 "r")
10722 (parallel [(set (zero_extract:DI
10723 (match_operand:DI 0 "register_operand")
10725 (match_operand 1 "const_0_to_63_operand"))
10727 (clobber (reg:CC FLAGS_REG))])]
10728 "TARGET_64BIT && !TARGET_USE_BT"
10731 int i = INTVAL (operands[1]);
10733 rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
10737 emit_move_insn (operands[2], op1);
10741 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10746 [(match_scratch:DI 2 "r")
10747 (parallel [(set (zero_extract:DI
10748 (match_operand:DI 0 "register_operand")
10750 (match_operand 1 "const_0_to_63_operand"))
10751 (not:DI (zero_extract:DI
10752 (match_dup 0) (const_int 1) (match_dup 1))))
10753 (clobber (reg:CC FLAGS_REG))])]
10754 "TARGET_64BIT && !TARGET_USE_BT"
10757 int i = INTVAL (operands[1]);
10759 rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
10763 emit_move_insn (operands[2], op1);
10767 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10771 (define_insn "*bt<mode>"
10772 [(set (reg:CCC FLAGS_REG)
10774 (zero_extract:SWI48
10775 (match_operand:SWI48 0 "register_operand" "r")
10777 (match_operand:SI 1 "nonmemory_operand" "rN"))
10781 switch (get_attr_mode (insn))
10784 return "bt{l}\t{%1, %k0|%k0, %1}";
10787 return "bt{q}\t{%q1, %0|%0, %q1}";
10790 gcc_unreachable ();
10793 [(set_attr "type" "alu1")
10794 (set_attr "prefix_0f" "1")
10797 (and (match_test "CONST_INT_P (operands[1])")
10798 (match_test "INTVAL (operands[1]) < 32"))
10799 (const_string "SI")
10800 (const_string "<MODE>")))])
10802 (define_insn_and_split "*jcc_bt<mode>"
10804 (if_then_else (match_operator 0 "bt_comparison_operator"
10805 [(zero_extract:SWI48
10806 (match_operand:SWI48 1 "register_operand")
10808 (match_operand:SI 2 "nonmemory_operand"))
10810 (label_ref (match_operand 3))
10812 (clobber (reg:CC FLAGS_REG))]
10813 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10814 && (CONST_INT_P (operands[2])
10815 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
10816 && INTVAL (operands[2])
10817 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
10818 : register_operand (operands[2], SImode))
10819 && can_create_pseudo_p ()"
10822 [(set (reg:CCC FLAGS_REG)
10824 (zero_extract:SWI48
10830 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10831 (label_ref (match_dup 3))
10834 operands[0] = shallow_copy_rtx (operands[0]);
10835 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10838 (define_insn_and_split "*jcc_bt<mode>_1"
10840 (if_then_else (match_operator 0 "bt_comparison_operator"
10841 [(zero_extract:SWI48
10842 (match_operand:SWI48 1 "register_operand")
10845 (match_operand:QI 2 "register_operand")))
10847 (label_ref (match_operand 3))
10849 (clobber (reg:CC FLAGS_REG))]
10850 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10851 && can_create_pseudo_p ()"
10854 [(set (reg:CCC FLAGS_REG)
10856 (zero_extract:SWI48
10862 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10863 (label_ref (match_dup 3))
10866 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10867 operands[0] = shallow_copy_rtx (operands[0]);
10868 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10871 ;; Avoid useless masking of bit offset operand.
10872 (define_insn_and_split "*jcc_bt<mode>_mask"
10874 (if_then_else (match_operator 0 "bt_comparison_operator"
10875 [(zero_extract:SWI48
10876 (match_operand:SWI48 1 "register_operand")
10879 (match_operand:SI 2 "register_operand")
10880 (match_operand 3 "const_int_operand")))])
10881 (label_ref (match_operand 4))
10883 (clobber (reg:CC FLAGS_REG))]
10884 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10885 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10886 == GET_MODE_BITSIZE (<MODE>mode)-1
10887 && can_create_pseudo_p ()"
10890 [(set (reg:CCC FLAGS_REG)
10892 (zero_extract:SWI48
10898 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10899 (label_ref (match_dup 4))
10902 operands[0] = shallow_copy_rtx (operands[0]);
10903 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10906 ;; Store-flag instructions.
10908 ;; For all sCOND expanders, also expand the compare or test insn that
10909 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10911 (define_insn_and_split "*setcc_di_1"
10912 [(set (match_operand:DI 0 "register_operand" "=q")
10913 (match_operator:DI 1 "ix86_comparison_operator"
10914 [(reg FLAGS_REG) (const_int 0)]))]
10915 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10917 "&& reload_completed"
10918 [(set (match_dup 2) (match_dup 1))
10919 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10921 operands[1] = shallow_copy_rtx (operands[1]);
10922 PUT_MODE (operands[1], QImode);
10923 operands[2] = gen_lowpart (QImode, operands[0]);
10926 (define_insn_and_split "*setcc_si_1_and"
10927 [(set (match_operand:SI 0 "register_operand" "=q")
10928 (match_operator:SI 1 "ix86_comparison_operator"
10929 [(reg FLAGS_REG) (const_int 0)]))
10930 (clobber (reg:CC FLAGS_REG))]
10931 "!TARGET_PARTIAL_REG_STALL
10932 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10934 "&& reload_completed"
10935 [(set (match_dup 2) (match_dup 1))
10936 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10937 (clobber (reg:CC FLAGS_REG))])]
10939 operands[1] = shallow_copy_rtx (operands[1]);
10940 PUT_MODE (operands[1], QImode);
10941 operands[2] = gen_lowpart (QImode, operands[0]);
10944 (define_insn_and_split "*setcc_si_1_movzbl"
10945 [(set (match_operand:SI 0 "register_operand" "=q")
10946 (match_operator:SI 1 "ix86_comparison_operator"
10947 [(reg FLAGS_REG) (const_int 0)]))]
10948 "!TARGET_PARTIAL_REG_STALL
10949 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10951 "&& reload_completed"
10952 [(set (match_dup 2) (match_dup 1))
10953 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10955 operands[1] = shallow_copy_rtx (operands[1]);
10956 PUT_MODE (operands[1], QImode);
10957 operands[2] = gen_lowpart (QImode, operands[0]);
10960 (define_insn "*setcc_qi"
10961 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10962 (match_operator:QI 1 "ix86_comparison_operator"
10963 [(reg FLAGS_REG) (const_int 0)]))]
10966 [(set_attr "type" "setcc")
10967 (set_attr "mode" "QI")])
10969 (define_insn "*setcc_qi_slp"
10970 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10971 (match_operator:QI 1 "ix86_comparison_operator"
10972 [(reg FLAGS_REG) (const_int 0)]))]
10975 [(set_attr "type" "setcc")
10976 (set_attr "mode" "QI")])
10978 ;; In general it is not safe to assume too much about CCmode registers,
10979 ;; so simplify-rtx stops when it sees a second one. Under certain
10980 ;; conditions this is safe on x86, so help combine not create
10987 [(set (match_operand:QI 0 "nonimmediate_operand")
10988 (ne:QI (match_operator 1 "ix86_comparison_operator"
10989 [(reg FLAGS_REG) (const_int 0)])
10992 [(set (match_dup 0) (match_dup 1))]
10994 operands[1] = shallow_copy_rtx (operands[1]);
10995 PUT_MODE (operands[1], QImode);
10999 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11000 (ne:QI (match_operator 1 "ix86_comparison_operator"
11001 [(reg FLAGS_REG) (const_int 0)])
11004 [(set (match_dup 0) (match_dup 1))]
11006 operands[1] = shallow_copy_rtx (operands[1]);
11007 PUT_MODE (operands[1], QImode);
11011 [(set (match_operand:QI 0 "nonimmediate_operand")
11012 (eq:QI (match_operator 1 "ix86_comparison_operator"
11013 [(reg FLAGS_REG) (const_int 0)])
11016 [(set (match_dup 0) (match_dup 1))]
11018 operands[1] = shallow_copy_rtx (operands[1]);
11019 PUT_MODE (operands[1], QImode);
11020 PUT_CODE (operands[1],
11021 ix86_reverse_condition (GET_CODE (operands[1]),
11022 GET_MODE (XEXP (operands[1], 0))));
11024 /* Make sure that (a) the CCmode we have for the flags is strong
11025 enough for the reversed compare or (b) we have a valid FP compare. */
11026 if (! ix86_comparison_operator (operands[1], VOIDmode))
11031 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11032 (eq:QI (match_operator 1 "ix86_comparison_operator"
11033 [(reg FLAGS_REG) (const_int 0)])
11036 [(set (match_dup 0) (match_dup 1))]
11038 operands[1] = shallow_copy_rtx (operands[1]);
11039 PUT_MODE (operands[1], QImode);
11040 PUT_CODE (operands[1],
11041 ix86_reverse_condition (GET_CODE (operands[1]),
11042 GET_MODE (XEXP (operands[1], 0))));
11044 /* Make sure that (a) the CCmode we have for the flags is strong
11045 enough for the reversed compare or (b) we have a valid FP compare. */
11046 if (! ix86_comparison_operator (operands[1], VOIDmode))
11050 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
11051 ;; subsequent logical operations are used to imitate conditional moves.
11052 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
11055 (define_insn "setcc_<mode>_sse"
11056 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
11057 (match_operator:MODEF 3 "sse_comparison_operator"
11058 [(match_operand:MODEF 1 "register_operand" "0,x")
11059 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
11060 "SSE_FLOAT_MODE_P (<MODE>mode)"
11062 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
11063 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
11064 [(set_attr "isa" "noavx,avx")
11065 (set_attr "type" "ssecmp")
11066 (set_attr "length_immediate" "1")
11067 (set_attr "prefix" "orig,vex")
11068 (set_attr "mode" "<MODE>")])
11070 ;; Basic conditional jump instructions.
11071 ;; We ignore the overflow flag for signed branch instructions.
11073 (define_insn "*jcc_1"
11075 (if_then_else (match_operator 1 "ix86_comparison_operator"
11076 [(reg FLAGS_REG) (const_int 0)])
11077 (label_ref (match_operand 0))
11081 [(set_attr "type" "ibr")
11082 (set_attr "modrm" "0")
11083 (set (attr "length_nobnd")
11085 (and (ge (minus (match_dup 0) (pc))
11087 (lt (minus (match_dup 0) (pc))
11092 (define_insn "*jcc_2"
11094 (if_then_else (match_operator 1 "ix86_comparison_operator"
11095 [(reg FLAGS_REG) (const_int 0)])
11097 (label_ref (match_operand 0))))]
11100 [(set_attr "type" "ibr")
11101 (set_attr "modrm" "0")
11102 (set (attr "length_nobnd")
11104 (and (ge (minus (match_dup 0) (pc))
11106 (lt (minus (match_dup 0) (pc))
11111 ;; In general it is not safe to assume too much about CCmode registers,
11112 ;; so simplify-rtx stops when it sees a second one. Under certain
11113 ;; conditions this is safe on x86, so help combine not create
11121 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11122 [(reg FLAGS_REG) (const_int 0)])
11124 (label_ref (match_operand 1))
11128 (if_then_else (match_dup 0)
11129 (label_ref (match_dup 1))
11132 operands[0] = shallow_copy_rtx (operands[0]);
11133 PUT_MODE (operands[0], VOIDmode);
11138 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11139 [(reg FLAGS_REG) (const_int 0)])
11141 (label_ref (match_operand 1))
11145 (if_then_else (match_dup 0)
11146 (label_ref (match_dup 1))
11149 operands[0] = shallow_copy_rtx (operands[0]);
11150 PUT_MODE (operands[0], VOIDmode);
11151 PUT_CODE (operands[0],
11152 ix86_reverse_condition (GET_CODE (operands[0]),
11153 GET_MODE (XEXP (operands[0], 0))));
11155 /* Make sure that (a) the CCmode we have for the flags is strong
11156 enough for the reversed compare or (b) we have a valid FP compare. */
11157 if (! ix86_comparison_operator (operands[0], VOIDmode))
11161 ;; Define combination compare-and-branch fp compare instructions to help
11164 (define_insn "*jcc<mode>_0_i387"
11166 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11167 [(match_operand:X87MODEF 1 "register_operand" "f")
11168 (match_operand:X87MODEF 2 "const0_operand")])
11169 (label_ref (match_operand 3))
11171 (clobber (reg:CCFP FPSR_REG))
11172 (clobber (reg:CCFP FLAGS_REG))
11173 (clobber (match_scratch:HI 4 "=a"))]
11174 "TARGET_80387 && !TARGET_CMOVE"
11177 (define_insn "*jcc<mode>_0_r_i387"
11179 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11180 [(match_operand:X87MODEF 1 "register_operand" "f")
11181 (match_operand:X87MODEF 2 "const0_operand")])
11183 (label_ref (match_operand 3))))
11184 (clobber (reg:CCFP FPSR_REG))
11185 (clobber (reg:CCFP FLAGS_REG))
11186 (clobber (match_scratch:HI 4 "=a"))]
11187 "TARGET_80387 && !TARGET_CMOVE"
11190 (define_insn "*jccxf_i387"
11192 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11193 [(match_operand:XF 1 "register_operand" "f")
11194 (match_operand:XF 2 "register_operand" "f")])
11195 (label_ref (match_operand 3))
11197 (clobber (reg:CCFP FPSR_REG))
11198 (clobber (reg:CCFP FLAGS_REG))
11199 (clobber (match_scratch:HI 4 "=a"))]
11200 "TARGET_80387 && !TARGET_CMOVE"
11203 (define_insn "*jccxf_r_i387"
11205 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11206 [(match_operand:XF 1 "register_operand" "f")
11207 (match_operand:XF 2 "register_operand" "f")])
11209 (label_ref (match_operand 3))))
11210 (clobber (reg:CCFP FPSR_REG))
11211 (clobber (reg:CCFP FLAGS_REG))
11212 (clobber (match_scratch:HI 4 "=a"))]
11213 "TARGET_80387 && !TARGET_CMOVE"
11216 (define_insn "*jcc<mode>_i387"
11218 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11219 [(match_operand:MODEF 1 "register_operand" "f")
11220 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11221 (label_ref (match_operand 3))
11223 (clobber (reg:CCFP FPSR_REG))
11224 (clobber (reg:CCFP FLAGS_REG))
11225 (clobber (match_scratch:HI 4 "=a"))]
11226 "TARGET_80387 && !TARGET_CMOVE"
11229 (define_insn "*jcc<mode>_r_i387"
11231 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11232 [(match_operand:MODEF 1 "register_operand" "f")
11233 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11235 (label_ref (match_operand 3))))
11236 (clobber (reg:CCFP FPSR_REG))
11237 (clobber (reg:CCFP FLAGS_REG))
11238 (clobber (match_scratch:HI 4 "=a"))]
11239 "TARGET_80387 && !TARGET_CMOVE"
11242 (define_insn "*jccu<mode>_i387"
11244 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11245 [(match_operand:X87MODEF 1 "register_operand" "f")
11246 (match_operand:X87MODEF 2 "register_operand" "f")])
11247 (label_ref (match_operand 3))
11249 (clobber (reg:CCFP FPSR_REG))
11250 (clobber (reg:CCFP FLAGS_REG))
11251 (clobber (match_scratch:HI 4 "=a"))]
11252 "TARGET_80387 && !TARGET_CMOVE"
11255 (define_insn "*jccu<mode>_r_i387"
11257 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11258 [(match_operand:X87MODEF 1 "register_operand" "f")
11259 (match_operand:X87MODEF 2 "register_operand" "f")])
11261 (label_ref (match_operand 3))))
11262 (clobber (reg:CCFP FPSR_REG))
11263 (clobber (reg:CCFP FLAGS_REG))
11264 (clobber (match_scratch:HI 4 "=a"))]
11265 "TARGET_80387 && !TARGET_CMOVE"
11270 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11271 [(match_operand:X87MODEF 1 "register_operand")
11272 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11274 (match_operand 4)))
11275 (clobber (reg:CCFP FPSR_REG))
11276 (clobber (reg:CCFP FLAGS_REG))]
11277 "TARGET_80387 && !TARGET_CMOVE
11278 && reload_completed"
11281 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11282 operands[3], operands[4], NULL_RTX);
11288 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11289 [(match_operand:X87MODEF 1 "register_operand")
11290 (match_operand:X87MODEF 2 "general_operand")])
11292 (match_operand 4)))
11293 (clobber (reg:CCFP FPSR_REG))
11294 (clobber (reg:CCFP FLAGS_REG))
11295 (clobber (match_scratch:HI 5))]
11296 "TARGET_80387 && !TARGET_CMOVE
11297 && reload_completed"
11300 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11301 operands[3], operands[4], operands[5]);
11305 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11306 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11307 ;; with a precedence over other operators and is always put in the first
11308 ;; place. Swap condition and operands to match ficom instruction.
11310 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11313 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11314 [(match_operator:X87MODEF 1 "float_operator"
11315 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11316 (match_operand:X87MODEF 3 "register_operand" "f")])
11317 (label_ref (match_operand 4))
11319 (clobber (reg:CCFP FPSR_REG))
11320 (clobber (reg:CCFP FLAGS_REG))
11321 (clobber (match_scratch:HI 5 "=a"))]
11322 "TARGET_80387 && !TARGET_CMOVE
11323 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11324 || optimize_function_for_size_p (cfun))"
11327 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11330 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11331 [(match_operator:X87MODEF 1 "float_operator"
11332 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11333 (match_operand:X87MODEF 3 "register_operand" "f")])
11335 (label_ref (match_operand 4))))
11336 (clobber (reg:CCFP FPSR_REG))
11337 (clobber (reg:CCFP FLAGS_REG))
11338 (clobber (match_scratch:HI 5 "=a"))]
11339 "TARGET_80387 && !TARGET_CMOVE
11340 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11341 || optimize_function_for_size_p (cfun))"
11347 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11348 [(match_operator:X87MODEF 1 "float_operator"
11349 [(match_operand:SWI24 2 "memory_operand")])
11350 (match_operand:X87MODEF 3 "register_operand")])
11352 (match_operand 5)))
11353 (clobber (reg:CCFP FPSR_REG))
11354 (clobber (reg:CCFP FLAGS_REG))
11355 (clobber (match_scratch:HI 6))]
11356 "TARGET_80387 && !TARGET_CMOVE
11357 && reload_completed"
11360 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11361 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11362 operands[4], operands[5], operands[6]);
11366 ;; Unconditional and other jump instructions
11368 (define_insn "jump"
11370 (label_ref (match_operand 0)))]
11373 [(set_attr "type" "ibr")
11374 (set_attr "modrm" "0")
11375 (set (attr "length_nobnd")
11377 (and (ge (minus (match_dup 0) (pc))
11379 (lt (minus (match_dup 0) (pc))
11384 (define_expand "indirect_jump"
11385 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11389 operands[0] = convert_memory_address (word_mode, operands[0]);
11392 (define_insn "*indirect_jump"
11393 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11396 [(set_attr "type" "ibr")
11397 (set_attr "length_immediate" "0")])
11399 (define_expand "tablejump"
11400 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11401 (use (label_ref (match_operand 1)))])]
11404 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11405 relative. Convert the relative address to an absolute address. */
11409 enum rtx_code code;
11411 /* We can't use @GOTOFF for text labels on VxWorks;
11412 see gotoff_operand. */
11413 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11417 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11419 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11423 op1 = pic_offset_table_rtx;
11428 op0 = pic_offset_table_rtx;
11432 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11437 operands[0] = convert_memory_address (word_mode, operands[0]);
11440 (define_insn "*tablejump_1"
11441 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11442 (use (label_ref (match_operand 1)))]
11445 [(set_attr "type" "ibr")
11446 (set_attr "length_immediate" "0")])
11448 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11451 [(set (reg FLAGS_REG) (match_operand 0))
11452 (set (match_operand:QI 1 "register_operand")
11453 (match_operator:QI 2 "ix86_comparison_operator"
11454 [(reg FLAGS_REG) (const_int 0)]))
11455 (set (match_operand 3 "any_QIreg_operand")
11456 (zero_extend (match_dup 1)))]
11457 "(peep2_reg_dead_p (3, operands[1])
11458 || operands_match_p (operands[1], operands[3]))
11459 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11460 [(set (match_dup 4) (match_dup 0))
11461 (set (strict_low_part (match_dup 5))
11464 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11465 operands[5] = gen_lowpart (QImode, operands[3]);
11466 ix86_expand_clear (operands[3]);
11470 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11471 (match_operand 4)])
11472 (set (match_operand:QI 1 "register_operand")
11473 (match_operator:QI 2 "ix86_comparison_operator"
11474 [(reg FLAGS_REG) (const_int 0)]))
11475 (set (match_operand 3 "any_QIreg_operand")
11476 (zero_extend (match_dup 1)))]
11477 "(peep2_reg_dead_p (3, operands[1])
11478 || operands_match_p (operands[1], operands[3]))
11479 && ! reg_overlap_mentioned_p (operands[3], operands[0])
11480 && ! (GET_CODE (operands[4]) == CLOBBER
11481 && reg_mentioned_p (operands[3], operands[4]))"
11482 [(parallel [(set (match_dup 5) (match_dup 0))
11484 (set (strict_low_part (match_dup 6))
11487 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11488 operands[6] = gen_lowpart (QImode, operands[3]);
11489 ix86_expand_clear (operands[3]);
11492 ;; Similar, but match zero extend with andsi3.
11495 [(set (reg FLAGS_REG) (match_operand 0))
11496 (set (match_operand:QI 1 "register_operand")
11497 (match_operator:QI 2 "ix86_comparison_operator"
11498 [(reg FLAGS_REG) (const_int 0)]))
11499 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
11500 (and:SI (match_dup 3) (const_int 255)))
11501 (clobber (reg:CC FLAGS_REG))])]
11502 "REGNO (operands[1]) == REGNO (operands[3])
11503 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11504 [(set (match_dup 4) (match_dup 0))
11505 (set (strict_low_part (match_dup 5))
11508 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11509 operands[5] = gen_lowpart (QImode, operands[3]);
11510 ix86_expand_clear (operands[3]);
11514 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11515 (match_operand 4)])
11516 (set (match_operand:QI 1 "register_operand")
11517 (match_operator:QI 2 "ix86_comparison_operator"
11518 [(reg FLAGS_REG) (const_int 0)]))
11519 (parallel [(set (match_operand 3 "any_QIreg_operand")
11520 (zero_extend (match_dup 1)))
11521 (clobber (reg:CC FLAGS_REG))])]
11522 "(peep2_reg_dead_p (3, operands[1])
11523 || operands_match_p (operands[1], operands[3]))
11524 && ! reg_overlap_mentioned_p (operands[3], operands[0])
11525 && ! (GET_CODE (operands[4]) == CLOBBER
11526 && reg_mentioned_p (operands[3], operands[4]))"
11527 [(parallel [(set (match_dup 5) (match_dup 0))
11529 (set (strict_low_part (match_dup 6))
11532 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11533 operands[6] = gen_lowpart (QImode, operands[3]);
11534 ix86_expand_clear (operands[3]);
11537 ;; Call instructions.
11539 ;; The predicates normally associated with named expanders are not properly
11540 ;; checked for calls. This is a bug in the generic code, but it isn't that
11541 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11543 ;; P6 processors will jump to the address after the decrement when %esp
11544 ;; is used as a call operand, so they will execute return address as a code.
11545 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11547 ;; Register constraint for call instruction.
11548 (define_mode_attr c [(SI "l") (DI "r")])
11550 ;; Call subroutine returning no value.
11552 (define_expand "call"
11553 [(call (match_operand:QI 0)
11555 (use (match_operand 2))]
11558 ix86_expand_call (NULL, operands[0], operands[1],
11559 operands[2], NULL, false);
11563 (define_expand "sibcall"
11564 [(call (match_operand:QI 0)
11566 (use (match_operand 2))]
11569 ix86_expand_call (NULL, operands[0], operands[1],
11570 operands[2], NULL, true);
11574 (define_insn "*call"
11575 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11576 (match_operand 1))]
11577 "!SIBLING_CALL_P (insn)"
11578 "* return ix86_output_call_insn (insn, operands[0]);"
11579 [(set_attr "type" "call")])
11581 ;; This covers both call and sibcall since only GOT slot is allowed.
11582 (define_insn "*call_got_x32"
11583 [(call (mem:QI (zero_extend:DI
11584 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
11585 (match_operand 1))]
11587 "* return ix86_output_call_insn (insn, operands[0]);"
11588 [(set_attr "type" "call")])
11590 (define_insn "*sibcall"
11591 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11592 (match_operand 1))]
11593 "SIBLING_CALL_P (insn)"
11594 "* return ix86_output_call_insn (insn, operands[0]);"
11595 [(set_attr "type" "call")])
11597 (define_insn "*sibcall_memory"
11598 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11600 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11602 "* return ix86_output_call_insn (insn, operands[0]);"
11603 [(set_attr "type" "call")])
11606 [(set (match_operand:W 0 "register_operand")
11607 (match_operand:W 1 "memory_operand"))
11608 (call (mem:QI (match_dup 0))
11609 (match_operand 3))]
11610 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11611 && !reg_mentioned_p (operands[0],
11612 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
11613 [(parallel [(call (mem:QI (match_dup 1))
11615 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11618 [(set (match_operand:W 0 "register_operand")
11619 (match_operand:W 1 "memory_operand"))
11620 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11621 (call (mem:QI (match_dup 0))
11622 (match_operand 3))]
11623 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11624 && !reg_mentioned_p (operands[0],
11625 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
11626 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11627 (parallel [(call (mem:QI (match_dup 1))
11629 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11631 (define_expand "call_pop"
11632 [(parallel [(call (match_operand:QI 0)
11633 (match_operand:SI 1))
11634 (set (reg:SI SP_REG)
11635 (plus:SI (reg:SI SP_REG)
11636 (match_operand:SI 3)))])]
11639 ix86_expand_call (NULL, operands[0], operands[1],
11640 operands[2], operands[3], false);
11644 (define_insn "*call_pop"
11645 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
11647 (set (reg:SI SP_REG)
11648 (plus:SI (reg:SI SP_REG)
11649 (match_operand:SI 2 "immediate_operand" "i")))]
11650 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11651 "* return ix86_output_call_insn (insn, operands[0]);"
11652 [(set_attr "type" "call")])
11654 (define_insn "*sibcall_pop"
11655 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
11657 (set (reg:SI SP_REG)
11658 (plus:SI (reg:SI SP_REG)
11659 (match_operand:SI 2 "immediate_operand" "i")))]
11660 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11661 "* return ix86_output_call_insn (insn, operands[0]);"
11662 [(set_attr "type" "call")])
11664 (define_insn "*sibcall_pop_memory"
11665 [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
11667 (set (reg:SI SP_REG)
11668 (plus:SI (reg:SI SP_REG)
11669 (match_operand:SI 2 "immediate_operand" "i")))
11670 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11672 "* return ix86_output_call_insn (insn, operands[0]);"
11673 [(set_attr "type" "call")])
11676 [(set (match_operand:SI 0 "register_operand")
11677 (match_operand:SI 1 "memory_operand"))
11678 (parallel [(call (mem:QI (match_dup 0))
11680 (set (reg:SI SP_REG)
11681 (plus:SI (reg:SI SP_REG)
11682 (match_operand:SI 4 "immediate_operand")))])]
11683 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11684 && !reg_mentioned_p (operands[0],
11685 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
11686 [(parallel [(call (mem:QI (match_dup 1))
11688 (set (reg:SI SP_REG)
11689 (plus:SI (reg:SI SP_REG)
11691 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11694 [(set (match_operand:SI 0 "register_operand")
11695 (match_operand:SI 1 "memory_operand"))
11696 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11697 (parallel [(call (mem:QI (match_dup 0))
11699 (set (reg:SI SP_REG)
11700 (plus:SI (reg:SI SP_REG)
11701 (match_operand:SI 4 "immediate_operand")))])]
11702 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11703 && !reg_mentioned_p (operands[0],
11704 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
11705 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11706 (parallel [(call (mem:QI (match_dup 1))
11708 (set (reg:SI SP_REG)
11709 (plus:SI (reg:SI SP_REG)
11711 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11713 ;; Combining simple memory jump instruction
11716 [(set (match_operand:W 0 "register_operand")
11717 (match_operand:W 1 "memory_operand"))
11718 (set (pc) (match_dup 0))]
11719 "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
11720 [(set (pc) (match_dup 1))])
11722 ;; Call subroutine, returning value in operand 0
11724 (define_expand "call_value"
11725 [(set (match_operand 0)
11726 (call (match_operand:QI 1)
11727 (match_operand 2)))
11728 (use (match_operand 3))]
11731 ix86_expand_call (operands[0], operands[1], operands[2],
11732 operands[3], NULL, false);
11736 (define_expand "sibcall_value"
11737 [(set (match_operand 0)
11738 (call (match_operand:QI 1)
11739 (match_operand 2)))
11740 (use (match_operand 3))]
11743 ix86_expand_call (operands[0], operands[1], operands[2],
11744 operands[3], NULL, true);
11748 (define_insn "*call_value"
11749 [(set (match_operand 0)
11750 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
11751 (match_operand 2)))]
11752 "!SIBLING_CALL_P (insn)"
11753 "* return ix86_output_call_insn (insn, operands[1]);"
11754 [(set_attr "type" "callv")])
11756 ;; This covers both call and sibcall since only GOT slot is allowed.
11757 (define_insn "*call_value_got_x32"
11758 [(set (match_operand 0)
11761 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
11762 (match_operand 2)))]
11764 "* return ix86_output_call_insn (insn, operands[1]);"
11765 [(set_attr "type" "callv")])
11767 (define_insn "*sibcall_value"
11768 [(set (match_operand 0)
11769 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
11770 (match_operand 2)))]
11771 "SIBLING_CALL_P (insn)"
11772 "* return ix86_output_call_insn (insn, operands[1]);"
11773 [(set_attr "type" "callv")])
11775 (define_insn "*sibcall_value_memory"
11776 [(set (match_operand 0)
11777 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
11778 (match_operand 2)))
11779 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11781 "* return ix86_output_call_insn (insn, operands[1]);"
11782 [(set_attr "type" "callv")])
11785 [(set (match_operand:W 0 "register_operand")
11786 (match_operand:W 1 "memory_operand"))
11787 (set (match_operand 2)
11788 (call (mem:QI (match_dup 0))
11789 (match_operand 3)))]
11790 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11791 && !reg_mentioned_p (operands[0],
11792 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
11793 [(parallel [(set (match_dup 2)
11794 (call (mem:QI (match_dup 1))
11796 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11799 [(set (match_operand:W 0 "register_operand")
11800 (match_operand:W 1 "memory_operand"))
11801 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11802 (set (match_operand 2)
11803 (call (mem:QI (match_dup 0))
11804 (match_operand 3)))]
11805 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11806 && !reg_mentioned_p (operands[0],
11807 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
11808 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11809 (parallel [(set (match_dup 2)
11810 (call (mem:QI (match_dup 1))
11812 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11814 (define_expand "call_value_pop"
11815 [(parallel [(set (match_operand 0)
11816 (call (match_operand:QI 1)
11817 (match_operand:SI 2)))
11818 (set (reg:SI SP_REG)
11819 (plus:SI (reg:SI SP_REG)
11820 (match_operand:SI 4)))])]
11823 ix86_expand_call (operands[0], operands[1], operands[2],
11824 operands[3], operands[4], false);
11828 (define_insn "*call_value_pop"
11829 [(set (match_operand 0)
11830 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
11831 (match_operand 2)))
11832 (set (reg:SI SP_REG)
11833 (plus:SI (reg:SI SP_REG)
11834 (match_operand:SI 3 "immediate_operand" "i")))]
11835 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11836 "* return ix86_output_call_insn (insn, operands[1]);"
11837 [(set_attr "type" "callv")])
11839 (define_insn "*sibcall_value_pop"
11840 [(set (match_operand 0)
11841 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
11842 (match_operand 2)))
11843 (set (reg:SI SP_REG)
11844 (plus:SI (reg:SI SP_REG)
11845 (match_operand:SI 3 "immediate_operand" "i")))]
11846 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11847 "* return ix86_output_call_insn (insn, operands[1]);"
11848 [(set_attr "type" "callv")])
11850 (define_insn "*sibcall_value_pop_memory"
11851 [(set (match_operand 0)
11852 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
11853 (match_operand 2)))
11854 (set (reg:SI SP_REG)
11855 (plus:SI (reg:SI SP_REG)
11856 (match_operand:SI 3 "immediate_operand" "i")))
11857 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11859 "* return ix86_output_call_insn (insn, operands[1]);"
11860 [(set_attr "type" "callv")])
11863 [(set (match_operand:SI 0 "register_operand")
11864 (match_operand:SI 1 "memory_operand"))
11865 (parallel [(set (match_operand 2)
11866 (call (mem:QI (match_dup 0))
11867 (match_operand 3)))
11868 (set (reg:SI SP_REG)
11869 (plus:SI (reg:SI SP_REG)
11870 (match_operand:SI 4 "immediate_operand")))])]
11871 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11872 && !reg_mentioned_p (operands[0],
11873 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
11874 [(parallel [(set (match_dup 2)
11875 (call (mem:QI (match_dup 1))
11877 (set (reg:SI SP_REG)
11878 (plus:SI (reg:SI SP_REG)
11880 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11883 [(set (match_operand:SI 0 "register_operand")
11884 (match_operand:SI 1 "memory_operand"))
11885 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11886 (parallel [(set (match_operand 2)
11887 (call (mem:QI (match_dup 0))
11888 (match_operand 3)))
11889 (set (reg:SI SP_REG)
11890 (plus:SI (reg:SI SP_REG)
11891 (match_operand:SI 4 "immediate_operand")))])]
11892 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11893 && !reg_mentioned_p (operands[0],
11894 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
11895 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11896 (parallel [(set (match_dup 2)
11897 (call (mem:QI (match_dup 1))
11899 (set (reg:SI SP_REG)
11900 (plus:SI (reg:SI SP_REG)
11902 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11904 ;; Call subroutine returning any type.
11906 (define_expand "untyped_call"
11907 [(parallel [(call (match_operand 0)
11910 (match_operand 2)])]
11915 /* In order to give reg-stack an easier job in validating two
11916 coprocessor registers as containing a possible return value,
11917 simply pretend the untyped call returns a complex long double
11920 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11921 and should have the default ABI. */
11923 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11924 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11925 operands[0], const0_rtx,
11926 GEN_INT ((TARGET_64BIT
11927 ? (ix86_abi == SYSV_ABI
11928 ? X86_64_SSE_REGPARM_MAX
11929 : X86_64_MS_SSE_REGPARM_MAX)
11930 : X86_32_SSE_REGPARM_MAX)
11934 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11936 rtx set = XVECEXP (operands[2], 0, i);
11937 emit_move_insn (SET_DEST (set), SET_SRC (set));
11940 /* The optimizer does not know that the call sets the function value
11941 registers we stored in the result block. We avoid problems by
11942 claiming that all hard registers are used and clobbered at this
11944 emit_insn (gen_blockage ());
11949 ;; Prologue and epilogue instructions
11951 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11952 ;; all of memory. This blocks insns from being moved across this point.
11954 (define_insn "blockage"
11955 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11958 [(set_attr "length" "0")])
11960 ;; Do not schedule instructions accessing memory across this point.
11962 (define_expand "memory_blockage"
11963 [(set (match_dup 0)
11964 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11967 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11968 MEM_VOLATILE_P (operands[0]) = 1;
11971 (define_insn "*memory_blockage"
11972 [(set (match_operand:BLK 0)
11973 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11976 [(set_attr "length" "0")])
11978 ;; As USE insns aren't meaningful after reload, this is used instead
11979 ;; to prevent deleting instructions setting registers for PIC code
11980 (define_insn "prologue_use"
11981 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11984 [(set_attr "length" "0")])
11986 ;; Insn emitted into the body of a function to return from a function.
11987 ;; This is only done if the function's epilogue is known to be simple.
11988 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11990 (define_expand "return"
11992 "ix86_can_use_return_insn_p ()"
11994 if (crtl->args.pops_args)
11996 rtx popc = GEN_INT (crtl->args.pops_args);
11997 emit_jump_insn (gen_simple_return_pop_internal (popc));
12002 ;; We need to disable this for TARGET_SEH, as otherwise
12003 ;; shrink-wrapped prologue gets enabled too. This might exceed
12004 ;; the maximum size of prologue in unwind information.
12006 (define_expand "simple_return"
12010 if (crtl->args.pops_args)
12012 rtx popc = GEN_INT (crtl->args.pops_args);
12013 emit_jump_insn (gen_simple_return_pop_internal (popc));
12018 (define_insn "simple_return_internal"
12022 [(set_attr "length_nobnd" "1")
12023 (set_attr "atom_unit" "jeu")
12024 (set_attr "length_immediate" "0")
12025 (set_attr "modrm" "0")])
12027 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12028 ;; instruction Athlon and K8 have.
12030 (define_insn "simple_return_internal_long"
12032 (unspec [(const_int 0)] UNSPEC_REP)]
12035 if (ix86_bnd_prefixed_insn_p (insn))
12038 return "rep%; ret";
12040 [(set_attr "length" "2")
12041 (set_attr "atom_unit" "jeu")
12042 (set_attr "length_immediate" "0")
12043 (set_attr "prefix_rep" "1")
12044 (set_attr "modrm" "0")])
12046 (define_insn "simple_return_pop_internal"
12048 (use (match_operand:SI 0 "const_int_operand"))]
12051 [(set_attr "length_nobnd" "3")
12052 (set_attr "atom_unit" "jeu")
12053 (set_attr "length_immediate" "2")
12054 (set_attr "modrm" "0")])
12056 (define_insn "simple_return_indirect_internal"
12058 (use (match_operand:SI 0 "register_operand" "r"))]
12061 [(set_attr "type" "ibr")
12062 (set_attr "length_immediate" "0")])
12068 [(set_attr "length" "1")
12069 (set_attr "length_immediate" "0")
12070 (set_attr "modrm" "0")])
12072 ;; Generate nops. Operand 0 is the number of nops, up to 8.
12073 (define_insn "nops"
12074 [(unspec_volatile [(match_operand 0 "const_int_operand")]
12078 int num = INTVAL (operands[0]);
12080 gcc_assert (IN_RANGE (num, 1, 8));
12083 fputs ("\tnop\n", asm_out_file);
12087 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12088 (set_attr "length_immediate" "0")
12089 (set_attr "modrm" "0")])
12091 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12092 ;; branch prediction penalty for the third jump in a 16-byte
12096 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12099 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12100 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12102 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12103 The align insn is used to avoid 3 jump instructions in the row to improve
12104 branch prediction and the benefits hardly outweigh the cost of extra 8
12105 nops on the average inserted by full alignment pseudo operation. */
12109 [(set_attr "length" "16")])
12111 (define_expand "prologue"
12114 "ix86_expand_prologue (); DONE;")
12116 (define_insn "set_got"
12117 [(set (match_operand:SI 0 "register_operand" "=r")
12118 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12119 (clobber (reg:CC FLAGS_REG))]
12121 "* return output_set_got (operands[0], NULL_RTX);"
12122 [(set_attr "type" "multi")
12123 (set_attr "length" "12")])
12125 (define_insn "set_got_labelled"
12126 [(set (match_operand:SI 0 "register_operand" "=r")
12127 (unspec:SI [(label_ref (match_operand 1))]
12129 (clobber (reg:CC FLAGS_REG))]
12131 "* return output_set_got (operands[0], operands[1]);"
12132 [(set_attr "type" "multi")
12133 (set_attr "length" "12")])
12135 (define_insn "set_got_rex64"
12136 [(set (match_operand:DI 0 "register_operand" "=r")
12137 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12139 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12140 [(set_attr "type" "lea")
12141 (set_attr "length_address" "4")
12142 (set_attr "mode" "DI")])
12144 (define_insn "set_rip_rex64"
12145 [(set (match_operand:DI 0 "register_operand" "=r")
12146 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12148 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12149 [(set_attr "type" "lea")
12150 (set_attr "length_address" "4")
12151 (set_attr "mode" "DI")])
12153 (define_insn "set_got_offset_rex64"
12154 [(set (match_operand:DI 0 "register_operand" "=r")
12156 [(label_ref (match_operand 1))]
12157 UNSPEC_SET_GOT_OFFSET))]
12159 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12160 [(set_attr "type" "imov")
12161 (set_attr "length_immediate" "0")
12162 (set_attr "length_address" "8")
12163 (set_attr "mode" "DI")])
12165 (define_expand "epilogue"
12168 "ix86_expand_epilogue (1); DONE;")
12170 (define_expand "sibcall_epilogue"
12173 "ix86_expand_epilogue (0); DONE;")
12175 (define_expand "eh_return"
12176 [(use (match_operand 0 "register_operand"))]
12179 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12181 /* Tricky bit: we write the address of the handler to which we will
12182 be returning into someone else's stack frame, one word below the
12183 stack address we wish to restore. */
12184 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12185 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12186 tmp = gen_rtx_MEM (Pmode, tmp);
12187 emit_move_insn (tmp, ra);
12189 emit_jump_insn (gen_eh_return_internal ());
12194 (define_insn_and_split "eh_return_internal"
12198 "epilogue_completed"
12200 "ix86_expand_epilogue (2); DONE;")
12202 (define_insn "leave"
12203 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12204 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12205 (clobber (mem:BLK (scratch)))]
12208 [(set_attr "type" "leave")])
12210 (define_insn "leave_rex64"
12211 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12212 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12213 (clobber (mem:BLK (scratch)))]
12216 [(set_attr "type" "leave")])
12218 ;; Handle -fsplit-stack.
12220 (define_expand "split_stack_prologue"
12224 ix86_expand_split_stack_prologue ();
12228 ;; In order to support the call/return predictor, we use a return
12229 ;; instruction which the middle-end doesn't see.
12230 (define_insn "split_stack_return"
12231 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12232 UNSPECV_SPLIT_STACK_RETURN)]
12235 if (operands[0] == const0_rtx)
12240 [(set_attr "atom_unit" "jeu")
12241 (set_attr "modrm" "0")
12242 (set (attr "length")
12243 (if_then_else (match_operand:SI 0 "const0_operand")
12246 (set (attr "length_immediate")
12247 (if_then_else (match_operand:SI 0 "const0_operand")
12251 ;; If there are operand 0 bytes available on the stack, jump to
12254 (define_expand "split_stack_space_check"
12255 [(set (pc) (if_then_else
12256 (ltu (minus (reg SP_REG)
12257 (match_operand 0 "register_operand"))
12258 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12259 (label_ref (match_operand 1))
12263 rtx reg, size, limit;
12265 reg = gen_reg_rtx (Pmode);
12266 size = force_reg (Pmode, operands[0]);
12267 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12268 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12269 UNSPEC_STACK_CHECK);
12270 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12271 ix86_expand_branch (GEU, reg, limit, operands[1]);
12276 ;; Bit manipulation instructions.
12278 (define_expand "ffs<mode>2"
12279 [(set (match_dup 2) (const_int -1))
12280 (parallel [(set (match_dup 3) (match_dup 4))
12281 (set (match_operand:SWI48 0 "register_operand")
12283 (match_operand:SWI48 1 "nonimmediate_operand")))])
12284 (set (match_dup 0) (if_then_else:SWI48
12285 (eq (match_dup 3) (const_int 0))
12288 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12289 (clobber (reg:CC FLAGS_REG))])]
12292 machine_mode flags_mode;
12294 if (<MODE>mode == SImode && !TARGET_CMOVE)
12296 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12301 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12303 operands[2] = gen_reg_rtx (<MODE>mode);
12304 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12305 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12308 (define_insn_and_split "ffssi2_no_cmove"
12309 [(set (match_operand:SI 0 "register_operand" "=r")
12310 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12311 (clobber (match_scratch:SI 2 "=&q"))
12312 (clobber (reg:CC FLAGS_REG))]
12315 "&& reload_completed"
12316 [(parallel [(set (match_dup 4) (match_dup 5))
12317 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12318 (set (strict_low_part (match_dup 3))
12319 (eq:QI (match_dup 4) (const_int 0)))
12320 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12321 (clobber (reg:CC FLAGS_REG))])
12322 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12323 (clobber (reg:CC FLAGS_REG))])
12324 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12325 (clobber (reg:CC FLAGS_REG))])]
12327 machine_mode flags_mode
12328 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12330 operands[3] = gen_lowpart (QImode, operands[2]);
12331 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12332 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12334 ix86_expand_clear (operands[2]);
12337 (define_insn "*tzcnt<mode>_1"
12338 [(set (reg:CCC FLAGS_REG)
12339 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12341 (set (match_operand:SWI48 0 "register_operand" "=r")
12342 (ctz:SWI48 (match_dup 1)))]
12343 "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
12344 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12345 [(set_attr "type" "alu1")
12346 (set_attr "prefix_0f" "1")
12347 (set_attr "prefix_rep" "1")
12348 (set_attr "btver2_decode" "double")
12349 (set_attr "mode" "<MODE>")])
12351 (define_insn "*bsf<mode>_1"
12352 [(set (reg:CCZ FLAGS_REG)
12353 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12355 (set (match_operand:SWI48 0 "register_operand" "=r")
12356 (ctz:SWI48 (match_dup 1)))]
12358 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12359 [(set_attr "type" "alu1")
12360 (set_attr "prefix_0f" "1")
12361 (set_attr "btver2_decode" "double")
12362 (set_attr "mode" "<MODE>")])
12364 (define_expand "ctz<mode>2"
12366 [(set (match_operand:SWI248 0 "register_operand")
12368 (match_operand:SWI248 1 "nonimmediate_operand")))
12369 (clobber (reg:CC FLAGS_REG))])])
12371 ; False dependency happens when destination is only updated by tzcnt,
12372 ; lzcnt or popcnt. There is no false dependency when destination is
12373 ; also used in source.
12374 (define_insn_and_split "*ctz<mode>2_falsedep_1"
12375 [(set (match_operand:SWI48 0 "register_operand" "=r")
12377 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12378 (clobber (reg:CC FLAGS_REG))]
12379 "(TARGET_BMI || TARGET_GENERIC)
12380 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12382 "&& reload_completed"
12384 [(set (match_dup 0)
12385 (ctz:SWI48 (match_dup 1)))
12386 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12387 (clobber (reg:CC FLAGS_REG))])]
12389 if (!reg_mentioned_p (operands[0], operands[1]))
12390 ix86_expand_clear (operands[0]);
12393 (define_insn "*ctz<mode>2_falsedep"
12394 [(set (match_operand:SWI48 0 "register_operand" "=r")
12396 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12397 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12398 UNSPEC_INSN_FALSE_DEP)
12399 (clobber (reg:CC FLAGS_REG))]
12403 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12404 else if (TARGET_GENERIC)
12405 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12406 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12408 gcc_unreachable ();
12410 [(set_attr "type" "alu1")
12411 (set_attr "prefix_0f" "1")
12412 (set_attr "prefix_rep" "1")
12413 (set_attr "mode" "<MODE>")])
12415 (define_insn "*ctz<mode>2"
12416 [(set (match_operand:SWI248 0 "register_operand" "=r")
12417 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12418 (clobber (reg:CC FLAGS_REG))]
12422 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12423 else if (optimize_function_for_size_p (cfun))
12425 else if (TARGET_GENERIC)
12426 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12427 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12429 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12431 [(set_attr "type" "alu1")
12432 (set_attr "prefix_0f" "1")
12433 (set (attr "prefix_rep")
12435 (ior (match_test "TARGET_BMI")
12436 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12437 (match_test "TARGET_GENERIC")))
12439 (const_string "0")))
12440 (set_attr "mode" "<MODE>")])
12442 (define_expand "clz<mode>2"
12444 [(set (match_operand:SWI248 0 "register_operand")
12447 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12448 (clobber (reg:CC FLAGS_REG))])
12450 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12451 (clobber (reg:CC FLAGS_REG))])]
12456 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12459 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12462 (define_expand "clz<mode>2_lzcnt"
12464 [(set (match_operand:SWI248 0 "register_operand")
12466 (match_operand:SWI248 1 "nonimmediate_operand")))
12467 (clobber (reg:CC FLAGS_REG))])]
12470 (define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
12471 [(set (match_operand:SWI48 0 "register_operand" "=r")
12473 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12474 (clobber (reg:CC FLAGS_REG))]
12476 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12478 "&& reload_completed"
12480 [(set (match_dup 0)
12481 (clz:SWI48 (match_dup 1)))
12482 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12483 (clobber (reg:CC FLAGS_REG))])]
12485 if (!reg_mentioned_p (operands[0], operands[1]))
12486 ix86_expand_clear (operands[0]);
12489 (define_insn "*clz<mode>2_lzcnt_falsedep"
12490 [(set (match_operand:SWI48 0 "register_operand" "=r")
12492 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12493 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12494 UNSPEC_INSN_FALSE_DEP)
12495 (clobber (reg:CC FLAGS_REG))]
12497 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12498 [(set_attr "prefix_rep" "1")
12499 (set_attr "type" "bitmanip")
12500 (set_attr "mode" "<MODE>")])
12502 (define_insn "*clz<mode>2_lzcnt"
12503 [(set (match_operand:SWI248 0 "register_operand" "=r")
12504 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12505 (clobber (reg:CC FLAGS_REG))]
12507 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12508 [(set_attr "prefix_rep" "1")
12509 (set_attr "type" "bitmanip")
12510 (set_attr "mode" "<MODE>")])
12512 ;; BMI instructions.
12513 (define_insn "*bmi_andn_<mode>"
12514 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12516 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
12517 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12518 (clobber (reg:CC FLAGS_REG))]
12520 "andn\t{%2, %1, %0|%0, %1, %2}"
12521 [(set_attr "type" "bitmanip")
12522 (set_attr "btver2_decode" "direct, double")
12523 (set_attr "mode" "<MODE>")])
12525 (define_insn "*bmi_andn_<mode>_ccno"
12526 [(set (reg FLAGS_REG)
12529 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
12530 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
12532 (clobber (match_scratch:SWI48 0 "=r,r"))]
12533 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
12534 "andn\t{%2, %1, %0|%0, %1, %2}"
12535 [(set_attr "type" "bitmanip")
12536 (set_attr "btver2_decode" "direct, double")
12537 (set_attr "mode" "<MODE>")])
12539 (define_insn "bmi_bextr_<mode>"
12540 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12541 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12542 (match_operand:SWI48 2 "register_operand" "r,r")]
12544 (clobber (reg:CC FLAGS_REG))]
12546 "bextr\t{%2, %1, %0|%0, %1, %2}"
12547 [(set_attr "type" "bitmanip")
12548 (set_attr "btver2_decode" "direct, double")
12549 (set_attr "mode" "<MODE>")])
12551 (define_insn "*bmi_bextr_<mode>_ccz"
12552 [(set (reg:CCZ FLAGS_REG)
12554 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12555 (match_operand:SWI48 2 "register_operand" "r,r")]
12558 (clobber (match_scratch:SWI48 0 "=r,r"))]
12560 "bextr\t{%2, %1, %0|%0, %1, %2}"
12561 [(set_attr "type" "bitmanip")
12562 (set_attr "btver2_decode" "direct, double")
12563 (set_attr "mode" "<MODE>")])
12565 (define_insn "*bmi_blsi_<mode>"
12566 [(set (match_operand:SWI48 0 "register_operand" "=r")
12569 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12571 (clobber (reg:CC FLAGS_REG))]
12573 "blsi\t{%1, %0|%0, %1}"
12574 [(set_attr "type" "bitmanip")
12575 (set_attr "btver2_decode" "double")
12576 (set_attr "mode" "<MODE>")])
12578 (define_insn "*bmi_blsmsk_<mode>"
12579 [(set (match_operand:SWI48 0 "register_operand" "=r")
12582 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12585 (clobber (reg:CC FLAGS_REG))]
12587 "blsmsk\t{%1, %0|%0, %1}"
12588 [(set_attr "type" "bitmanip")
12589 (set_attr "btver2_decode" "double")
12590 (set_attr "mode" "<MODE>")])
12592 (define_insn "*bmi_blsr_<mode>"
12593 [(set (match_operand:SWI48 0 "register_operand" "=r")
12596 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12599 (clobber (reg:CC FLAGS_REG))]
12601 "blsr\t{%1, %0|%0, %1}"
12602 [(set_attr "type" "bitmanip")
12603 (set_attr "btver2_decode" "double")
12604 (set_attr "mode" "<MODE>")])
12606 ;; BMI2 instructions.
12607 (define_expand "bmi2_bzhi_<mode>3"
12609 [(set (match_operand:SWI48 0 "register_operand")
12610 (zero_extract:SWI48
12611 (match_operand:SWI48 1 "nonimmediate_operand")
12613 (and:SWI48 (match_operand:SWI48 2 "register_operand")
12617 (clobber (reg:CC FLAGS_REG))])]
12619 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
12621 (define_insn "*bmi2_bzhi_<mode>3"
12622 [(set (match_operand:SWI48 0 "register_operand" "=r")
12623 (zero_extract:SWI48
12624 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12626 (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
12628 (match_operand:SWI48 3 "const_int_operand" "n"))
12630 (clobber (reg:CC FLAGS_REG))]
12631 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12632 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12633 [(set_attr "type" "bitmanip")
12634 (set_attr "prefix" "vex")
12635 (set_attr "mode" "<MODE>")])
12637 (define_mode_attr k [(SI "k") (DI "q")])
12639 (define_insn "*bmi2_bzhi_<mode>3_1"
12640 [(set (match_operand:SWI48 0 "register_operand" "=r")
12641 (zero_extract:SWI48
12642 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12644 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
12645 (match_operand:SWI48 3 "const_int_operand" "n"))
12647 (clobber (reg:CC FLAGS_REG))]
12648 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12649 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
12650 [(set_attr "type" "bitmanip")
12651 (set_attr "prefix" "vex")
12652 (set_attr "mode" "<MODE>")])
12654 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
12655 [(set (reg:CCZ FLAGS_REG)
12657 (zero_extract:SWI48
12658 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12660 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
12661 (match_operand:SWI48 3 "const_int_operand" "n"))
12664 (clobber (match_scratch:SWI48 0 "=r"))]
12665 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12666 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
12667 [(set_attr "type" "bitmanip")
12668 (set_attr "prefix" "vex")
12669 (set_attr "mode" "<MODE>")])
12671 (define_insn "bmi2_pdep_<mode>3"
12672 [(set (match_operand:SWI48 0 "register_operand" "=r")
12673 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12674 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12677 "pdep\t{%2, %1, %0|%0, %1, %2}"
12678 [(set_attr "type" "bitmanip")
12679 (set_attr "prefix" "vex")
12680 (set_attr "mode" "<MODE>")])
12682 (define_insn "bmi2_pext_<mode>3"
12683 [(set (match_operand:SWI48 0 "register_operand" "=r")
12684 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12685 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12688 "pext\t{%2, %1, %0|%0, %1, %2}"
12689 [(set_attr "type" "bitmanip")
12690 (set_attr "prefix" "vex")
12691 (set_attr "mode" "<MODE>")])
12693 ;; TBM instructions.
12694 (define_insn "tbm_bextri_<mode>"
12695 [(set (match_operand:SWI48 0 "register_operand" "=r")
12696 (zero_extract:SWI48
12697 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12698 (match_operand 2 "const_0_to_255_operand" "N")
12699 (match_operand 3 "const_0_to_255_operand" "N")))
12700 (clobber (reg:CC FLAGS_REG))]
12703 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12704 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12706 [(set_attr "type" "bitmanip")
12707 (set_attr "mode" "<MODE>")])
12709 (define_insn "*tbm_blcfill_<mode>"
12710 [(set (match_operand:SWI48 0 "register_operand" "=r")
12713 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12716 (clobber (reg:CC FLAGS_REG))]
12718 "blcfill\t{%1, %0|%0, %1}"
12719 [(set_attr "type" "bitmanip")
12720 (set_attr "mode" "<MODE>")])
12722 (define_insn "*tbm_blci_<mode>"
12723 [(set (match_operand:SWI48 0 "register_operand" "=r")
12727 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12730 (clobber (reg:CC FLAGS_REG))]
12732 "blci\t{%1, %0|%0, %1}"
12733 [(set_attr "type" "bitmanip")
12734 (set_attr "mode" "<MODE>")])
12736 (define_insn "*tbm_blcic_<mode>"
12737 [(set (match_operand:SWI48 0 "register_operand" "=r")
12740 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12744 (clobber (reg:CC FLAGS_REG))]
12746 "blcic\t{%1, %0|%0, %1}"
12747 [(set_attr "type" "bitmanip")
12748 (set_attr "mode" "<MODE>")])
12750 (define_insn "*tbm_blcmsk_<mode>"
12751 [(set (match_operand:SWI48 0 "register_operand" "=r")
12754 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12757 (clobber (reg:CC FLAGS_REG))]
12759 "blcmsk\t{%1, %0|%0, %1}"
12760 [(set_attr "type" "bitmanip")
12761 (set_attr "mode" "<MODE>")])
12763 (define_insn "*tbm_blcs_<mode>"
12764 [(set (match_operand:SWI48 0 "register_operand" "=r")
12767 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12770 (clobber (reg:CC FLAGS_REG))]
12772 "blcs\t{%1, %0|%0, %1}"
12773 [(set_attr "type" "bitmanip")
12774 (set_attr "mode" "<MODE>")])
12776 (define_insn "*tbm_blsfill_<mode>"
12777 [(set (match_operand:SWI48 0 "register_operand" "=r")
12780 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12783 (clobber (reg:CC FLAGS_REG))]
12785 "blsfill\t{%1, %0|%0, %1}"
12786 [(set_attr "type" "bitmanip")
12787 (set_attr "mode" "<MODE>")])
12789 (define_insn "*tbm_blsic_<mode>"
12790 [(set (match_operand:SWI48 0 "register_operand" "=r")
12793 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12797 (clobber (reg:CC FLAGS_REG))]
12799 "blsic\t{%1, %0|%0, %1}"
12800 [(set_attr "type" "bitmanip")
12801 (set_attr "mode" "<MODE>")])
12803 (define_insn "*tbm_t1mskc_<mode>"
12804 [(set (match_operand:SWI48 0 "register_operand" "=r")
12807 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12811 (clobber (reg:CC FLAGS_REG))]
12813 "t1mskc\t{%1, %0|%0, %1}"
12814 [(set_attr "type" "bitmanip")
12815 (set_attr "mode" "<MODE>")])
12817 (define_insn "*tbm_tzmsk_<mode>"
12818 [(set (match_operand:SWI48 0 "register_operand" "=r")
12821 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12825 (clobber (reg:CC FLAGS_REG))]
12827 "tzmsk\t{%1, %0|%0, %1}"
12828 [(set_attr "type" "bitmanip")
12829 (set_attr "mode" "<MODE>")])
12831 (define_insn "bsr_rex64"
12832 [(set (match_operand:DI 0 "register_operand" "=r")
12833 (minus:DI (const_int 63)
12834 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12835 (clobber (reg:CC FLAGS_REG))]
12837 "bsr{q}\t{%1, %0|%0, %1}"
12838 [(set_attr "type" "alu1")
12839 (set_attr "prefix_0f" "1")
12840 (set_attr "mode" "DI")])
12843 [(set (match_operand:SI 0 "register_operand" "=r")
12844 (minus:SI (const_int 31)
12845 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12846 (clobber (reg:CC FLAGS_REG))]
12848 "bsr{l}\t{%1, %0|%0, %1}"
12849 [(set_attr "type" "alu1")
12850 (set_attr "prefix_0f" "1")
12851 (set_attr "mode" "SI")])
12853 (define_insn "*bsrhi"
12854 [(set (match_operand:HI 0 "register_operand" "=r")
12855 (minus:HI (const_int 15)
12856 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12857 (clobber (reg:CC FLAGS_REG))]
12859 "bsr{w}\t{%1, %0|%0, %1}"
12860 [(set_attr "type" "alu1")
12861 (set_attr "prefix_0f" "1")
12862 (set_attr "mode" "HI")])
12864 (define_expand "popcount<mode>2"
12866 [(set (match_operand:SWI248 0 "register_operand")
12868 (match_operand:SWI248 1 "nonimmediate_operand")))
12869 (clobber (reg:CC FLAGS_REG))])]
12872 (define_insn_and_split "*popcount<mode>2_falsedep_1"
12873 [(set (match_operand:SWI48 0 "register_operand" "=r")
12875 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12876 (clobber (reg:CC FLAGS_REG))]
12878 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12880 "&& reload_completed"
12882 [(set (match_dup 0)
12883 (popcount:SWI48 (match_dup 1)))
12884 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12885 (clobber (reg:CC FLAGS_REG))])]
12887 if (!reg_mentioned_p (operands[0], operands[1]))
12888 ix86_expand_clear (operands[0]);
12891 (define_insn "*popcount<mode>2_falsedep"
12892 [(set (match_operand:SWI48 0 "register_operand" "=r")
12894 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12895 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12896 UNSPEC_INSN_FALSE_DEP)
12897 (clobber (reg:CC FLAGS_REG))]
12901 return "popcnt\t{%1, %0|%0, %1}";
12903 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12906 [(set_attr "prefix_rep" "1")
12907 (set_attr "type" "bitmanip")
12908 (set_attr "mode" "<MODE>")])
12910 (define_insn "*popcount<mode>2"
12911 [(set (match_operand:SWI248 0 "register_operand" "=r")
12913 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12914 (clobber (reg:CC FLAGS_REG))]
12918 return "popcnt\t{%1, %0|%0, %1}";
12920 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12923 [(set_attr "prefix_rep" "1")
12924 (set_attr "type" "bitmanip")
12925 (set_attr "mode" "<MODE>")])
12927 (define_expand "bswapdi2"
12928 [(set (match_operand:DI 0 "register_operand")
12929 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12933 operands[1] = force_reg (DImode, operands[1]);
12936 (define_expand "bswapsi2"
12937 [(set (match_operand:SI 0 "register_operand")
12938 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12943 else if (TARGET_BSWAP)
12944 operands[1] = force_reg (SImode, operands[1]);
12947 rtx x = operands[0];
12949 emit_move_insn (x, operands[1]);
12950 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12951 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12952 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12957 (define_insn "*bswap<mode>2_movbe"
12958 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12959 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12961 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12964 movbe\t{%1, %0|%0, %1}
12965 movbe\t{%1, %0|%0, %1}"
12966 [(set_attr "type" "bitmanip,imov,imov")
12967 (set_attr "modrm" "0,1,1")
12968 (set_attr "prefix_0f" "*,1,1")
12969 (set_attr "prefix_extra" "*,1,1")
12970 (set_attr "mode" "<MODE>")])
12972 (define_insn "*bswap<mode>2"
12973 [(set (match_operand:SWI48 0 "register_operand" "=r")
12974 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12977 [(set_attr "type" "bitmanip")
12978 (set_attr "modrm" "0")
12979 (set_attr "mode" "<MODE>")])
12981 (define_insn "*bswaphi_lowpart_1"
12982 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12983 (bswap:HI (match_dup 0)))
12984 (clobber (reg:CC FLAGS_REG))]
12985 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12987 xchg{b}\t{%h0, %b0|%b0, %h0}
12988 rol{w}\t{$8, %0|%0, 8}"
12989 [(set_attr "length" "2,4")
12990 (set_attr "mode" "QI,HI")])
12992 (define_insn "bswaphi_lowpart"
12993 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12994 (bswap:HI (match_dup 0)))
12995 (clobber (reg:CC FLAGS_REG))]
12997 "rol{w}\t{$8, %0|%0, 8}"
12998 [(set_attr "length" "4")
12999 (set_attr "mode" "HI")])
13001 (define_expand "paritydi2"
13002 [(set (match_operand:DI 0 "register_operand")
13003 (parity:DI (match_operand:DI 1 "register_operand")))]
13006 rtx scratch = gen_reg_rtx (QImode);
13009 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
13010 NULL_RTX, operands[1]));
13012 cond = gen_rtx_fmt_ee (ORDERED, QImode,
13013 gen_rtx_REG (CCmode, FLAGS_REG),
13015 emit_insn (gen_rtx_SET (scratch, cond));
13018 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
13021 rtx tmp = gen_reg_rtx (SImode);
13023 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
13024 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
13029 (define_expand "paritysi2"
13030 [(set (match_operand:SI 0 "register_operand")
13031 (parity:SI (match_operand:SI 1 "register_operand")))]
13034 rtx scratch = gen_reg_rtx (QImode);
13037 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
13039 cond = gen_rtx_fmt_ee (ORDERED, QImode,
13040 gen_rtx_REG (CCmode, FLAGS_REG),
13042 emit_insn (gen_rtx_SET (scratch, cond));
13044 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
13048 (define_insn_and_split "paritydi2_cmp"
13049 [(set (reg:CC FLAGS_REG)
13050 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
13052 (clobber (match_scratch:DI 0 "=r"))
13053 (clobber (match_scratch:SI 1 "=&r"))
13054 (clobber (match_scratch:HI 2 "=Q"))]
13057 "&& reload_completed"
13059 [(set (match_dup 1)
13060 (xor:SI (match_dup 1) (match_dup 4)))
13061 (clobber (reg:CC FLAGS_REG))])
13063 [(set (reg:CC FLAGS_REG)
13064 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13065 (clobber (match_dup 1))
13066 (clobber (match_dup 2))])]
13068 operands[4] = gen_lowpart (SImode, operands[3]);
13072 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
13073 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
13076 operands[1] = gen_highpart (SImode, operands[3]);
13079 (define_insn_and_split "paritysi2_cmp"
13080 [(set (reg:CC FLAGS_REG)
13081 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
13083 (clobber (match_scratch:SI 0 "=r"))
13084 (clobber (match_scratch:HI 1 "=&Q"))]
13087 "&& reload_completed"
13089 [(set (match_dup 1)
13090 (xor:HI (match_dup 1) (match_dup 3)))
13091 (clobber (reg:CC FLAGS_REG))])
13093 [(set (reg:CC FLAGS_REG)
13094 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13095 (clobber (match_dup 1))])]
13097 operands[3] = gen_lowpart (HImode, operands[2]);
13099 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
13100 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
13103 (define_insn "*parityhi2_cmp"
13104 [(set (reg:CC FLAGS_REG)
13105 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
13107 (clobber (match_scratch:HI 0 "=Q"))]
13109 "xor{b}\t{%h0, %b0|%b0, %h0}"
13110 [(set_attr "length" "2")
13111 (set_attr "mode" "HI")])
13114 ;; Thread-local storage patterns for ELF.
13116 ;; Note that these code sequences must appear exactly as shown
13117 ;; in order to allow linker relaxation.
13119 (define_insn "*tls_global_dynamic_32_gnu"
13120 [(set (match_operand:SI 0 "register_operand" "=a")
13122 [(match_operand:SI 1 "register_operand" "b")
13123 (match_operand 2 "tls_symbolic_operand")
13124 (match_operand 3 "constant_call_address_operand" "Bz")
13127 (clobber (match_scratch:SI 4 "=d"))
13128 (clobber (match_scratch:SI 5 "=c"))
13129 (clobber (reg:CC FLAGS_REG))]
13130 "!TARGET_64BIT && TARGET_GNU_TLS"
13133 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
13134 if (TARGET_SUN_TLS)
13135 #ifdef HAVE_AS_IX86_TLSGDPLT
13136 return "call\t%a2@tlsgdplt";
13138 return "call\t%p3@plt";
13140 return "call\t%P3";
13142 [(set_attr "type" "multi")
13143 (set_attr "length" "12")])
13145 (define_expand "tls_global_dynamic_32"
13147 [(set (match_operand:SI 0 "register_operand")
13148 (unspec:SI [(match_operand:SI 2 "register_operand")
13149 (match_operand 1 "tls_symbolic_operand")
13150 (match_operand 3 "constant_call_address_operand")
13153 (clobber (match_scratch:SI 4))
13154 (clobber (match_scratch:SI 5))
13155 (clobber (reg:CC FLAGS_REG))])]
13157 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13159 (define_insn "*tls_global_dynamic_64_<mode>"
13160 [(set (match_operand:P 0 "register_operand" "=a")
13162 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
13163 (match_operand 3)))
13164 (unspec:P [(match_operand 1 "tls_symbolic_operand")
13170 fputs (ASM_BYTE "0x66\n", asm_out_file);
13172 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13173 fputs (ASM_SHORT "0x6666\n", asm_out_file);
13174 fputs ("\trex64\n", asm_out_file);
13175 if (TARGET_SUN_TLS)
13176 return "call\t%p2@plt";
13177 return "call\t%P2";
13179 [(set_attr "type" "multi")
13180 (set (attr "length")
13181 (symbol_ref "TARGET_X32 ? 15 : 16"))])
13183 (define_insn "*tls_global_dynamic_64_largepic"
13184 [(set (match_operand:DI 0 "register_operand" "=a")
13186 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
13187 (match_operand:DI 3 "immediate_operand" "i")))
13188 (match_operand 4)))
13189 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13192 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13193 && GET_CODE (operands[3]) == CONST
13194 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13195 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13198 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13199 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13200 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13201 return "call\t{*%%rax|rax}";
13203 [(set_attr "type" "multi")
13204 (set_attr "length" "22")])
13206 (define_expand "tls_global_dynamic_64_<mode>"
13208 [(set (match_operand:P 0 "register_operand")
13210 (mem:QI (match_operand 2))
13212 (unspec:P [(match_operand 1 "tls_symbolic_operand")
13216 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13218 (define_insn "*tls_local_dynamic_base_32_gnu"
13219 [(set (match_operand:SI 0 "register_operand" "=a")
13221 [(match_operand:SI 1 "register_operand" "b")
13222 (match_operand 2 "constant_call_address_operand" "Bz")
13224 UNSPEC_TLS_LD_BASE))
13225 (clobber (match_scratch:SI 3 "=d"))
13226 (clobber (match_scratch:SI 4 "=c"))
13227 (clobber (reg:CC FLAGS_REG))]
13228 "!TARGET_64BIT && TARGET_GNU_TLS"
13231 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13232 if (TARGET_SUN_TLS)
13234 if (HAVE_AS_IX86_TLSLDMPLT)
13235 return "call\t%&@tlsldmplt";
13237 return "call\t%p2@plt";
13239 return "call\t%P2";
13241 [(set_attr "type" "multi")
13242 (set_attr "length" "11")])
13244 (define_expand "tls_local_dynamic_base_32"
13246 [(set (match_operand:SI 0 "register_operand")
13248 [(match_operand:SI 1 "register_operand")
13249 (match_operand 2 "constant_call_address_operand")
13251 UNSPEC_TLS_LD_BASE))
13252 (clobber (match_scratch:SI 3))
13253 (clobber (match_scratch:SI 4))
13254 (clobber (reg:CC FLAGS_REG))])]
13256 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13258 (define_insn "*tls_local_dynamic_base_64_<mode>"
13259 [(set (match_operand:P 0 "register_operand" "=a")
13261 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13262 (match_operand 2)))
13263 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
13267 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13268 if (TARGET_SUN_TLS)
13269 return "call\t%p1@plt";
13270 return "call\t%P1";
13272 [(set_attr "type" "multi")
13273 (set_attr "length" "12")])
13275 (define_insn "*tls_local_dynamic_base_64_largepic"
13276 [(set (match_operand:DI 0 "register_operand" "=a")
13278 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13279 (match_operand:DI 2 "immediate_operand" "i")))
13280 (match_operand 3)))
13281 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
13282 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13283 && GET_CODE (operands[2]) == CONST
13284 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13285 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13288 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13289 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13290 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13291 return "call\t{*%%rax|rax}";
13293 [(set_attr "type" "multi")
13294 (set_attr "length" "22")])
13296 (define_expand "tls_local_dynamic_base_64_<mode>"
13298 [(set (match_operand:P 0 "register_operand")
13300 (mem:QI (match_operand 1))
13302 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
13304 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13306 ;; Local dynamic of a single variable is a lose. Show combine how
13307 ;; to convert that back to global dynamic.
13309 (define_insn_and_split "*tls_local_dynamic_32_once"
13310 [(set (match_operand:SI 0 "register_operand" "=a")
13312 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13313 (match_operand 2 "constant_call_address_operand" "Bz")
13315 UNSPEC_TLS_LD_BASE)
13316 (const:SI (unspec:SI
13317 [(match_operand 3 "tls_symbolic_operand")]
13319 (clobber (match_scratch:SI 4 "=d"))
13320 (clobber (match_scratch:SI 5 "=c"))
13321 (clobber (reg:CC FLAGS_REG))]
13326 [(set (match_dup 0)
13327 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13330 (clobber (match_dup 4))
13331 (clobber (match_dup 5))
13332 (clobber (reg:CC FLAGS_REG))])])
13334 ;; Segment register for the thread base ptr load
13335 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13337 ;; Load and add the thread base pointer from %<tp_seg>:0.
13338 (define_insn "*load_tp_x32"
13339 [(set (match_operand:SI 0 "register_operand" "=r")
13340 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13342 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13343 [(set_attr "type" "imov")
13344 (set_attr "modrm" "0")
13345 (set_attr "length" "7")
13346 (set_attr "memory" "load")
13347 (set_attr "imm_disp" "false")])
13349 (define_insn "*load_tp_x32_zext"
13350 [(set (match_operand:DI 0 "register_operand" "=r")
13351 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13353 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13354 [(set_attr "type" "imov")
13355 (set_attr "modrm" "0")
13356 (set_attr "length" "7")
13357 (set_attr "memory" "load")
13358 (set_attr "imm_disp" "false")])
13360 (define_insn "*load_tp_<mode>"
13361 [(set (match_operand:P 0 "register_operand" "=r")
13362 (unspec:P [(const_int 0)] UNSPEC_TP))]
13364 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13365 [(set_attr "type" "imov")
13366 (set_attr "modrm" "0")
13367 (set_attr "length" "7")
13368 (set_attr "memory" "load")
13369 (set_attr "imm_disp" "false")])
13371 (define_insn "*add_tp_x32"
13372 [(set (match_operand:SI 0 "register_operand" "=r")
13373 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13374 (match_operand:SI 1 "register_operand" "0")))
13375 (clobber (reg:CC FLAGS_REG))]
13377 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13378 [(set_attr "type" "alu")
13379 (set_attr "modrm" "0")
13380 (set_attr "length" "7")
13381 (set_attr "memory" "load")
13382 (set_attr "imm_disp" "false")])
13384 (define_insn "*add_tp_x32_zext"
13385 [(set (match_operand:DI 0 "register_operand" "=r")
13387 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13388 (match_operand:SI 1 "register_operand" "0"))))
13389 (clobber (reg:CC FLAGS_REG))]
13391 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13392 [(set_attr "type" "alu")
13393 (set_attr "modrm" "0")
13394 (set_attr "length" "7")
13395 (set_attr "memory" "load")
13396 (set_attr "imm_disp" "false")])
13398 (define_insn "*add_tp_<mode>"
13399 [(set (match_operand:P 0 "register_operand" "=r")
13400 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13401 (match_operand:P 1 "register_operand" "0")))
13402 (clobber (reg:CC FLAGS_REG))]
13404 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13405 [(set_attr "type" "alu")
13406 (set_attr "modrm" "0")
13407 (set_attr "length" "7")
13408 (set_attr "memory" "load")
13409 (set_attr "imm_disp" "false")])
13411 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13412 ;; %rax as destination of the initial executable code sequence.
13413 (define_insn "tls_initial_exec_64_sun"
13414 [(set (match_operand:DI 0 "register_operand" "=a")
13416 [(match_operand 1 "tls_symbolic_operand")]
13417 UNSPEC_TLS_IE_SUN))
13418 (clobber (reg:CC FLAGS_REG))]
13419 "TARGET_64BIT && TARGET_SUN_TLS"
13422 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13423 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13425 [(set_attr "type" "multi")])
13427 ;; GNU2 TLS patterns can be split.
13429 (define_expand "tls_dynamic_gnu2_32"
13430 [(set (match_dup 3)
13431 (plus:SI (match_operand:SI 2 "register_operand")
13433 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13436 [(set (match_operand:SI 0 "register_operand")
13437 (unspec:SI [(match_dup 1) (match_dup 3)
13438 (match_dup 2) (reg:SI SP_REG)]
13440 (clobber (reg:CC FLAGS_REG))])]
13441 "!TARGET_64BIT && TARGET_GNU2_TLS"
13443 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13444 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13447 (define_insn "*tls_dynamic_gnu2_lea_32"
13448 [(set (match_operand:SI 0 "register_operand" "=r")
13449 (plus:SI (match_operand:SI 1 "register_operand" "b")
13451 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13452 UNSPEC_TLSDESC))))]
13453 "!TARGET_64BIT && TARGET_GNU2_TLS"
13454 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13455 [(set_attr "type" "lea")
13456 (set_attr "mode" "SI")
13457 (set_attr "length" "6")
13458 (set_attr "length_address" "4")])
13460 (define_insn "*tls_dynamic_gnu2_call_32"
13461 [(set (match_operand:SI 0 "register_operand" "=a")
13462 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13463 (match_operand:SI 2 "register_operand" "0")
13464 ;; we have to make sure %ebx still points to the GOT
13465 (match_operand:SI 3 "register_operand" "b")
13468 (clobber (reg:CC FLAGS_REG))]
13469 "!TARGET_64BIT && TARGET_GNU2_TLS"
13470 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13471 [(set_attr "type" "call")
13472 (set_attr "length" "2")
13473 (set_attr "length_address" "0")])
13475 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13476 [(set (match_operand:SI 0 "register_operand" "=&a")
13478 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13479 (match_operand:SI 4)
13480 (match_operand:SI 2 "register_operand" "b")
13483 (const:SI (unspec:SI
13484 [(match_operand 1 "tls_symbolic_operand")]
13486 (clobber (reg:CC FLAGS_REG))]
13487 "!TARGET_64BIT && TARGET_GNU2_TLS"
13490 [(set (match_dup 0) (match_dup 5))]
13492 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13493 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13496 (define_expand "tls_dynamic_gnu2_64"
13497 [(set (match_dup 2)
13498 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13501 [(set (match_operand:DI 0 "register_operand")
13502 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13504 (clobber (reg:CC FLAGS_REG))])]
13505 "TARGET_64BIT && TARGET_GNU2_TLS"
13507 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13508 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13511 (define_insn "*tls_dynamic_gnu2_lea_64"
13512 [(set (match_operand:DI 0 "register_operand" "=r")
13513 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13515 "TARGET_64BIT && TARGET_GNU2_TLS"
13516 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13517 [(set_attr "type" "lea")
13518 (set_attr "mode" "DI")
13519 (set_attr "length" "7")
13520 (set_attr "length_address" "4")])
13522 (define_insn "*tls_dynamic_gnu2_call_64"
13523 [(set (match_operand:DI 0 "register_operand" "=a")
13524 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13525 (match_operand:DI 2 "register_operand" "0")
13528 (clobber (reg:CC FLAGS_REG))]
13529 "TARGET_64BIT && TARGET_GNU2_TLS"
13530 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13531 [(set_attr "type" "call")
13532 (set_attr "length" "2")
13533 (set_attr "length_address" "0")])
13535 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13536 [(set (match_operand:DI 0 "register_operand" "=&a")
13538 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13539 (match_operand:DI 3)
13542 (const:DI (unspec:DI
13543 [(match_operand 1 "tls_symbolic_operand")]
13545 (clobber (reg:CC FLAGS_REG))]
13546 "TARGET_64BIT && TARGET_GNU2_TLS"
13549 [(set (match_dup 0) (match_dup 4))]
13551 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13552 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13555 ;; These patterns match the binary 387 instructions for addM3, subM3,
13556 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13557 ;; SFmode. The first is the normal insn, the second the same insn but
13558 ;; with one operand a conversion, and the third the same insn but with
13559 ;; the other operand a conversion. The conversion may be SFmode or
13560 ;; SImode if the target mode DFmode, but only SImode if the target mode
13563 ;; Gcc is slightly more smart about handling normal two address instructions
13564 ;; so use special patterns for add and mull.
13566 (define_insn "*fop_<mode>_comm_mixed"
13567 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
13568 (match_operator:MODEF 3 "binary_fp_operator"
13569 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
13570 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
13571 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13572 && COMMUTATIVE_ARITH_P (operands[3])
13573 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13574 "* return output_387_binary_op (insn, operands);"
13575 [(set (attr "type")
13576 (if_then_else (eq_attr "alternative" "1,2")
13577 (if_then_else (match_operand:MODEF 3 "mult_operator")
13578 (const_string "ssemul")
13579 (const_string "sseadd"))
13580 (if_then_else (match_operand:MODEF 3 "mult_operator")
13581 (const_string "fmul")
13582 (const_string "fop"))))
13583 (set_attr "isa" "*,noavx,avx")
13584 (set_attr "prefix" "orig,orig,vex")
13585 (set_attr "mode" "<MODE>")
13586 (set (attr "enabled")
13587 (cond [(eq_attr "alternative" "0")
13588 (symbol_ref "TARGET_MIX_SSE_I387")
13590 (const_string "*")))])
13592 (define_insn "*fop_<mode>_comm_i387"
13593 [(set (match_operand:MODEF 0 "register_operand" "=f")
13594 (match_operator:MODEF 3 "binary_fp_operator"
13595 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13596 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13597 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13598 && COMMUTATIVE_ARITH_P (operands[3])
13599 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13600 "* return output_387_binary_op (insn, operands);"
13601 [(set (attr "type")
13602 (if_then_else (match_operand:MODEF 3 "mult_operator")
13603 (const_string "fmul")
13604 (const_string "fop")))
13605 (set_attr "mode" "<MODE>")])
13607 (define_insn "*rcpsf2_sse"
13608 [(set (match_operand:SF 0 "register_operand" "=x")
13609 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13612 "%vrcpss\t{%1, %d0|%d0, %1}"
13613 [(set_attr "type" "sse")
13614 (set_attr "atom_sse_attr" "rcp")
13615 (set_attr "btver2_sse_attr" "rcp")
13616 (set_attr "prefix" "maybe_vex")
13617 (set_attr "mode" "SF")])
13619 (define_insn "*fop_<mode>_1_mixed"
13620 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
13621 (match_operator:MODEF 3 "binary_fp_operator"
13622 [(match_operand:MODEF 1
13623 "register_mixssei387nonimm_operand" "0,fm,0,v")
13624 (match_operand:MODEF 2
13625 "nonimmediate_operand" "fm,0,xm,vm")]))]
13626 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13627 && !COMMUTATIVE_ARITH_P (operands[3])
13628 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13629 "* return output_387_binary_op (insn, operands);"
13630 [(set (attr "type")
13631 (cond [(and (eq_attr "alternative" "2,3")
13632 (match_operand:MODEF 3 "mult_operator"))
13633 (const_string "ssemul")
13634 (and (eq_attr "alternative" "2,3")
13635 (match_operand:MODEF 3 "div_operator"))
13636 (const_string "ssediv")
13637 (eq_attr "alternative" "2,3")
13638 (const_string "sseadd")
13639 (match_operand:MODEF 3 "mult_operator")
13640 (const_string "fmul")
13641 (match_operand:MODEF 3 "div_operator")
13642 (const_string "fdiv")
13644 (const_string "fop")))
13645 (set_attr "isa" "*,*,noavx,avx")
13646 (set_attr "prefix" "orig,orig,orig,vex")
13647 (set_attr "mode" "<MODE>")
13648 (set (attr "enabled")
13649 (cond [(eq_attr "alternative" "0,1")
13650 (symbol_ref "TARGET_MIX_SSE_I387")
13652 (const_string "*")))])
13654 ;; This pattern is not fully shadowed by the pattern above.
13655 (define_insn "*fop_<mode>_1_i387"
13656 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13657 (match_operator:MODEF 3 "binary_fp_operator"
13658 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13659 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13660 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13661 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13662 && !COMMUTATIVE_ARITH_P (operands[3])
13663 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13664 "* return output_387_binary_op (insn, operands);"
13665 [(set (attr "type")
13666 (cond [(match_operand:MODEF 3 "mult_operator")
13667 (const_string "fmul")
13668 (match_operand:MODEF 3 "div_operator")
13669 (const_string "fdiv")
13671 (const_string "fop")))
13672 (set_attr "mode" "<MODE>")])
13674 ;; ??? Add SSE splitters for these!
13675 (define_insn "*fop_<MODEF:mode>_2_i387"
13676 [(set (match_operand:MODEF 0 "register_operand" "=f")
13677 (match_operator:MODEF 3 "binary_fp_operator"
13679 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13680 (match_operand:MODEF 2 "register_operand" "0")]))]
13681 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13682 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13683 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13684 || optimize_function_for_size_p (cfun))"
13685 { return output_387_binary_op (insn, operands); }
13686 [(set (attr "type")
13687 (cond [(match_operand:MODEF 3 "mult_operator")
13688 (const_string "fmul")
13689 (match_operand:MODEF 3 "div_operator")
13690 (const_string "fdiv")
13692 (const_string "fop")))
13693 (set_attr "fp_int_src" "true")
13694 (set_attr "mode" "<SWI24:MODE>")])
13696 (define_insn "*fop_<MODEF:mode>_3_i387"
13697 [(set (match_operand:MODEF 0 "register_operand" "=f")
13698 (match_operator:MODEF 3 "binary_fp_operator"
13699 [(match_operand:MODEF 1 "register_operand" "0")
13701 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13702 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13703 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13704 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13705 || optimize_function_for_size_p (cfun))"
13706 { return output_387_binary_op (insn, operands); }
13707 [(set (attr "type")
13708 (cond [(match_operand:MODEF 3 "mult_operator")
13709 (const_string "fmul")
13710 (match_operand:MODEF 3 "div_operator")
13711 (const_string "fdiv")
13713 (const_string "fop")))
13714 (set_attr "fp_int_src" "true")
13715 (set_attr "mode" "<MODE>")])
13717 (define_insn "*fop_df_4_i387"
13718 [(set (match_operand:DF 0 "register_operand" "=f,f")
13719 (match_operator:DF 3 "binary_fp_operator"
13721 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13722 (match_operand:DF 2 "register_operand" "0,f")]))]
13723 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13724 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13725 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13726 "* return output_387_binary_op (insn, operands);"
13727 [(set (attr "type")
13728 (cond [(match_operand:DF 3 "mult_operator")
13729 (const_string "fmul")
13730 (match_operand:DF 3 "div_operator")
13731 (const_string "fdiv")
13733 (const_string "fop")))
13734 (set_attr "mode" "SF")])
13736 (define_insn "*fop_df_5_i387"
13737 [(set (match_operand:DF 0 "register_operand" "=f,f")
13738 (match_operator:DF 3 "binary_fp_operator"
13739 [(match_operand:DF 1 "register_operand" "0,f")
13741 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13742 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13743 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13744 "* return output_387_binary_op (insn, operands);"
13745 [(set (attr "type")
13746 (cond [(match_operand:DF 3 "mult_operator")
13747 (const_string "fmul")
13748 (match_operand:DF 3 "div_operator")
13749 (const_string "fdiv")
13751 (const_string "fop")))
13752 (set_attr "mode" "SF")])
13754 (define_insn "*fop_df_6_i387"
13755 [(set (match_operand:DF 0 "register_operand" "=f,f")
13756 (match_operator:DF 3 "binary_fp_operator"
13758 (match_operand:SF 1 "register_operand" "0,f"))
13760 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13761 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13762 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13763 "* return output_387_binary_op (insn, operands);"
13764 [(set (attr "type")
13765 (cond [(match_operand:DF 3 "mult_operator")
13766 (const_string "fmul")
13767 (match_operand:DF 3 "div_operator")
13768 (const_string "fdiv")
13770 (const_string "fop")))
13771 (set_attr "mode" "SF")])
13773 (define_insn "*fop_xf_comm_i387"
13774 [(set (match_operand:XF 0 "register_operand" "=f")
13775 (match_operator:XF 3 "binary_fp_operator"
13776 [(match_operand:XF 1 "register_operand" "%0")
13777 (match_operand:XF 2 "register_operand" "f")]))]
13779 && COMMUTATIVE_ARITH_P (operands[3])"
13780 "* return output_387_binary_op (insn, operands);"
13781 [(set (attr "type")
13782 (if_then_else (match_operand:XF 3 "mult_operator")
13783 (const_string "fmul")
13784 (const_string "fop")))
13785 (set_attr "mode" "XF")])
13787 (define_insn "*fop_xf_1_i387"
13788 [(set (match_operand:XF 0 "register_operand" "=f,f")
13789 (match_operator:XF 3 "binary_fp_operator"
13790 [(match_operand:XF 1 "register_operand" "0,f")
13791 (match_operand:XF 2 "register_operand" "f,0")]))]
13793 && !COMMUTATIVE_ARITH_P (operands[3])"
13794 "* return output_387_binary_op (insn, operands);"
13795 [(set (attr "type")
13796 (cond [(match_operand:XF 3 "mult_operator")
13797 (const_string "fmul")
13798 (match_operand:XF 3 "div_operator")
13799 (const_string "fdiv")
13801 (const_string "fop")))
13802 (set_attr "mode" "XF")])
13804 (define_insn "*fop_xf_2_i387"
13805 [(set (match_operand:XF 0 "register_operand" "=f")
13806 (match_operator:XF 3 "binary_fp_operator"
13808 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13809 (match_operand:XF 2 "register_operand" "0")]))]
13811 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13812 { return output_387_binary_op (insn, operands); }
13813 [(set (attr "type")
13814 (cond [(match_operand:XF 3 "mult_operator")
13815 (const_string "fmul")
13816 (match_operand:XF 3 "div_operator")
13817 (const_string "fdiv")
13819 (const_string "fop")))
13820 (set_attr "fp_int_src" "true")
13821 (set_attr "mode" "<MODE>")])
13823 (define_insn "*fop_xf_3_i387"
13824 [(set (match_operand:XF 0 "register_operand" "=f")
13825 (match_operator:XF 3 "binary_fp_operator"
13826 [(match_operand:XF 1 "register_operand" "0")
13828 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13830 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13831 { return output_387_binary_op (insn, operands); }
13832 [(set (attr "type")
13833 (cond [(match_operand:XF 3 "mult_operator")
13834 (const_string "fmul")
13835 (match_operand:XF 3 "div_operator")
13836 (const_string "fdiv")
13838 (const_string "fop")))
13839 (set_attr "fp_int_src" "true")
13840 (set_attr "mode" "<MODE>")])
13842 (define_insn "*fop_xf_4_i387"
13843 [(set (match_operand:XF 0 "register_operand" "=f,f")
13844 (match_operator:XF 3 "binary_fp_operator"
13846 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13847 (match_operand:XF 2 "register_operand" "0,f")]))]
13849 "* return output_387_binary_op (insn, operands);"
13850 [(set (attr "type")
13851 (cond [(match_operand:XF 3 "mult_operator")
13852 (const_string "fmul")
13853 (match_operand:XF 3 "div_operator")
13854 (const_string "fdiv")
13856 (const_string "fop")))
13857 (set_attr "mode" "<MODE>")])
13859 (define_insn "*fop_xf_5_i387"
13860 [(set (match_operand:XF 0 "register_operand" "=f,f")
13861 (match_operator:XF 3 "binary_fp_operator"
13862 [(match_operand:XF 1 "register_operand" "0,f")
13864 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13866 "* return output_387_binary_op (insn, operands);"
13867 [(set (attr "type")
13868 (cond [(match_operand:XF 3 "mult_operator")
13869 (const_string "fmul")
13870 (match_operand:XF 3 "div_operator")
13871 (const_string "fdiv")
13873 (const_string "fop")))
13874 (set_attr "mode" "<MODE>")])
13876 (define_insn "*fop_xf_6_i387"
13877 [(set (match_operand:XF 0 "register_operand" "=f,f")
13878 (match_operator:XF 3 "binary_fp_operator"
13880 (match_operand:MODEF 1 "register_operand" "0,f"))
13882 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13884 "* return output_387_binary_op (insn, operands);"
13885 [(set (attr "type")
13886 (cond [(match_operand:XF 3 "mult_operator")
13887 (const_string "fmul")
13888 (match_operand:XF 3 "div_operator")
13889 (const_string "fdiv")
13891 (const_string "fop")))
13892 (set_attr "mode" "<MODE>")])
13894 ;; FPU special functions.
13896 ;; This pattern implements a no-op XFmode truncation for
13897 ;; all fancy i386 XFmode math functions.
13899 (define_insn "truncxf<mode>2_i387_noop_unspec"
13900 [(set (match_operand:MODEF 0 "register_operand" "=f")
13901 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13902 UNSPEC_TRUNC_NOOP))]
13903 "TARGET_USE_FANCY_MATH_387"
13904 "* return output_387_reg_move (insn, operands);"
13905 [(set_attr "type" "fmov")
13906 (set_attr "mode" "<MODE>")])
13908 (define_insn "sqrtxf2"
13909 [(set (match_operand:XF 0 "register_operand" "=f")
13910 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13911 "TARGET_USE_FANCY_MATH_387"
13913 [(set_attr "type" "fpspc")
13914 (set_attr "mode" "XF")
13915 (set_attr "athlon_decode" "direct")
13916 (set_attr "amdfam10_decode" "direct")
13917 (set_attr "bdver1_decode" "direct")])
13919 (define_insn "sqrt_extend<mode>xf2_i387"
13920 [(set (match_operand:XF 0 "register_operand" "=f")
13923 (match_operand:MODEF 1 "register_operand" "0"))))]
13924 "TARGET_USE_FANCY_MATH_387"
13926 [(set_attr "type" "fpspc")
13927 (set_attr "mode" "XF")
13928 (set_attr "athlon_decode" "direct")
13929 (set_attr "amdfam10_decode" "direct")
13930 (set_attr "bdver1_decode" "direct")])
13932 (define_insn "*rsqrtsf2_sse"
13933 [(set (match_operand:SF 0 "register_operand" "=x")
13934 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13937 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13938 [(set_attr "type" "sse")
13939 (set_attr "atom_sse_attr" "rcp")
13940 (set_attr "btver2_sse_attr" "rcp")
13941 (set_attr "prefix" "maybe_vex")
13942 (set_attr "mode" "SF")])
13944 (define_expand "rsqrtsf2"
13945 [(set (match_operand:SF 0 "register_operand")
13946 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13950 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13954 (define_insn "*sqrt<mode>2_sse"
13955 [(set (match_operand:MODEF 0 "register_operand" "=v")
13957 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
13958 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13959 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13960 [(set_attr "type" "sse")
13961 (set_attr "atom_sse_attr" "sqrt")
13962 (set_attr "btver2_sse_attr" "sqrt")
13963 (set_attr "prefix" "maybe_vex")
13964 (set_attr "mode" "<MODE>")
13965 (set_attr "athlon_decode" "*")
13966 (set_attr "amdfam10_decode" "*")
13967 (set_attr "bdver1_decode" "*")])
13969 (define_expand "sqrt<mode>2"
13970 [(set (match_operand:MODEF 0 "register_operand")
13972 (match_operand:MODEF 1 "nonimmediate_operand")))]
13973 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13974 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13976 if (<MODE>mode == SFmode
13978 && TARGET_RECIP_SQRT
13979 && !optimize_function_for_size_p (cfun)
13980 && flag_finite_math_only && !flag_trapping_math
13981 && flag_unsafe_math_optimizations)
13983 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13987 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13989 rtx op0 = gen_reg_rtx (XFmode);
13990 rtx op1 = force_reg (<MODE>mode, operands[1]);
13992 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13993 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13998 (define_insn "fpremxf4_i387"
13999 [(set (match_operand:XF 0 "register_operand" "=f")
14000 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14001 (match_operand:XF 3 "register_operand" "1")]
14003 (set (match_operand:XF 1 "register_operand" "=u")
14004 (unspec:XF [(match_dup 2) (match_dup 3)]
14006 (set (reg:CCFP FPSR_REG)
14007 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14009 "TARGET_USE_FANCY_MATH_387
14010 && flag_finite_math_only"
14012 [(set_attr "type" "fpspc")
14013 (set_attr "mode" "XF")])
14015 (define_expand "fmodxf3"
14016 [(use (match_operand:XF 0 "register_operand"))
14017 (use (match_operand:XF 1 "general_operand"))
14018 (use (match_operand:XF 2 "general_operand"))]
14019 "TARGET_USE_FANCY_MATH_387
14020 && flag_finite_math_only"
14022 rtx_code_label *label = gen_label_rtx ();
14024 rtx op1 = gen_reg_rtx (XFmode);
14025 rtx op2 = gen_reg_rtx (XFmode);
14027 emit_move_insn (op2, operands[2]);
14028 emit_move_insn (op1, operands[1]);
14030 emit_label (label);
14031 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14032 ix86_emit_fp_unordered_jump (label);
14033 LABEL_NUSES (label) = 1;
14035 emit_move_insn (operands[0], op1);
14039 (define_expand "fmod<mode>3"
14040 [(use (match_operand:MODEF 0 "register_operand"))
14041 (use (match_operand:MODEF 1 "general_operand"))
14042 (use (match_operand:MODEF 2 "general_operand"))]
14043 "TARGET_USE_FANCY_MATH_387
14044 && flag_finite_math_only"
14046 rtx (*gen_truncxf) (rtx, rtx);
14048 rtx_code_label *label = gen_label_rtx ();
14050 rtx op1 = gen_reg_rtx (XFmode);
14051 rtx op2 = gen_reg_rtx (XFmode);
14053 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14054 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14056 emit_label (label);
14057 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14058 ix86_emit_fp_unordered_jump (label);
14059 LABEL_NUSES (label) = 1;
14061 /* Truncate the result properly for strict SSE math. */
14062 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14063 && !TARGET_MIX_SSE_I387)
14064 gen_truncxf = gen_truncxf<mode>2;
14066 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14068 emit_insn (gen_truncxf (operands[0], op1));
14072 (define_insn "fprem1xf4_i387"
14073 [(set (match_operand:XF 0 "register_operand" "=f")
14074 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14075 (match_operand:XF 3 "register_operand" "1")]
14077 (set (match_operand:XF 1 "register_operand" "=u")
14078 (unspec:XF [(match_dup 2) (match_dup 3)]
14080 (set (reg:CCFP FPSR_REG)
14081 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14083 "TARGET_USE_FANCY_MATH_387
14084 && flag_finite_math_only"
14086 [(set_attr "type" "fpspc")
14087 (set_attr "mode" "XF")])
14089 (define_expand "remainderxf3"
14090 [(use (match_operand:XF 0 "register_operand"))
14091 (use (match_operand:XF 1 "general_operand"))
14092 (use (match_operand:XF 2 "general_operand"))]
14093 "TARGET_USE_FANCY_MATH_387
14094 && flag_finite_math_only"
14096 rtx_code_label *label = gen_label_rtx ();
14098 rtx op1 = gen_reg_rtx (XFmode);
14099 rtx op2 = gen_reg_rtx (XFmode);
14101 emit_move_insn (op2, operands[2]);
14102 emit_move_insn (op1, operands[1]);
14104 emit_label (label);
14105 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14106 ix86_emit_fp_unordered_jump (label);
14107 LABEL_NUSES (label) = 1;
14109 emit_move_insn (operands[0], op1);
14113 (define_expand "remainder<mode>3"
14114 [(use (match_operand:MODEF 0 "register_operand"))
14115 (use (match_operand:MODEF 1 "general_operand"))
14116 (use (match_operand:MODEF 2 "general_operand"))]
14117 "TARGET_USE_FANCY_MATH_387
14118 && flag_finite_math_only"
14120 rtx (*gen_truncxf) (rtx, rtx);
14122 rtx_code_label *label = gen_label_rtx ();
14124 rtx op1 = gen_reg_rtx (XFmode);
14125 rtx op2 = gen_reg_rtx (XFmode);
14127 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14128 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14130 emit_label (label);
14132 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14133 ix86_emit_fp_unordered_jump (label);
14134 LABEL_NUSES (label) = 1;
14136 /* Truncate the result properly for strict SSE math. */
14137 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14138 && !TARGET_MIX_SSE_I387)
14139 gen_truncxf = gen_truncxf<mode>2;
14141 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14143 emit_insn (gen_truncxf (operands[0], op1));
14147 (define_int_iterator SINCOS
14151 (define_int_attr sincos
14152 [(UNSPEC_SIN "sin")
14153 (UNSPEC_COS "cos")])
14155 (define_insn "*<sincos>xf2_i387"
14156 [(set (match_operand:XF 0 "register_operand" "=f")
14157 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14159 "TARGET_USE_FANCY_MATH_387
14160 && flag_unsafe_math_optimizations"
14162 [(set_attr "type" "fpspc")
14163 (set_attr "mode" "XF")])
14165 (define_insn "*<sincos>_extend<mode>xf2_i387"
14166 [(set (match_operand:XF 0 "register_operand" "=f")
14167 (unspec:XF [(float_extend:XF
14168 (match_operand:MODEF 1 "register_operand" "0"))]
14170 "TARGET_USE_FANCY_MATH_387
14171 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14172 || TARGET_MIX_SSE_I387)
14173 && flag_unsafe_math_optimizations"
14175 [(set_attr "type" "fpspc")
14176 (set_attr "mode" "XF")])
14178 ;; When sincos pattern is defined, sin and cos builtin functions will be
14179 ;; expanded to sincos pattern with one of its outputs left unused.
14180 ;; CSE pass will figure out if two sincos patterns can be combined,
14181 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14182 ;; depending on the unused output.
14184 (define_insn "sincosxf3"
14185 [(set (match_operand:XF 0 "register_operand" "=f")
14186 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14187 UNSPEC_SINCOS_COS))
14188 (set (match_operand:XF 1 "register_operand" "=u")
14189 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14190 "TARGET_USE_FANCY_MATH_387
14191 && flag_unsafe_math_optimizations"
14193 [(set_attr "type" "fpspc")
14194 (set_attr "mode" "XF")])
14197 [(set (match_operand:XF 0 "register_operand")
14198 (unspec:XF [(match_operand:XF 2 "register_operand")]
14199 UNSPEC_SINCOS_COS))
14200 (set (match_operand:XF 1 "register_operand")
14201 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14202 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14203 && can_create_pseudo_p ()"
14204 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14207 [(set (match_operand:XF 0 "register_operand")
14208 (unspec:XF [(match_operand:XF 2 "register_operand")]
14209 UNSPEC_SINCOS_COS))
14210 (set (match_operand:XF 1 "register_operand")
14211 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14212 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14213 && can_create_pseudo_p ()"
14214 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14216 (define_insn "sincos_extend<mode>xf3_i387"
14217 [(set (match_operand:XF 0 "register_operand" "=f")
14218 (unspec:XF [(float_extend:XF
14219 (match_operand:MODEF 2 "register_operand" "0"))]
14220 UNSPEC_SINCOS_COS))
14221 (set (match_operand:XF 1 "register_operand" "=u")
14222 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14223 "TARGET_USE_FANCY_MATH_387
14224 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14225 || TARGET_MIX_SSE_I387)
14226 && flag_unsafe_math_optimizations"
14228 [(set_attr "type" "fpspc")
14229 (set_attr "mode" "XF")])
14232 [(set (match_operand:XF 0 "register_operand")
14233 (unspec:XF [(float_extend:XF
14234 (match_operand:MODEF 2 "register_operand"))]
14235 UNSPEC_SINCOS_COS))
14236 (set (match_operand:XF 1 "register_operand")
14237 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14238 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14239 && can_create_pseudo_p ()"
14240 [(set (match_dup 1)
14241 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14244 [(set (match_operand:XF 0 "register_operand")
14245 (unspec:XF [(float_extend:XF
14246 (match_operand:MODEF 2 "register_operand"))]
14247 UNSPEC_SINCOS_COS))
14248 (set (match_operand:XF 1 "register_operand")
14249 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14250 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14251 && can_create_pseudo_p ()"
14252 [(set (match_dup 0)
14253 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14255 (define_expand "sincos<mode>3"
14256 [(use (match_operand:MODEF 0 "register_operand"))
14257 (use (match_operand:MODEF 1 "register_operand"))
14258 (use (match_operand:MODEF 2 "register_operand"))]
14259 "TARGET_USE_FANCY_MATH_387
14260 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14261 || TARGET_MIX_SSE_I387)
14262 && flag_unsafe_math_optimizations"
14264 rtx op0 = gen_reg_rtx (XFmode);
14265 rtx op1 = gen_reg_rtx (XFmode);
14267 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14268 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14269 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14273 (define_insn "fptanxf4_i387"
14274 [(set (match_operand:XF 0 "register_operand" "=f")
14275 (match_operand:XF 3 "const_double_operand" "F"))
14276 (set (match_operand:XF 1 "register_operand" "=u")
14277 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14279 "TARGET_USE_FANCY_MATH_387
14280 && flag_unsafe_math_optimizations
14281 && standard_80387_constant_p (operands[3]) == 2"
14283 [(set_attr "type" "fpspc")
14284 (set_attr "mode" "XF")])
14286 (define_insn "fptan_extend<mode>xf4_i387"
14287 [(set (match_operand:MODEF 0 "register_operand" "=f")
14288 (match_operand:MODEF 3 "const_double_operand" "F"))
14289 (set (match_operand:XF 1 "register_operand" "=u")
14290 (unspec:XF [(float_extend:XF
14291 (match_operand:MODEF 2 "register_operand" "0"))]
14293 "TARGET_USE_FANCY_MATH_387
14294 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14295 || TARGET_MIX_SSE_I387)
14296 && flag_unsafe_math_optimizations
14297 && standard_80387_constant_p (operands[3]) == 2"
14299 [(set_attr "type" "fpspc")
14300 (set_attr "mode" "XF")])
14302 (define_expand "tanxf2"
14303 [(use (match_operand:XF 0 "register_operand"))
14304 (use (match_operand:XF 1 "register_operand"))]
14305 "TARGET_USE_FANCY_MATH_387
14306 && flag_unsafe_math_optimizations"
14308 rtx one = gen_reg_rtx (XFmode);
14309 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14311 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14315 (define_expand "tan<mode>2"
14316 [(use (match_operand:MODEF 0 "register_operand"))
14317 (use (match_operand:MODEF 1 "register_operand"))]
14318 "TARGET_USE_FANCY_MATH_387
14319 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14320 || TARGET_MIX_SSE_I387)
14321 && flag_unsafe_math_optimizations"
14323 rtx op0 = gen_reg_rtx (XFmode);
14325 rtx one = gen_reg_rtx (<MODE>mode);
14326 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14328 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14329 operands[1], op2));
14330 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14334 (define_insn "*fpatanxf3_i387"
14335 [(set (match_operand:XF 0 "register_operand" "=f")
14336 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14337 (match_operand:XF 2 "register_operand" "u")]
14339 (clobber (match_scratch:XF 3 "=2"))]
14340 "TARGET_USE_FANCY_MATH_387
14341 && flag_unsafe_math_optimizations"
14343 [(set_attr "type" "fpspc")
14344 (set_attr "mode" "XF")])
14346 (define_insn "fpatan_extend<mode>xf3_i387"
14347 [(set (match_operand:XF 0 "register_operand" "=f")
14348 (unspec:XF [(float_extend:XF
14349 (match_operand:MODEF 1 "register_operand" "0"))
14351 (match_operand:MODEF 2 "register_operand" "u"))]
14353 (clobber (match_scratch:XF 3 "=2"))]
14354 "TARGET_USE_FANCY_MATH_387
14355 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14356 || TARGET_MIX_SSE_I387)
14357 && flag_unsafe_math_optimizations"
14359 [(set_attr "type" "fpspc")
14360 (set_attr "mode" "XF")])
14362 (define_expand "atan2xf3"
14363 [(parallel [(set (match_operand:XF 0 "register_operand")
14364 (unspec:XF [(match_operand:XF 2 "register_operand")
14365 (match_operand:XF 1 "register_operand")]
14367 (clobber (match_scratch:XF 3))])]
14368 "TARGET_USE_FANCY_MATH_387
14369 && flag_unsafe_math_optimizations")
14371 (define_expand "atan2<mode>3"
14372 [(use (match_operand:MODEF 0 "register_operand"))
14373 (use (match_operand:MODEF 1 "register_operand"))
14374 (use (match_operand:MODEF 2 "register_operand"))]
14375 "TARGET_USE_FANCY_MATH_387
14376 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14377 || TARGET_MIX_SSE_I387)
14378 && flag_unsafe_math_optimizations"
14380 rtx op0 = gen_reg_rtx (XFmode);
14382 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14383 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14387 (define_expand "atanxf2"
14388 [(parallel [(set (match_operand:XF 0 "register_operand")
14389 (unspec:XF [(match_dup 2)
14390 (match_operand:XF 1 "register_operand")]
14392 (clobber (match_scratch:XF 3))])]
14393 "TARGET_USE_FANCY_MATH_387
14394 && flag_unsafe_math_optimizations"
14396 operands[2] = gen_reg_rtx (XFmode);
14397 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14400 (define_expand "atan<mode>2"
14401 [(use (match_operand:MODEF 0 "register_operand"))
14402 (use (match_operand:MODEF 1 "register_operand"))]
14403 "TARGET_USE_FANCY_MATH_387
14404 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14405 || TARGET_MIX_SSE_I387)
14406 && flag_unsafe_math_optimizations"
14408 rtx op0 = gen_reg_rtx (XFmode);
14410 rtx op2 = gen_reg_rtx (<MODE>mode);
14411 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14413 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14414 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14418 (define_expand "asinxf2"
14419 [(set (match_dup 2)
14420 (mult:XF (match_operand:XF 1 "register_operand")
14422 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14423 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14424 (parallel [(set (match_operand:XF 0 "register_operand")
14425 (unspec:XF [(match_dup 5) (match_dup 1)]
14427 (clobber (match_scratch:XF 6))])]
14428 "TARGET_USE_FANCY_MATH_387
14429 && flag_unsafe_math_optimizations"
14433 if (optimize_insn_for_size_p ())
14436 for (i = 2; i < 6; i++)
14437 operands[i] = gen_reg_rtx (XFmode);
14439 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14442 (define_expand "asin<mode>2"
14443 [(use (match_operand:MODEF 0 "register_operand"))
14444 (use (match_operand:MODEF 1 "general_operand"))]
14445 "TARGET_USE_FANCY_MATH_387
14446 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14447 || TARGET_MIX_SSE_I387)
14448 && flag_unsafe_math_optimizations"
14450 rtx op0 = gen_reg_rtx (XFmode);
14451 rtx op1 = gen_reg_rtx (XFmode);
14453 if (optimize_insn_for_size_p ())
14456 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14457 emit_insn (gen_asinxf2 (op0, op1));
14458 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14462 (define_expand "acosxf2"
14463 [(set (match_dup 2)
14464 (mult:XF (match_operand:XF 1 "register_operand")
14466 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14467 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14468 (parallel [(set (match_operand:XF 0 "register_operand")
14469 (unspec:XF [(match_dup 1) (match_dup 5)]
14471 (clobber (match_scratch:XF 6))])]
14472 "TARGET_USE_FANCY_MATH_387
14473 && flag_unsafe_math_optimizations"
14477 if (optimize_insn_for_size_p ())
14480 for (i = 2; i < 6; i++)
14481 operands[i] = gen_reg_rtx (XFmode);
14483 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14486 (define_expand "acos<mode>2"
14487 [(use (match_operand:MODEF 0 "register_operand"))
14488 (use (match_operand:MODEF 1 "general_operand"))]
14489 "TARGET_USE_FANCY_MATH_387
14490 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14491 || TARGET_MIX_SSE_I387)
14492 && flag_unsafe_math_optimizations"
14494 rtx op0 = gen_reg_rtx (XFmode);
14495 rtx op1 = gen_reg_rtx (XFmode);
14497 if (optimize_insn_for_size_p ())
14500 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14501 emit_insn (gen_acosxf2 (op0, op1));
14502 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14506 (define_insn "fyl2xxf3_i387"
14507 [(set (match_operand:XF 0 "register_operand" "=f")
14508 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14509 (match_operand:XF 2 "register_operand" "u")]
14511 (clobber (match_scratch:XF 3 "=2"))]
14512 "TARGET_USE_FANCY_MATH_387
14513 && flag_unsafe_math_optimizations"
14515 [(set_attr "type" "fpspc")
14516 (set_attr "mode" "XF")])
14518 (define_insn "fyl2x_extend<mode>xf3_i387"
14519 [(set (match_operand:XF 0 "register_operand" "=f")
14520 (unspec:XF [(float_extend:XF
14521 (match_operand:MODEF 1 "register_operand" "0"))
14522 (match_operand:XF 2 "register_operand" "u")]
14524 (clobber (match_scratch:XF 3 "=2"))]
14525 "TARGET_USE_FANCY_MATH_387
14526 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14527 || TARGET_MIX_SSE_I387)
14528 && flag_unsafe_math_optimizations"
14530 [(set_attr "type" "fpspc")
14531 (set_attr "mode" "XF")])
14533 (define_expand "logxf2"
14534 [(parallel [(set (match_operand:XF 0 "register_operand")
14535 (unspec:XF [(match_operand:XF 1 "register_operand")
14536 (match_dup 2)] UNSPEC_FYL2X))
14537 (clobber (match_scratch:XF 3))])]
14538 "TARGET_USE_FANCY_MATH_387
14539 && flag_unsafe_math_optimizations"
14541 operands[2] = gen_reg_rtx (XFmode);
14542 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14545 (define_expand "log<mode>2"
14546 [(use (match_operand:MODEF 0 "register_operand"))
14547 (use (match_operand:MODEF 1 "register_operand"))]
14548 "TARGET_USE_FANCY_MATH_387
14549 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14550 || TARGET_MIX_SSE_I387)
14551 && flag_unsafe_math_optimizations"
14553 rtx op0 = gen_reg_rtx (XFmode);
14555 rtx op2 = gen_reg_rtx (XFmode);
14556 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14558 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14559 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14563 (define_expand "log10xf2"
14564 [(parallel [(set (match_operand:XF 0 "register_operand")
14565 (unspec:XF [(match_operand:XF 1 "register_operand")
14566 (match_dup 2)] UNSPEC_FYL2X))
14567 (clobber (match_scratch:XF 3))])]
14568 "TARGET_USE_FANCY_MATH_387
14569 && flag_unsafe_math_optimizations"
14571 operands[2] = gen_reg_rtx (XFmode);
14572 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14575 (define_expand "log10<mode>2"
14576 [(use (match_operand:MODEF 0 "register_operand"))
14577 (use (match_operand:MODEF 1 "register_operand"))]
14578 "TARGET_USE_FANCY_MATH_387
14579 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14580 || TARGET_MIX_SSE_I387)
14581 && flag_unsafe_math_optimizations"
14583 rtx op0 = gen_reg_rtx (XFmode);
14585 rtx op2 = gen_reg_rtx (XFmode);
14586 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14588 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14589 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14593 (define_expand "log2xf2"
14594 [(parallel [(set (match_operand:XF 0 "register_operand")
14595 (unspec:XF [(match_operand:XF 1 "register_operand")
14596 (match_dup 2)] UNSPEC_FYL2X))
14597 (clobber (match_scratch:XF 3))])]
14598 "TARGET_USE_FANCY_MATH_387
14599 && flag_unsafe_math_optimizations"
14601 operands[2] = gen_reg_rtx (XFmode);
14602 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14605 (define_expand "log2<mode>2"
14606 [(use (match_operand:MODEF 0 "register_operand"))
14607 (use (match_operand:MODEF 1 "register_operand"))]
14608 "TARGET_USE_FANCY_MATH_387
14609 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14610 || TARGET_MIX_SSE_I387)
14611 && flag_unsafe_math_optimizations"
14613 rtx op0 = gen_reg_rtx (XFmode);
14615 rtx op2 = gen_reg_rtx (XFmode);
14616 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14618 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14619 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14623 (define_insn "fyl2xp1xf3_i387"
14624 [(set (match_operand:XF 0 "register_operand" "=f")
14625 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14626 (match_operand:XF 2 "register_operand" "u")]
14628 (clobber (match_scratch:XF 3 "=2"))]
14629 "TARGET_USE_FANCY_MATH_387
14630 && flag_unsafe_math_optimizations"
14632 [(set_attr "type" "fpspc")
14633 (set_attr "mode" "XF")])
14635 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14636 [(set (match_operand:XF 0 "register_operand" "=f")
14637 (unspec:XF [(float_extend:XF
14638 (match_operand:MODEF 1 "register_operand" "0"))
14639 (match_operand:XF 2 "register_operand" "u")]
14641 (clobber (match_scratch:XF 3 "=2"))]
14642 "TARGET_USE_FANCY_MATH_387
14643 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14644 || TARGET_MIX_SSE_I387)
14645 && flag_unsafe_math_optimizations"
14647 [(set_attr "type" "fpspc")
14648 (set_attr "mode" "XF")])
14650 (define_expand "log1pxf2"
14651 [(use (match_operand:XF 0 "register_operand"))
14652 (use (match_operand:XF 1 "register_operand"))]
14653 "TARGET_USE_FANCY_MATH_387
14654 && flag_unsafe_math_optimizations"
14656 if (optimize_insn_for_size_p ())
14659 ix86_emit_i387_log1p (operands[0], operands[1]);
14663 (define_expand "log1p<mode>2"
14664 [(use (match_operand:MODEF 0 "register_operand"))
14665 (use (match_operand:MODEF 1 "register_operand"))]
14666 "TARGET_USE_FANCY_MATH_387
14667 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14668 || TARGET_MIX_SSE_I387)
14669 && flag_unsafe_math_optimizations"
14673 if (optimize_insn_for_size_p ())
14676 op0 = gen_reg_rtx (XFmode);
14678 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14680 ix86_emit_i387_log1p (op0, operands[1]);
14681 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14685 (define_insn "fxtractxf3_i387"
14686 [(set (match_operand:XF 0 "register_operand" "=f")
14687 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14688 UNSPEC_XTRACT_FRACT))
14689 (set (match_operand:XF 1 "register_operand" "=u")
14690 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14691 "TARGET_USE_FANCY_MATH_387
14692 && flag_unsafe_math_optimizations"
14694 [(set_attr "type" "fpspc")
14695 (set_attr "mode" "XF")])
14697 (define_insn "fxtract_extend<mode>xf3_i387"
14698 [(set (match_operand:XF 0 "register_operand" "=f")
14699 (unspec:XF [(float_extend:XF
14700 (match_operand:MODEF 2 "register_operand" "0"))]
14701 UNSPEC_XTRACT_FRACT))
14702 (set (match_operand:XF 1 "register_operand" "=u")
14703 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14704 "TARGET_USE_FANCY_MATH_387
14705 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14706 || TARGET_MIX_SSE_I387)
14707 && flag_unsafe_math_optimizations"
14709 [(set_attr "type" "fpspc")
14710 (set_attr "mode" "XF")])
14712 (define_expand "logbxf2"
14713 [(parallel [(set (match_dup 2)
14714 (unspec:XF [(match_operand:XF 1 "register_operand")]
14715 UNSPEC_XTRACT_FRACT))
14716 (set (match_operand:XF 0 "register_operand")
14717 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14718 "TARGET_USE_FANCY_MATH_387
14719 && flag_unsafe_math_optimizations"
14720 "operands[2] = gen_reg_rtx (XFmode);")
14722 (define_expand "logb<mode>2"
14723 [(use (match_operand:MODEF 0 "register_operand"))
14724 (use (match_operand:MODEF 1 "register_operand"))]
14725 "TARGET_USE_FANCY_MATH_387
14726 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14727 || TARGET_MIX_SSE_I387)
14728 && flag_unsafe_math_optimizations"
14730 rtx op0 = gen_reg_rtx (XFmode);
14731 rtx op1 = gen_reg_rtx (XFmode);
14733 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14734 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14738 (define_expand "ilogbxf2"
14739 [(use (match_operand:SI 0 "register_operand"))
14740 (use (match_operand:XF 1 "register_operand"))]
14741 "TARGET_USE_FANCY_MATH_387
14742 && flag_unsafe_math_optimizations"
14746 if (optimize_insn_for_size_p ())
14749 op0 = gen_reg_rtx (XFmode);
14750 op1 = gen_reg_rtx (XFmode);
14752 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14753 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14757 (define_expand "ilogb<mode>2"
14758 [(use (match_operand:SI 0 "register_operand"))
14759 (use (match_operand:MODEF 1 "register_operand"))]
14760 "TARGET_USE_FANCY_MATH_387
14761 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14762 || TARGET_MIX_SSE_I387)
14763 && flag_unsafe_math_optimizations"
14767 if (optimize_insn_for_size_p ())
14770 op0 = gen_reg_rtx (XFmode);
14771 op1 = gen_reg_rtx (XFmode);
14773 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14774 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14778 (define_insn "*f2xm1xf2_i387"
14779 [(set (match_operand:XF 0 "register_operand" "=f")
14780 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14782 "TARGET_USE_FANCY_MATH_387
14783 && flag_unsafe_math_optimizations"
14785 [(set_attr "type" "fpspc")
14786 (set_attr "mode" "XF")])
14788 (define_insn "fscalexf4_i387"
14789 [(set (match_operand:XF 0 "register_operand" "=f")
14790 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14791 (match_operand:XF 3 "register_operand" "1")]
14792 UNSPEC_FSCALE_FRACT))
14793 (set (match_operand:XF 1 "register_operand" "=u")
14794 (unspec:XF [(match_dup 2) (match_dup 3)]
14795 UNSPEC_FSCALE_EXP))]
14796 "TARGET_USE_FANCY_MATH_387
14797 && flag_unsafe_math_optimizations"
14799 [(set_attr "type" "fpspc")
14800 (set_attr "mode" "XF")])
14802 (define_expand "expNcorexf3"
14803 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14804 (match_operand:XF 2 "register_operand")))
14805 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14806 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14807 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14808 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14809 (parallel [(set (match_operand:XF 0 "register_operand")
14810 (unspec:XF [(match_dup 8) (match_dup 4)]
14811 UNSPEC_FSCALE_FRACT))
14813 (unspec:XF [(match_dup 8) (match_dup 4)]
14814 UNSPEC_FSCALE_EXP))])]
14815 "TARGET_USE_FANCY_MATH_387
14816 && flag_unsafe_math_optimizations"
14820 if (optimize_insn_for_size_p ())
14823 for (i = 3; i < 10; i++)
14824 operands[i] = gen_reg_rtx (XFmode);
14826 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14829 (define_expand "expxf2"
14830 [(use (match_operand:XF 0 "register_operand"))
14831 (use (match_operand:XF 1 "register_operand"))]
14832 "TARGET_USE_FANCY_MATH_387
14833 && flag_unsafe_math_optimizations"
14837 if (optimize_insn_for_size_p ())
14840 op2 = gen_reg_rtx (XFmode);
14841 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14843 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14847 (define_expand "exp<mode>2"
14848 [(use (match_operand:MODEF 0 "register_operand"))
14849 (use (match_operand:MODEF 1 "general_operand"))]
14850 "TARGET_USE_FANCY_MATH_387
14851 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14852 || TARGET_MIX_SSE_I387)
14853 && flag_unsafe_math_optimizations"
14857 if (optimize_insn_for_size_p ())
14860 op0 = gen_reg_rtx (XFmode);
14861 op1 = gen_reg_rtx (XFmode);
14863 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14864 emit_insn (gen_expxf2 (op0, op1));
14865 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14869 (define_expand "exp10xf2"
14870 [(use (match_operand:XF 0 "register_operand"))
14871 (use (match_operand:XF 1 "register_operand"))]
14872 "TARGET_USE_FANCY_MATH_387
14873 && flag_unsafe_math_optimizations"
14877 if (optimize_insn_for_size_p ())
14880 op2 = gen_reg_rtx (XFmode);
14881 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14883 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14887 (define_expand "exp10<mode>2"
14888 [(use (match_operand:MODEF 0 "register_operand"))
14889 (use (match_operand:MODEF 1 "general_operand"))]
14890 "TARGET_USE_FANCY_MATH_387
14891 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14892 || TARGET_MIX_SSE_I387)
14893 && flag_unsafe_math_optimizations"
14897 if (optimize_insn_for_size_p ())
14900 op0 = gen_reg_rtx (XFmode);
14901 op1 = gen_reg_rtx (XFmode);
14903 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14904 emit_insn (gen_exp10xf2 (op0, op1));
14905 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14909 (define_expand "exp2xf2"
14910 [(use (match_operand:XF 0 "register_operand"))
14911 (use (match_operand:XF 1 "register_operand"))]
14912 "TARGET_USE_FANCY_MATH_387
14913 && flag_unsafe_math_optimizations"
14917 if (optimize_insn_for_size_p ())
14920 op2 = gen_reg_rtx (XFmode);
14921 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14923 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14927 (define_expand "exp2<mode>2"
14928 [(use (match_operand:MODEF 0 "register_operand"))
14929 (use (match_operand:MODEF 1 "general_operand"))]
14930 "TARGET_USE_FANCY_MATH_387
14931 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14932 || TARGET_MIX_SSE_I387)
14933 && flag_unsafe_math_optimizations"
14937 if (optimize_insn_for_size_p ())
14940 op0 = gen_reg_rtx (XFmode);
14941 op1 = gen_reg_rtx (XFmode);
14943 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14944 emit_insn (gen_exp2xf2 (op0, op1));
14945 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14949 (define_expand "expm1xf2"
14950 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14952 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14953 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14954 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14955 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14956 (parallel [(set (match_dup 7)
14957 (unspec:XF [(match_dup 6) (match_dup 4)]
14958 UNSPEC_FSCALE_FRACT))
14960 (unspec:XF [(match_dup 6) (match_dup 4)]
14961 UNSPEC_FSCALE_EXP))])
14962 (parallel [(set (match_dup 10)
14963 (unspec:XF [(match_dup 9) (match_dup 8)]
14964 UNSPEC_FSCALE_FRACT))
14965 (set (match_dup 11)
14966 (unspec:XF [(match_dup 9) (match_dup 8)]
14967 UNSPEC_FSCALE_EXP))])
14968 (set (match_dup 12) (minus:XF (match_dup 10)
14969 (float_extend:XF (match_dup 13))))
14970 (set (match_operand:XF 0 "register_operand")
14971 (plus:XF (match_dup 12) (match_dup 7)))]
14972 "TARGET_USE_FANCY_MATH_387
14973 && flag_unsafe_math_optimizations"
14977 if (optimize_insn_for_size_p ())
14980 for (i = 2; i < 13; i++)
14981 operands[i] = gen_reg_rtx (XFmode);
14984 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14986 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14989 (define_expand "expm1<mode>2"
14990 [(use (match_operand:MODEF 0 "register_operand"))
14991 (use (match_operand:MODEF 1 "general_operand"))]
14992 "TARGET_USE_FANCY_MATH_387
14993 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14994 || TARGET_MIX_SSE_I387)
14995 && flag_unsafe_math_optimizations"
14999 if (optimize_insn_for_size_p ())
15002 op0 = gen_reg_rtx (XFmode);
15003 op1 = gen_reg_rtx (XFmode);
15005 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15006 emit_insn (gen_expm1xf2 (op0, op1));
15007 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15011 (define_expand "ldexpxf3"
15012 [(match_operand:XF 0 "register_operand")
15013 (match_operand:XF 1 "register_operand")
15014 (match_operand:SI 2 "register_operand")]
15015 "TARGET_USE_FANCY_MATH_387
15016 && flag_unsafe_math_optimizations"
15019 if (optimize_insn_for_size_p ())
15022 tmp1 = gen_reg_rtx (XFmode);
15023 tmp2 = gen_reg_rtx (XFmode);
15025 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
15026 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
15027 operands[1], tmp1));
15031 (define_expand "ldexp<mode>3"
15032 [(use (match_operand:MODEF 0 "register_operand"))
15033 (use (match_operand:MODEF 1 "general_operand"))
15034 (use (match_operand:SI 2 "register_operand"))]
15035 "TARGET_USE_FANCY_MATH_387
15036 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15037 || TARGET_MIX_SSE_I387)
15038 && flag_unsafe_math_optimizations"
15042 if (optimize_insn_for_size_p ())
15045 op0 = gen_reg_rtx (XFmode);
15046 op1 = gen_reg_rtx (XFmode);
15048 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15049 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15050 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15054 (define_expand "scalbxf3"
15055 [(parallel [(set (match_operand:XF 0 " register_operand")
15056 (unspec:XF [(match_operand:XF 1 "register_operand")
15057 (match_operand:XF 2 "register_operand")]
15058 UNSPEC_FSCALE_FRACT))
15060 (unspec:XF [(match_dup 1) (match_dup 2)]
15061 UNSPEC_FSCALE_EXP))])]
15062 "TARGET_USE_FANCY_MATH_387
15063 && flag_unsafe_math_optimizations"
15065 if (optimize_insn_for_size_p ())
15068 operands[3] = gen_reg_rtx (XFmode);
15071 (define_expand "scalb<mode>3"
15072 [(use (match_operand:MODEF 0 "register_operand"))
15073 (use (match_operand:MODEF 1 "general_operand"))
15074 (use (match_operand:MODEF 2 "general_operand"))]
15075 "TARGET_USE_FANCY_MATH_387
15076 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15077 || TARGET_MIX_SSE_I387)
15078 && flag_unsafe_math_optimizations"
15082 if (optimize_insn_for_size_p ())
15085 op0 = gen_reg_rtx (XFmode);
15086 op1 = gen_reg_rtx (XFmode);
15087 op2 = gen_reg_rtx (XFmode);
15089 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15090 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15091 emit_insn (gen_scalbxf3 (op0, op1, op2));
15092 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15096 (define_expand "significandxf2"
15097 [(parallel [(set (match_operand:XF 0 "register_operand")
15098 (unspec:XF [(match_operand:XF 1 "register_operand")]
15099 UNSPEC_XTRACT_FRACT))
15101 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15102 "TARGET_USE_FANCY_MATH_387
15103 && flag_unsafe_math_optimizations"
15104 "operands[2] = gen_reg_rtx (XFmode);")
15106 (define_expand "significand<mode>2"
15107 [(use (match_operand:MODEF 0 "register_operand"))
15108 (use (match_operand:MODEF 1 "register_operand"))]
15109 "TARGET_USE_FANCY_MATH_387
15110 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15111 || TARGET_MIX_SSE_I387)
15112 && flag_unsafe_math_optimizations"
15114 rtx op0 = gen_reg_rtx (XFmode);
15115 rtx op1 = gen_reg_rtx (XFmode);
15117 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15118 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15123 (define_insn "sse4_1_round<mode>2"
15124 [(set (match_operand:MODEF 0 "register_operand" "=x")
15125 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
15126 (match_operand:SI 2 "const_0_to_15_operand" "n")]
15129 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15130 [(set_attr "type" "ssecvt")
15131 (set_attr "prefix_extra" "1")
15132 (set_attr "prefix" "maybe_vex")
15133 (set_attr "mode" "<MODE>")])
15135 (define_insn "rintxf2"
15136 [(set (match_operand:XF 0 "register_operand" "=f")
15137 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15139 "TARGET_USE_FANCY_MATH_387
15140 && flag_unsafe_math_optimizations"
15142 [(set_attr "type" "fpspc")
15143 (set_attr "mode" "XF")])
15145 (define_expand "rint<mode>2"
15146 [(use (match_operand:MODEF 0 "register_operand"))
15147 (use (match_operand:MODEF 1 "register_operand"))]
15148 "(TARGET_USE_FANCY_MATH_387
15149 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15150 || TARGET_MIX_SSE_I387)
15151 && flag_unsafe_math_optimizations)
15152 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15153 && !flag_trapping_math)"
15155 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15156 && !flag_trapping_math)
15159 emit_insn (gen_sse4_1_round<mode>2
15160 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
15161 else if (optimize_insn_for_size_p ())
15164 ix86_expand_rint (operands[0], operands[1]);
15168 rtx op0 = gen_reg_rtx (XFmode);
15169 rtx op1 = gen_reg_rtx (XFmode);
15171 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15172 emit_insn (gen_rintxf2 (op0, op1));
15174 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15179 (define_expand "round<mode>2"
15180 [(match_operand:X87MODEF 0 "register_operand")
15181 (match_operand:X87MODEF 1 "nonimmediate_operand")]
15182 "(TARGET_USE_FANCY_MATH_387
15183 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15184 || TARGET_MIX_SSE_I387)
15185 && flag_unsafe_math_optimizations)
15186 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15187 && !flag_trapping_math && !flag_rounding_math)"
15189 if (optimize_insn_for_size_p ())
15192 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15193 && !flag_trapping_math && !flag_rounding_math)
15197 operands[1] = force_reg (<MODE>mode, operands[1]);
15198 ix86_expand_round_sse4 (operands[0], operands[1]);
15200 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15201 ix86_expand_round (operands[0], operands[1]);
15203 ix86_expand_rounddf_32 (operands[0], operands[1]);
15207 operands[1] = force_reg (<MODE>mode, operands[1]);
15208 ix86_emit_i387_round (operands[0], operands[1]);
15213 (define_insn_and_split "*fistdi2_1"
15214 [(set (match_operand:DI 0 "nonimmediate_operand")
15215 (unspec:DI [(match_operand:XF 1 "register_operand")]
15217 "TARGET_USE_FANCY_MATH_387
15218 && can_create_pseudo_p ()"
15223 if (memory_operand (operands[0], VOIDmode))
15224 emit_insn (gen_fistdi2 (operands[0], operands[1]));
15227 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15228 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15233 [(set_attr "type" "fpspc")
15234 (set_attr "mode" "DI")])
15236 (define_insn "fistdi2"
15237 [(set (match_operand:DI 0 "memory_operand" "=m")
15238 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15240 (clobber (match_scratch:XF 2 "=&1f"))]
15241 "TARGET_USE_FANCY_MATH_387"
15242 "* return output_fix_trunc (insn, operands, false);"
15243 [(set_attr "type" "fpspc")
15244 (set_attr "mode" "DI")])
15246 (define_insn "fistdi2_with_temp"
15247 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15248 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15250 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15251 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15252 "TARGET_USE_FANCY_MATH_387"
15254 [(set_attr "type" "fpspc")
15255 (set_attr "mode" "DI")])
15258 [(set (match_operand:DI 0 "register_operand")
15259 (unspec:DI [(match_operand:XF 1 "register_operand")]
15261 (clobber (match_operand:DI 2 "memory_operand"))
15262 (clobber (match_scratch 3))]
15264 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15265 (clobber (match_dup 3))])
15266 (set (match_dup 0) (match_dup 2))])
15269 [(set (match_operand:DI 0 "memory_operand")
15270 (unspec:DI [(match_operand:XF 1 "register_operand")]
15272 (clobber (match_operand:DI 2 "memory_operand"))
15273 (clobber (match_scratch 3))]
15275 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15276 (clobber (match_dup 3))])])
15278 (define_insn_and_split "*fist<mode>2_1"
15279 [(set (match_operand:SWI24 0 "register_operand")
15280 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15282 "TARGET_USE_FANCY_MATH_387
15283 && can_create_pseudo_p ()"
15288 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15289 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15293 [(set_attr "type" "fpspc")
15294 (set_attr "mode" "<MODE>")])
15296 (define_insn "fist<mode>2"
15297 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15298 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15300 "TARGET_USE_FANCY_MATH_387"
15301 "* return output_fix_trunc (insn, operands, false);"
15302 [(set_attr "type" "fpspc")
15303 (set_attr "mode" "<MODE>")])
15305 (define_insn "fist<mode>2_with_temp"
15306 [(set (match_operand:SWI24 0 "register_operand" "=r")
15307 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15309 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15310 "TARGET_USE_FANCY_MATH_387"
15312 [(set_attr "type" "fpspc")
15313 (set_attr "mode" "<MODE>")])
15316 [(set (match_operand:SWI24 0 "register_operand")
15317 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15319 (clobber (match_operand:SWI24 2 "memory_operand"))]
15321 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15322 (set (match_dup 0) (match_dup 2))])
15325 [(set (match_operand:SWI24 0 "memory_operand")
15326 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15328 (clobber (match_operand:SWI24 2 "memory_operand"))]
15330 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15332 (define_expand "lrintxf<mode>2"
15333 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15334 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15336 "TARGET_USE_FANCY_MATH_387")
15338 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15339 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15340 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15341 UNSPEC_FIX_NOTRUNC))]
15342 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15344 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15345 [(match_operand:SWI248x 0 "nonimmediate_operand")
15346 (match_operand:X87MODEF 1 "register_operand")]
15347 "(TARGET_USE_FANCY_MATH_387
15348 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15349 || TARGET_MIX_SSE_I387)
15350 && flag_unsafe_math_optimizations)
15351 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15352 && <SWI248x:MODE>mode != HImode
15353 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15354 && !flag_trapping_math && !flag_rounding_math)"
15356 if (optimize_insn_for_size_p ())
15359 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15360 && <SWI248x:MODE>mode != HImode
15361 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15362 && !flag_trapping_math && !flag_rounding_math)
15363 ix86_expand_lround (operands[0], operands[1]);
15365 ix86_emit_i387_round (operands[0], operands[1]);
15369 (define_int_iterator FRNDINT_ROUNDING
15370 [UNSPEC_FRNDINT_FLOOR
15371 UNSPEC_FRNDINT_CEIL
15372 UNSPEC_FRNDINT_TRUNC])
15374 (define_int_iterator FIST_ROUNDING
15378 ;; Base name for define_insn
15379 (define_int_attr rounding_insn
15380 [(UNSPEC_FRNDINT_FLOOR "floor")
15381 (UNSPEC_FRNDINT_CEIL "ceil")
15382 (UNSPEC_FRNDINT_TRUNC "btrunc")
15383 (UNSPEC_FIST_FLOOR "floor")
15384 (UNSPEC_FIST_CEIL "ceil")])
15386 (define_int_attr rounding
15387 [(UNSPEC_FRNDINT_FLOOR "floor")
15388 (UNSPEC_FRNDINT_CEIL "ceil")
15389 (UNSPEC_FRNDINT_TRUNC "trunc")
15390 (UNSPEC_FIST_FLOOR "floor")
15391 (UNSPEC_FIST_CEIL "ceil")])
15393 (define_int_attr ROUNDING
15394 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15395 (UNSPEC_FRNDINT_CEIL "CEIL")
15396 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15397 (UNSPEC_FIST_FLOOR "FLOOR")
15398 (UNSPEC_FIST_CEIL "CEIL")])
15400 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15401 (define_insn_and_split "frndintxf2_<rounding>"
15402 [(set (match_operand:XF 0 "register_operand")
15403 (unspec:XF [(match_operand:XF 1 "register_operand")]
15405 (clobber (reg:CC FLAGS_REG))]
15406 "TARGET_USE_FANCY_MATH_387
15407 && flag_unsafe_math_optimizations
15408 && can_create_pseudo_p ()"
15413 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15415 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15416 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15418 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15419 operands[2], operands[3]));
15422 [(set_attr "type" "frndint")
15423 (set_attr "i387_cw" "<rounding>")
15424 (set_attr "mode" "XF")])
15426 (define_insn "frndintxf2_<rounding>_i387"
15427 [(set (match_operand:XF 0 "register_operand" "=f")
15428 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15430 (use (match_operand:HI 2 "memory_operand" "m"))
15431 (use (match_operand:HI 3 "memory_operand" "m"))]
15432 "TARGET_USE_FANCY_MATH_387
15433 && flag_unsafe_math_optimizations"
15434 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15435 [(set_attr "type" "frndint")
15436 (set_attr "i387_cw" "<rounding>")
15437 (set_attr "mode" "XF")])
15439 (define_expand "<rounding_insn>xf2"
15440 [(parallel [(set (match_operand:XF 0 "register_operand")
15441 (unspec:XF [(match_operand:XF 1 "register_operand")]
15443 (clobber (reg:CC FLAGS_REG))])]
15444 "TARGET_USE_FANCY_MATH_387
15445 && flag_unsafe_math_optimizations
15446 && !optimize_insn_for_size_p ()")
15448 (define_expand "<rounding_insn><mode>2"
15449 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15450 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15452 (clobber (reg:CC FLAGS_REG))])]
15453 "(TARGET_USE_FANCY_MATH_387
15454 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15455 || TARGET_MIX_SSE_I387)
15456 && flag_unsafe_math_optimizations)
15457 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15458 && !flag_trapping_math)"
15460 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15461 && !flag_trapping_math)
15464 emit_insn (gen_sse4_1_round<mode>2
15465 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15466 else if (optimize_insn_for_size_p ())
15468 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15470 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15471 ix86_expand_floorceil (operands[0], operands[1], true);
15472 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15473 ix86_expand_floorceil (operands[0], operands[1], false);
15474 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15475 ix86_expand_trunc (operands[0], operands[1]);
15477 gcc_unreachable ();
15481 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15482 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15483 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15484 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15485 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15486 ix86_expand_truncdf_32 (operands[0], operands[1]);
15488 gcc_unreachable ();
15495 if (optimize_insn_for_size_p ())
15498 op0 = gen_reg_rtx (XFmode);
15499 op1 = gen_reg_rtx (XFmode);
15500 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15501 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15503 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15508 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15509 (define_insn_and_split "frndintxf2_mask_pm"
15510 [(set (match_operand:XF 0 "register_operand")
15511 (unspec:XF [(match_operand:XF 1 "register_operand")]
15512 UNSPEC_FRNDINT_MASK_PM))
15513 (clobber (reg:CC FLAGS_REG))]
15514 "TARGET_USE_FANCY_MATH_387
15515 && flag_unsafe_math_optimizations
15516 && can_create_pseudo_p ()"
15521 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15523 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15524 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15526 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15527 operands[2], operands[3]));
15530 [(set_attr "type" "frndint")
15531 (set_attr "i387_cw" "mask_pm")
15532 (set_attr "mode" "XF")])
15534 (define_insn "frndintxf2_mask_pm_i387"
15535 [(set (match_operand:XF 0 "register_operand" "=f")
15536 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15537 UNSPEC_FRNDINT_MASK_PM))
15538 (use (match_operand:HI 2 "memory_operand" "m"))
15539 (use (match_operand:HI 3 "memory_operand" "m"))]
15540 "TARGET_USE_FANCY_MATH_387
15541 && flag_unsafe_math_optimizations"
15542 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15543 [(set_attr "type" "frndint")
15544 (set_attr "i387_cw" "mask_pm")
15545 (set_attr "mode" "XF")])
15547 (define_expand "nearbyintxf2"
15548 [(parallel [(set (match_operand:XF 0 "register_operand")
15549 (unspec:XF [(match_operand:XF 1 "register_operand")]
15550 UNSPEC_FRNDINT_MASK_PM))
15551 (clobber (reg:CC FLAGS_REG))])]
15552 "TARGET_USE_FANCY_MATH_387
15553 && flag_unsafe_math_optimizations")
15555 (define_expand "nearbyint<mode>2"
15556 [(use (match_operand:MODEF 0 "register_operand"))
15557 (use (match_operand:MODEF 1 "register_operand"))]
15558 "TARGET_USE_FANCY_MATH_387
15559 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15560 || TARGET_MIX_SSE_I387)
15561 && flag_unsafe_math_optimizations"
15563 rtx op0 = gen_reg_rtx (XFmode);
15564 rtx op1 = gen_reg_rtx (XFmode);
15566 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15567 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15569 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15573 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15574 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15575 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15576 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15578 (clobber (reg:CC FLAGS_REG))]
15579 "TARGET_USE_FANCY_MATH_387
15580 && flag_unsafe_math_optimizations
15581 && can_create_pseudo_p ()"
15586 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15588 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15589 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15590 if (memory_operand (operands[0], VOIDmode))
15591 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15592 operands[2], operands[3]));
15595 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15596 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15597 (operands[0], operands[1], operands[2],
15598 operands[3], operands[4]));
15602 [(set_attr "type" "fistp")
15603 (set_attr "i387_cw" "<rounding>")
15604 (set_attr "mode" "<MODE>")])
15606 (define_insn "fistdi2_<rounding>"
15607 [(set (match_operand:DI 0 "memory_operand" "=m")
15608 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15610 (use (match_operand:HI 2 "memory_operand" "m"))
15611 (use (match_operand:HI 3 "memory_operand" "m"))
15612 (clobber (match_scratch:XF 4 "=&1f"))]
15613 "TARGET_USE_FANCY_MATH_387
15614 && flag_unsafe_math_optimizations"
15615 "* return output_fix_trunc (insn, operands, false);"
15616 [(set_attr "type" "fistp")
15617 (set_attr "i387_cw" "<rounding>")
15618 (set_attr "mode" "DI")])
15620 (define_insn "fistdi2_<rounding>_with_temp"
15621 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15622 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15624 (use (match_operand:HI 2 "memory_operand" "m,m"))
15625 (use (match_operand:HI 3 "memory_operand" "m,m"))
15626 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15627 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15628 "TARGET_USE_FANCY_MATH_387
15629 && flag_unsafe_math_optimizations"
15631 [(set_attr "type" "fistp")
15632 (set_attr "i387_cw" "<rounding>")
15633 (set_attr "mode" "DI")])
15636 [(set (match_operand:DI 0 "register_operand")
15637 (unspec:DI [(match_operand:XF 1 "register_operand")]
15639 (use (match_operand:HI 2 "memory_operand"))
15640 (use (match_operand:HI 3 "memory_operand"))
15641 (clobber (match_operand:DI 4 "memory_operand"))
15642 (clobber (match_scratch 5))]
15644 [(parallel [(set (match_dup 4)
15645 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15646 (use (match_dup 2))
15647 (use (match_dup 3))
15648 (clobber (match_dup 5))])
15649 (set (match_dup 0) (match_dup 4))])
15652 [(set (match_operand:DI 0 "memory_operand")
15653 (unspec:DI [(match_operand:XF 1 "register_operand")]
15655 (use (match_operand:HI 2 "memory_operand"))
15656 (use (match_operand:HI 3 "memory_operand"))
15657 (clobber (match_operand:DI 4 "memory_operand"))
15658 (clobber (match_scratch 5))]
15660 [(parallel [(set (match_dup 0)
15661 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15662 (use (match_dup 2))
15663 (use (match_dup 3))
15664 (clobber (match_dup 5))])])
15666 (define_insn "fist<mode>2_<rounding>"
15667 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15668 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15670 (use (match_operand:HI 2 "memory_operand" "m"))
15671 (use (match_operand:HI 3 "memory_operand" "m"))]
15672 "TARGET_USE_FANCY_MATH_387
15673 && flag_unsafe_math_optimizations"
15674 "* return output_fix_trunc (insn, operands, false);"
15675 [(set_attr "type" "fistp")
15676 (set_attr "i387_cw" "<rounding>")
15677 (set_attr "mode" "<MODE>")])
15679 (define_insn "fist<mode>2_<rounding>_with_temp"
15680 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15681 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15683 (use (match_operand:HI 2 "memory_operand" "m,m"))
15684 (use (match_operand:HI 3 "memory_operand" "m,m"))
15685 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15686 "TARGET_USE_FANCY_MATH_387
15687 && flag_unsafe_math_optimizations"
15689 [(set_attr "type" "fistp")
15690 (set_attr "i387_cw" "<rounding>")
15691 (set_attr "mode" "<MODE>")])
15694 [(set (match_operand:SWI24 0 "register_operand")
15695 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15697 (use (match_operand:HI 2 "memory_operand"))
15698 (use (match_operand:HI 3 "memory_operand"))
15699 (clobber (match_operand:SWI24 4 "memory_operand"))]
15701 [(parallel [(set (match_dup 4)
15702 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15703 (use (match_dup 2))
15704 (use (match_dup 3))])
15705 (set (match_dup 0) (match_dup 4))])
15708 [(set (match_operand:SWI24 0 "memory_operand")
15709 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15711 (use (match_operand:HI 2 "memory_operand"))
15712 (use (match_operand:HI 3 "memory_operand"))
15713 (clobber (match_operand:SWI24 4 "memory_operand"))]
15715 [(parallel [(set (match_dup 0)
15716 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15717 (use (match_dup 2))
15718 (use (match_dup 3))])])
15720 (define_expand "l<rounding_insn>xf<mode>2"
15721 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15722 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15724 (clobber (reg:CC FLAGS_REG))])]
15725 "TARGET_USE_FANCY_MATH_387
15726 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15727 && flag_unsafe_math_optimizations")
15729 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15730 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15731 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15733 (clobber (reg:CC FLAGS_REG))])]
15734 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15735 && !flag_trapping_math"
15737 if (TARGET_64BIT && optimize_insn_for_size_p ())
15740 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15741 ix86_expand_lfloorceil (operands[0], operands[1], true);
15742 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15743 ix86_expand_lfloorceil (operands[0], operands[1], false);
15745 gcc_unreachable ();
15750 (define_insn "fxam<mode>2_i387"
15751 [(set (match_operand:HI 0 "register_operand" "=a")
15753 [(match_operand:X87MODEF 1 "register_operand" "f")]
15755 "TARGET_USE_FANCY_MATH_387"
15756 "fxam\n\tfnstsw\t%0"
15757 [(set_attr "type" "multi")
15758 (set_attr "length" "4")
15759 (set_attr "unit" "i387")
15760 (set_attr "mode" "<MODE>")])
15762 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15763 [(set (match_operand:HI 0 "register_operand")
15765 [(match_operand:MODEF 1 "memory_operand")]
15767 "TARGET_USE_FANCY_MATH_387
15768 && can_create_pseudo_p ()"
15771 [(set (match_dup 2)(match_dup 1))
15773 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15775 operands[2] = gen_reg_rtx (<MODE>mode);
15777 MEM_VOLATILE_P (operands[1]) = 1;
15779 [(set_attr "type" "multi")
15780 (set_attr "unit" "i387")
15781 (set_attr "mode" "<MODE>")])
15783 (define_expand "isinfxf2"
15784 [(use (match_operand:SI 0 "register_operand"))
15785 (use (match_operand:XF 1 "register_operand"))]
15786 "TARGET_USE_FANCY_MATH_387
15787 && ix86_libc_has_function (function_c99_misc)"
15789 rtx mask = GEN_INT (0x45);
15790 rtx val = GEN_INT (0x05);
15794 rtx scratch = gen_reg_rtx (HImode);
15795 rtx res = gen_reg_rtx (QImode);
15797 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15799 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15800 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15801 cond = gen_rtx_fmt_ee (EQ, QImode,
15802 gen_rtx_REG (CCmode, FLAGS_REG),
15804 emit_insn (gen_rtx_SET (res, cond));
15805 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15809 (define_expand "isinf<mode>2"
15810 [(use (match_operand:SI 0 "register_operand"))
15811 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15812 "TARGET_USE_FANCY_MATH_387
15813 && ix86_libc_has_function (function_c99_misc)
15814 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15816 rtx mask = GEN_INT (0x45);
15817 rtx val = GEN_INT (0x05);
15821 rtx scratch = gen_reg_rtx (HImode);
15822 rtx res = gen_reg_rtx (QImode);
15824 /* Remove excess precision by forcing value through memory. */
15825 if (memory_operand (operands[1], VOIDmode))
15826 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15829 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15831 emit_move_insn (temp, operands[1]);
15832 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15835 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15836 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15837 cond = gen_rtx_fmt_ee (EQ, QImode,
15838 gen_rtx_REG (CCmode, FLAGS_REG),
15840 emit_insn (gen_rtx_SET (res, cond));
15841 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15845 (define_expand "signbitxf2"
15846 [(use (match_operand:SI 0 "register_operand"))
15847 (use (match_operand:XF 1 "register_operand"))]
15848 "TARGET_USE_FANCY_MATH_387"
15850 rtx scratch = gen_reg_rtx (HImode);
15852 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15853 emit_insn (gen_andsi3 (operands[0],
15854 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15858 (define_insn "movmsk_df"
15859 [(set (match_operand:SI 0 "register_operand" "=r")
15861 [(match_operand:DF 1 "register_operand" "x")]
15863 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15864 "%vmovmskpd\t{%1, %0|%0, %1}"
15865 [(set_attr "type" "ssemov")
15866 (set_attr "prefix" "maybe_vex")
15867 (set_attr "mode" "DF")])
15869 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15870 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15871 (define_expand "signbitdf2"
15872 [(use (match_operand:SI 0 "register_operand"))
15873 (use (match_operand:DF 1 "register_operand"))]
15874 "TARGET_USE_FANCY_MATH_387
15875 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15877 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15879 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15880 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15884 rtx scratch = gen_reg_rtx (HImode);
15886 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15887 emit_insn (gen_andsi3 (operands[0],
15888 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15893 (define_expand "signbitsf2"
15894 [(use (match_operand:SI 0 "register_operand"))
15895 (use (match_operand:SF 1 "register_operand"))]
15896 "TARGET_USE_FANCY_MATH_387
15897 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15899 rtx scratch = gen_reg_rtx (HImode);
15901 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15902 emit_insn (gen_andsi3 (operands[0],
15903 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15907 ;; Block operation instructions
15910 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15913 [(set_attr "length" "1")
15914 (set_attr "length_immediate" "0")
15915 (set_attr "modrm" "0")])
15917 (define_expand "movmem<mode>"
15918 [(use (match_operand:BLK 0 "memory_operand"))
15919 (use (match_operand:BLK 1 "memory_operand"))
15920 (use (match_operand:SWI48 2 "nonmemory_operand"))
15921 (use (match_operand:SWI48 3 "const_int_operand"))
15922 (use (match_operand:SI 4 "const_int_operand"))
15923 (use (match_operand:SI 5 "const_int_operand"))
15924 (use (match_operand:SI 6 ""))
15925 (use (match_operand:SI 7 ""))
15926 (use (match_operand:SI 8 ""))]
15929 if (ix86_expand_set_or_movmem (operands[0], operands[1],
15930 operands[2], NULL, operands[3],
15931 operands[4], operands[5],
15932 operands[6], operands[7],
15933 operands[8], false))
15939 ;; Most CPUs don't like single string operations
15940 ;; Handle this case here to simplify previous expander.
15942 (define_expand "strmov"
15943 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15944 (set (match_operand 1 "memory_operand") (match_dup 4))
15945 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15946 (clobber (reg:CC FLAGS_REG))])
15947 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15948 (clobber (reg:CC FLAGS_REG))])]
15951 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15953 /* If .md ever supports :P for Pmode, these can be directly
15954 in the pattern above. */
15955 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15956 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15958 /* Can't use this if the user has appropriated esi or edi. */
15959 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15960 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15962 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15963 operands[2], operands[3],
15964 operands[5], operands[6]));
15968 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15971 (define_expand "strmov_singleop"
15972 [(parallel [(set (match_operand 1 "memory_operand")
15973 (match_operand 3 "memory_operand"))
15974 (set (match_operand 0 "register_operand")
15976 (set (match_operand 2 "register_operand")
15977 (match_operand 5))])]
15979 "ix86_current_function_needs_cld = 1;")
15981 (define_insn "*strmovdi_rex_1"
15982 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15983 (mem:DI (match_operand:P 3 "register_operand" "1")))
15984 (set (match_operand:P 0 "register_operand" "=D")
15985 (plus:P (match_dup 2)
15987 (set (match_operand:P 1 "register_operand" "=S")
15988 (plus:P (match_dup 3)
15991 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15993 [(set_attr "type" "str")
15994 (set_attr "memory" "both")
15995 (set_attr "mode" "DI")])
15997 (define_insn "*strmovsi_1"
15998 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15999 (mem:SI (match_operand:P 3 "register_operand" "1")))
16000 (set (match_operand:P 0 "register_operand" "=D")
16001 (plus:P (match_dup 2)
16003 (set (match_operand:P 1 "register_operand" "=S")
16004 (plus:P (match_dup 3)
16006 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16008 [(set_attr "type" "str")
16009 (set_attr "memory" "both")
16010 (set_attr "mode" "SI")])
16012 (define_insn "*strmovhi_1"
16013 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16014 (mem:HI (match_operand:P 3 "register_operand" "1")))
16015 (set (match_operand:P 0 "register_operand" "=D")
16016 (plus:P (match_dup 2)
16018 (set (match_operand:P 1 "register_operand" "=S")
16019 (plus:P (match_dup 3)
16021 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16023 [(set_attr "type" "str")
16024 (set_attr "memory" "both")
16025 (set_attr "mode" "HI")])
16027 (define_insn "*strmovqi_1"
16028 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16029 (mem:QI (match_operand:P 3 "register_operand" "1")))
16030 (set (match_operand:P 0 "register_operand" "=D")
16031 (plus:P (match_dup 2)
16033 (set (match_operand:P 1 "register_operand" "=S")
16034 (plus:P (match_dup 3)
16036 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16038 [(set_attr "type" "str")
16039 (set_attr "memory" "both")
16040 (set (attr "prefix_rex")
16042 (match_test "<P:MODE>mode == DImode")
16044 (const_string "*")))
16045 (set_attr "mode" "QI")])
16047 (define_expand "rep_mov"
16048 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16049 (set (match_operand 0 "register_operand")
16051 (set (match_operand 2 "register_operand")
16053 (set (match_operand 1 "memory_operand")
16054 (match_operand 3 "memory_operand"))
16055 (use (match_dup 4))])]
16057 "ix86_current_function_needs_cld = 1;")
16059 (define_insn "*rep_movdi_rex64"
16060 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16061 (set (match_operand:P 0 "register_operand" "=D")
16062 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16064 (match_operand:P 3 "register_operand" "0")))
16065 (set (match_operand:P 1 "register_operand" "=S")
16066 (plus:P (ashift:P (match_dup 5) (const_int 3))
16067 (match_operand:P 4 "register_operand" "1")))
16068 (set (mem:BLK (match_dup 3))
16069 (mem:BLK (match_dup 4)))
16070 (use (match_dup 5))]
16072 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16074 [(set_attr "type" "str")
16075 (set_attr "prefix_rep" "1")
16076 (set_attr "memory" "both")
16077 (set_attr "mode" "DI")])
16079 (define_insn "*rep_movsi"
16080 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16081 (set (match_operand:P 0 "register_operand" "=D")
16082 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16084 (match_operand:P 3 "register_operand" "0")))
16085 (set (match_operand:P 1 "register_operand" "=S")
16086 (plus:P (ashift:P (match_dup 5) (const_int 2))
16087 (match_operand:P 4 "register_operand" "1")))
16088 (set (mem:BLK (match_dup 3))
16089 (mem:BLK (match_dup 4)))
16090 (use (match_dup 5))]
16091 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16092 "%^rep{%;} movs{l|d}"
16093 [(set_attr "type" "str")
16094 (set_attr "prefix_rep" "1")
16095 (set_attr "memory" "both")
16096 (set_attr "mode" "SI")])
16098 (define_insn "*rep_movqi"
16099 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16100 (set (match_operand:P 0 "register_operand" "=D")
16101 (plus:P (match_operand:P 3 "register_operand" "0")
16102 (match_operand:P 5 "register_operand" "2")))
16103 (set (match_operand:P 1 "register_operand" "=S")
16104 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16105 (set (mem:BLK (match_dup 3))
16106 (mem:BLK (match_dup 4)))
16107 (use (match_dup 5))]
16108 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16110 [(set_attr "type" "str")
16111 (set_attr "prefix_rep" "1")
16112 (set_attr "memory" "both")
16113 (set_attr "mode" "QI")])
16115 (define_expand "setmem<mode>"
16116 [(use (match_operand:BLK 0 "memory_operand"))
16117 (use (match_operand:SWI48 1 "nonmemory_operand"))
16118 (use (match_operand:QI 2 "nonmemory_operand"))
16119 (use (match_operand 3 "const_int_operand"))
16120 (use (match_operand:SI 4 "const_int_operand"))
16121 (use (match_operand:SI 5 "const_int_operand"))
16122 (use (match_operand:SI 6 ""))
16123 (use (match_operand:SI 7 ""))
16124 (use (match_operand:SI 8 ""))]
16127 if (ix86_expand_set_or_movmem (operands[0], NULL,
16128 operands[1], operands[2],
16129 operands[3], operands[4],
16130 operands[5], operands[6],
16131 operands[7], operands[8], true))
16137 ;; Most CPUs don't like single string operations
16138 ;; Handle this case here to simplify previous expander.
16140 (define_expand "strset"
16141 [(set (match_operand 1 "memory_operand")
16142 (match_operand 2 "register_operand"))
16143 (parallel [(set (match_operand 0 "register_operand")
16145 (clobber (reg:CC FLAGS_REG))])]
16148 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16149 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16151 /* If .md ever supports :P for Pmode, this can be directly
16152 in the pattern above. */
16153 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16154 GEN_INT (GET_MODE_SIZE (GET_MODE
16156 /* Can't use this if the user has appropriated eax or edi. */
16157 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16158 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16160 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16166 (define_expand "strset_singleop"
16167 [(parallel [(set (match_operand 1 "memory_operand")
16168 (match_operand 2 "register_operand"))
16169 (set (match_operand 0 "register_operand")
16171 (unspec [(const_int 0)] UNSPEC_STOS)])]
16173 "ix86_current_function_needs_cld = 1;")
16175 (define_insn "*strsetdi_rex_1"
16176 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16177 (match_operand:DI 2 "register_operand" "a"))
16178 (set (match_operand:P 0 "register_operand" "=D")
16179 (plus:P (match_dup 1)
16181 (unspec [(const_int 0)] UNSPEC_STOS)]
16183 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16185 [(set_attr "type" "str")
16186 (set_attr "memory" "store")
16187 (set_attr "mode" "DI")])
16189 (define_insn "*strsetsi_1"
16190 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16191 (match_operand:SI 2 "register_operand" "a"))
16192 (set (match_operand:P 0 "register_operand" "=D")
16193 (plus:P (match_dup 1)
16195 (unspec [(const_int 0)] UNSPEC_STOS)]
16196 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16198 [(set_attr "type" "str")
16199 (set_attr "memory" "store")
16200 (set_attr "mode" "SI")])
16202 (define_insn "*strsethi_1"
16203 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16204 (match_operand:HI 2 "register_operand" "a"))
16205 (set (match_operand:P 0 "register_operand" "=D")
16206 (plus:P (match_dup 1)
16208 (unspec [(const_int 0)] UNSPEC_STOS)]
16209 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16211 [(set_attr "type" "str")
16212 (set_attr "memory" "store")
16213 (set_attr "mode" "HI")])
16215 (define_insn "*strsetqi_1"
16216 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16217 (match_operand:QI 2 "register_operand" "a"))
16218 (set (match_operand:P 0 "register_operand" "=D")
16219 (plus:P (match_dup 1)
16221 (unspec [(const_int 0)] UNSPEC_STOS)]
16222 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16224 [(set_attr "type" "str")
16225 (set_attr "memory" "store")
16226 (set (attr "prefix_rex")
16228 (match_test "<P:MODE>mode == DImode")
16230 (const_string "*")))
16231 (set_attr "mode" "QI")])
16233 (define_expand "rep_stos"
16234 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16235 (set (match_operand 0 "register_operand")
16237 (set (match_operand 2 "memory_operand") (const_int 0))
16238 (use (match_operand 3 "register_operand"))
16239 (use (match_dup 1))])]
16241 "ix86_current_function_needs_cld = 1;")
16243 (define_insn "*rep_stosdi_rex64"
16244 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16245 (set (match_operand:P 0 "register_operand" "=D")
16246 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16248 (match_operand:P 3 "register_operand" "0")))
16249 (set (mem:BLK (match_dup 3))
16251 (use (match_operand:DI 2 "register_operand" "a"))
16252 (use (match_dup 4))]
16254 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16256 [(set_attr "type" "str")
16257 (set_attr "prefix_rep" "1")
16258 (set_attr "memory" "store")
16259 (set_attr "mode" "DI")])
16261 (define_insn "*rep_stossi"
16262 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16263 (set (match_operand:P 0 "register_operand" "=D")
16264 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16266 (match_operand:P 3 "register_operand" "0")))
16267 (set (mem:BLK (match_dup 3))
16269 (use (match_operand:SI 2 "register_operand" "a"))
16270 (use (match_dup 4))]
16271 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16272 "%^rep{%;} stos{l|d}"
16273 [(set_attr "type" "str")
16274 (set_attr "prefix_rep" "1")
16275 (set_attr "memory" "store")
16276 (set_attr "mode" "SI")])
16278 (define_insn "*rep_stosqi"
16279 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16280 (set (match_operand:P 0 "register_operand" "=D")
16281 (plus:P (match_operand:P 3 "register_operand" "0")
16282 (match_operand:P 4 "register_operand" "1")))
16283 (set (mem:BLK (match_dup 3))
16285 (use (match_operand:QI 2 "register_operand" "a"))
16286 (use (match_dup 4))]
16287 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16289 [(set_attr "type" "str")
16290 (set_attr "prefix_rep" "1")
16291 (set_attr "memory" "store")
16292 (set (attr "prefix_rex")
16294 (match_test "<P:MODE>mode == DImode")
16296 (const_string "*")))
16297 (set_attr "mode" "QI")])
16299 (define_expand "cmpstrnsi"
16300 [(set (match_operand:SI 0 "register_operand")
16301 (compare:SI (match_operand:BLK 1 "general_operand")
16302 (match_operand:BLK 2 "general_operand")))
16303 (use (match_operand 3 "general_operand"))
16304 (use (match_operand 4 "immediate_operand"))]
16307 rtx addr1, addr2, out, outlow, count, countreg, align;
16309 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16312 /* Can't use this if the user has appropriated ecx, esi or edi. */
16313 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16318 out = gen_reg_rtx (SImode);
16320 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16321 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16322 if (addr1 != XEXP (operands[1], 0))
16323 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16324 if (addr2 != XEXP (operands[2], 0))
16325 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16327 count = operands[3];
16328 countreg = ix86_zero_extend_to_Pmode (count);
16330 /* %%% Iff we are testing strict equality, we can use known alignment
16331 to good advantage. This may be possible with combine, particularly
16332 once cc0 is dead. */
16333 align = operands[4];
16335 if (CONST_INT_P (count))
16337 if (INTVAL (count) == 0)
16339 emit_move_insn (operands[0], const0_rtx);
16342 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16343 operands[1], operands[2]));
16347 rtx (*gen_cmp) (rtx, rtx);
16349 gen_cmp = (TARGET_64BIT
16350 ? gen_cmpdi_1 : gen_cmpsi_1);
16352 emit_insn (gen_cmp (countreg, countreg));
16353 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16354 operands[1], operands[2]));
16357 outlow = gen_lowpart (QImode, out);
16358 emit_insn (gen_cmpintqi (outlow));
16359 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16361 if (operands[0] != out)
16362 emit_move_insn (operands[0], out);
16367 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16369 (define_expand "cmpintqi"
16370 [(set (match_dup 1)
16371 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16373 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16374 (parallel [(set (match_operand:QI 0 "register_operand")
16375 (minus:QI (match_dup 1)
16377 (clobber (reg:CC FLAGS_REG))])]
16380 operands[1] = gen_reg_rtx (QImode);
16381 operands[2] = gen_reg_rtx (QImode);
16384 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16385 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16387 (define_expand "cmpstrnqi_nz_1"
16388 [(parallel [(set (reg:CC FLAGS_REG)
16389 (compare:CC (match_operand 4 "memory_operand")
16390 (match_operand 5 "memory_operand")))
16391 (use (match_operand 2 "register_operand"))
16392 (use (match_operand:SI 3 "immediate_operand"))
16393 (clobber (match_operand 0 "register_operand"))
16394 (clobber (match_operand 1 "register_operand"))
16395 (clobber (match_dup 2))])]
16397 "ix86_current_function_needs_cld = 1;")
16399 (define_insn "*cmpstrnqi_nz_1"
16400 [(set (reg:CC FLAGS_REG)
16401 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16402 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16403 (use (match_operand:P 6 "register_operand" "2"))
16404 (use (match_operand:SI 3 "immediate_operand" "i"))
16405 (clobber (match_operand:P 0 "register_operand" "=S"))
16406 (clobber (match_operand:P 1 "register_operand" "=D"))
16407 (clobber (match_operand:P 2 "register_operand" "=c"))]
16408 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16410 [(set_attr "type" "str")
16411 (set_attr "mode" "QI")
16412 (set (attr "prefix_rex")
16414 (match_test "<P:MODE>mode == DImode")
16416 (const_string "*")))
16417 (set_attr "prefix_rep" "1")])
16419 ;; The same, but the count is not known to not be zero.
16421 (define_expand "cmpstrnqi_1"
16422 [(parallel [(set (reg:CC FLAGS_REG)
16423 (if_then_else:CC (ne (match_operand 2 "register_operand")
16425 (compare:CC (match_operand 4 "memory_operand")
16426 (match_operand 5 "memory_operand"))
16428 (use (match_operand:SI 3 "immediate_operand"))
16429 (use (reg:CC FLAGS_REG))
16430 (clobber (match_operand 0 "register_operand"))
16431 (clobber (match_operand 1 "register_operand"))
16432 (clobber (match_dup 2))])]
16434 "ix86_current_function_needs_cld = 1;")
16436 (define_insn "*cmpstrnqi_1"
16437 [(set (reg:CC FLAGS_REG)
16438 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16440 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16441 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16443 (use (match_operand:SI 3 "immediate_operand" "i"))
16444 (use (reg:CC FLAGS_REG))
16445 (clobber (match_operand:P 0 "register_operand" "=S"))
16446 (clobber (match_operand:P 1 "register_operand" "=D"))
16447 (clobber (match_operand:P 2 "register_operand" "=c"))]
16448 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16450 [(set_attr "type" "str")
16451 (set_attr "mode" "QI")
16452 (set (attr "prefix_rex")
16454 (match_test "<P:MODE>mode == DImode")
16456 (const_string "*")))
16457 (set_attr "prefix_rep" "1")])
16459 (define_expand "strlen<mode>"
16460 [(set (match_operand:P 0 "register_operand")
16461 (unspec:P [(match_operand:BLK 1 "general_operand")
16462 (match_operand:QI 2 "immediate_operand")
16463 (match_operand 3 "immediate_operand")]
16467 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16473 (define_expand "strlenqi_1"
16474 [(parallel [(set (match_operand 0 "register_operand")
16476 (clobber (match_operand 1 "register_operand"))
16477 (clobber (reg:CC FLAGS_REG))])]
16479 "ix86_current_function_needs_cld = 1;")
16481 (define_insn "*strlenqi_1"
16482 [(set (match_operand:P 0 "register_operand" "=&c")
16483 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16484 (match_operand:QI 2 "register_operand" "a")
16485 (match_operand:P 3 "immediate_operand" "i")
16486 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16487 (clobber (match_operand:P 1 "register_operand" "=D"))
16488 (clobber (reg:CC FLAGS_REG))]
16489 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16490 "%^repnz{%;} scasb"
16491 [(set_attr "type" "str")
16492 (set_attr "mode" "QI")
16493 (set (attr "prefix_rex")
16495 (match_test "<P:MODE>mode == DImode")
16497 (const_string "*")))
16498 (set_attr "prefix_rep" "1")])
16500 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16501 ;; handled in combine, but it is not currently up to the task.
16502 ;; When used for their truth value, the cmpstrn* expanders generate
16511 ;; The intermediate three instructions are unnecessary.
16513 ;; This one handles cmpstrn*_nz_1...
16516 (set (reg:CC FLAGS_REG)
16517 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16518 (mem:BLK (match_operand 5 "register_operand"))))
16519 (use (match_operand 6 "register_operand"))
16520 (use (match_operand:SI 3 "immediate_operand"))
16521 (clobber (match_operand 0 "register_operand"))
16522 (clobber (match_operand 1 "register_operand"))
16523 (clobber (match_operand 2 "register_operand"))])
16524 (set (match_operand:QI 7 "register_operand")
16525 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16526 (set (match_operand:QI 8 "register_operand")
16527 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16528 (set (reg FLAGS_REG)
16529 (compare (match_dup 7) (match_dup 8)))
16531 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16533 (set (reg:CC FLAGS_REG)
16534 (compare:CC (mem:BLK (match_dup 4))
16535 (mem:BLK (match_dup 5))))
16536 (use (match_dup 6))
16537 (use (match_dup 3))
16538 (clobber (match_dup 0))
16539 (clobber (match_dup 1))
16540 (clobber (match_dup 2))])])
16542 ;; ...and this one handles cmpstrn*_1.
16545 (set (reg:CC FLAGS_REG)
16546 (if_then_else:CC (ne (match_operand 6 "register_operand")
16548 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16549 (mem:BLK (match_operand 5 "register_operand")))
16551 (use (match_operand:SI 3 "immediate_operand"))
16552 (use (reg:CC FLAGS_REG))
16553 (clobber (match_operand 0 "register_operand"))
16554 (clobber (match_operand 1 "register_operand"))
16555 (clobber (match_operand 2 "register_operand"))])
16556 (set (match_operand:QI 7 "register_operand")
16557 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16558 (set (match_operand:QI 8 "register_operand")
16559 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16560 (set (reg FLAGS_REG)
16561 (compare (match_dup 7) (match_dup 8)))
16563 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16565 (set (reg:CC FLAGS_REG)
16566 (if_then_else:CC (ne (match_dup 6)
16568 (compare:CC (mem:BLK (match_dup 4))
16569 (mem:BLK (match_dup 5)))
16571 (use (match_dup 3))
16572 (use (reg:CC FLAGS_REG))
16573 (clobber (match_dup 0))
16574 (clobber (match_dup 1))
16575 (clobber (match_dup 2))])])
16577 ;; Conditional move instructions.
16579 (define_expand "mov<mode>cc"
16580 [(set (match_operand:SWIM 0 "register_operand")
16581 (if_then_else:SWIM (match_operand 1 "comparison_operator")
16582 (match_operand:SWIM 2 "<general_operand>")
16583 (match_operand:SWIM 3 "<general_operand>")))]
16585 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16587 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16588 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16589 ;; So just document what we're doing explicitly.
16591 (define_expand "x86_mov<mode>cc_0_m1"
16593 [(set (match_operand:SWI48 0 "register_operand")
16594 (if_then_else:SWI48
16595 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16596 [(match_operand 1 "flags_reg_operand")
16600 (clobber (reg:CC FLAGS_REG))])])
16602 (define_insn "*x86_mov<mode>cc_0_m1"
16603 [(set (match_operand:SWI48 0 "register_operand" "=r")
16604 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16605 [(reg FLAGS_REG) (const_int 0)])
16608 (clobber (reg:CC FLAGS_REG))]
16610 "sbb{<imodesuffix>}\t%0, %0"
16611 ; Since we don't have the proper number of operands for an alu insn,
16612 ; fill in all the blanks.
16613 [(set_attr "type" "alu")
16614 (set_attr "use_carry" "1")
16615 (set_attr "pent_pair" "pu")
16616 (set_attr "memory" "none")
16617 (set_attr "imm_disp" "false")
16618 (set_attr "mode" "<MODE>")
16619 (set_attr "length_immediate" "0")])
16621 (define_insn "*x86_mov<mode>cc_0_m1_se"
16622 [(set (match_operand:SWI48 0 "register_operand" "=r")
16623 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16624 [(reg FLAGS_REG) (const_int 0)])
16627 (clobber (reg:CC FLAGS_REG))]
16629 "sbb{<imodesuffix>}\t%0, %0"
16630 [(set_attr "type" "alu")
16631 (set_attr "use_carry" "1")
16632 (set_attr "pent_pair" "pu")
16633 (set_attr "memory" "none")
16634 (set_attr "imm_disp" "false")
16635 (set_attr "mode" "<MODE>")
16636 (set_attr "length_immediate" "0")])
16638 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16639 [(set (match_operand:SWI48 0 "register_operand" "=r")
16640 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16641 [(reg FLAGS_REG) (const_int 0)])))
16642 (clobber (reg:CC FLAGS_REG))]
16644 "sbb{<imodesuffix>}\t%0, %0"
16645 [(set_attr "type" "alu")
16646 (set_attr "use_carry" "1")
16647 (set_attr "pent_pair" "pu")
16648 (set_attr "memory" "none")
16649 (set_attr "imm_disp" "false")
16650 (set_attr "mode" "<MODE>")
16651 (set_attr "length_immediate" "0")])
16653 (define_insn "*mov<mode>cc_noc"
16654 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16655 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16656 [(reg FLAGS_REG) (const_int 0)])
16657 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16658 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16659 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16661 cmov%O2%C1\t{%2, %0|%0, %2}
16662 cmov%O2%c1\t{%3, %0|%0, %3}"
16663 [(set_attr "type" "icmov")
16664 (set_attr "mode" "<MODE>")])
16666 (define_insn "*movsicc_noc_zext"
16667 [(set (match_operand:DI 0 "register_operand" "=r,r")
16668 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
16669 [(reg FLAGS_REG) (const_int 0)])
16671 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
16673 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
16675 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16677 cmov%O2%C1\t{%2, %k0|%k0, %2}
16678 cmov%O2%c1\t{%3, %k0|%k0, %3}"
16679 [(set_attr "type" "icmov")
16680 (set_attr "mode" "SI")])
16682 ;; Don't do conditional moves with memory inputs. This splitter helps
16683 ;; register starved x86_32 by forcing inputs into registers before reload.
16685 [(set (match_operand:SWI248 0 "register_operand")
16686 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16687 [(reg FLAGS_REG) (const_int 0)])
16688 (match_operand:SWI248 2 "nonimmediate_operand")
16689 (match_operand:SWI248 3 "nonimmediate_operand")))]
16690 "!TARGET_64BIT && TARGET_CMOVE
16691 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16692 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16693 && can_create_pseudo_p ()
16694 && optimize_insn_for_speed_p ()"
16695 [(set (match_dup 0)
16696 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16698 if (MEM_P (operands[2]))
16699 operands[2] = force_reg (<MODE>mode, operands[2]);
16700 if (MEM_P (operands[3]))
16701 operands[3] = force_reg (<MODE>mode, operands[3]);
16704 (define_insn "*movqicc_noc"
16705 [(set (match_operand:QI 0 "register_operand" "=r,r")
16706 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16707 [(reg FLAGS_REG) (const_int 0)])
16708 (match_operand:QI 2 "register_operand" "r,0")
16709 (match_operand:QI 3 "register_operand" "0,r")))]
16710 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16712 [(set_attr "type" "icmov")
16713 (set_attr "mode" "QI")])
16716 [(set (match_operand:SWI12 0 "register_operand")
16717 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16718 [(reg FLAGS_REG) (const_int 0)])
16719 (match_operand:SWI12 2 "register_operand")
16720 (match_operand:SWI12 3 "register_operand")))]
16721 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16722 && reload_completed"
16723 [(set (match_dup 0)
16724 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16726 operands[0] = gen_lowpart (SImode, operands[0]);
16727 operands[2] = gen_lowpart (SImode, operands[2]);
16728 operands[3] = gen_lowpart (SImode, operands[3]);
16731 ;; Don't do conditional moves with memory inputs
16733 [(match_scratch:SWI248 4 "r")
16734 (set (match_operand:SWI248 0 "register_operand")
16735 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16736 [(reg FLAGS_REG) (const_int 0)])
16737 (match_operand:SWI248 2 "nonimmediate_operand")
16738 (match_operand:SWI248 3 "nonimmediate_operand")))]
16739 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16740 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16741 && optimize_insn_for_speed_p ()"
16742 [(set (match_dup 4) (match_dup 5))
16744 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16746 if (MEM_P (operands[2]))
16748 operands[5] = operands[2];
16749 operands[2] = operands[4];
16751 else if (MEM_P (operands[3]))
16753 operands[5] = operands[3];
16754 operands[3] = operands[4];
16757 gcc_unreachable ();
16761 [(match_scratch:SI 4 "r")
16762 (set (match_operand:DI 0 "register_operand")
16763 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
16764 [(reg FLAGS_REG) (const_int 0)])
16766 (match_operand:SI 2 "nonimmediate_operand"))
16768 (match_operand:SI 3 "nonimmediate_operand"))))]
16770 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16771 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16772 && optimize_insn_for_speed_p ()"
16773 [(set (match_dup 4) (match_dup 5))
16775 (if_then_else:DI (match_dup 1)
16776 (zero_extend:DI (match_dup 2))
16777 (zero_extend:DI (match_dup 3))))]
16779 if (MEM_P (operands[2]))
16781 operands[5] = operands[2];
16782 operands[2] = operands[4];
16784 else if (MEM_P (operands[3]))
16786 operands[5] = operands[3];
16787 operands[3] = operands[4];
16790 gcc_unreachable ();
16793 (define_expand "mov<mode>cc"
16794 [(set (match_operand:X87MODEF 0 "register_operand")
16795 (if_then_else:X87MODEF
16796 (match_operand 1 "comparison_operator")
16797 (match_operand:X87MODEF 2 "register_operand")
16798 (match_operand:X87MODEF 3 "register_operand")))]
16799 "(TARGET_80387 && TARGET_CMOVE)
16800 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16801 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16803 (define_insn "*movxfcc_1"
16804 [(set (match_operand:XF 0 "register_operand" "=f,f")
16805 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16806 [(reg FLAGS_REG) (const_int 0)])
16807 (match_operand:XF 2 "register_operand" "f,0")
16808 (match_operand:XF 3 "register_operand" "0,f")))]
16809 "TARGET_80387 && TARGET_CMOVE"
16811 fcmov%F1\t{%2, %0|%0, %2}
16812 fcmov%f1\t{%3, %0|%0, %3}"
16813 [(set_attr "type" "fcmov")
16814 (set_attr "mode" "XF")])
16816 (define_insn "*movdfcc_1"
16817 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16818 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16819 [(reg FLAGS_REG) (const_int 0)])
16820 (match_operand:DF 2 "nonimmediate_operand"
16822 (match_operand:DF 3 "nonimmediate_operand"
16823 "0 ,f,0 ,rm,0, rm")))]
16824 "TARGET_80387 && TARGET_CMOVE
16825 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16827 fcmov%F1\t{%2, %0|%0, %2}
16828 fcmov%f1\t{%3, %0|%0, %3}
16831 cmov%O2%C1\t{%2, %0|%0, %2}
16832 cmov%O2%c1\t{%3, %0|%0, %3}"
16833 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16834 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16835 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16838 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16839 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16840 [(reg FLAGS_REG) (const_int 0)])
16841 (match_operand:DF 2 "nonimmediate_operand")
16842 (match_operand:DF 3 "nonimmediate_operand")))]
16843 "!TARGET_64BIT && reload_completed"
16844 [(set (match_dup 2)
16845 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16847 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16849 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16850 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16853 (define_insn "*movsfcc_1_387"
16854 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16855 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16856 [(reg FLAGS_REG) (const_int 0)])
16857 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16858 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16859 "TARGET_80387 && TARGET_CMOVE
16860 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16862 fcmov%F1\t{%2, %0|%0, %2}
16863 fcmov%f1\t{%3, %0|%0, %3}
16864 cmov%O2%C1\t{%2, %0|%0, %2}
16865 cmov%O2%c1\t{%3, %0|%0, %3}"
16866 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16867 (set_attr "mode" "SF,SF,SI,SI")])
16869 ;; Don't do conditional moves with memory inputs. This splitter helps
16870 ;; register starved x86_32 by forcing inputs into registers before reload.
16872 [(set (match_operand:MODEF 0 "register_operand")
16873 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16874 [(reg FLAGS_REG) (const_int 0)])
16875 (match_operand:MODEF 2 "nonimmediate_operand")
16876 (match_operand:MODEF 3 "nonimmediate_operand")))]
16877 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16878 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16879 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16880 && can_create_pseudo_p ()
16881 && optimize_insn_for_speed_p ()"
16882 [(set (match_dup 0)
16883 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16885 if (MEM_P (operands[2]))
16886 operands[2] = force_reg (<MODE>mode, operands[2]);
16887 if (MEM_P (operands[3]))
16888 operands[3] = force_reg (<MODE>mode, operands[3]);
16891 ;; Don't do conditional moves with memory inputs
16893 [(match_scratch:MODEF 4 "r")
16894 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16895 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16896 [(reg FLAGS_REG) (const_int 0)])
16897 (match_operand:MODEF 2 "nonimmediate_operand")
16898 (match_operand:MODEF 3 "nonimmediate_operand")))]
16899 "(<MODE>mode != DFmode || TARGET_64BIT)
16900 && TARGET_80387 && TARGET_CMOVE
16901 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16902 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16903 && optimize_insn_for_speed_p ()"
16904 [(set (match_dup 4) (match_dup 5))
16906 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16908 if (MEM_P (operands[2]))
16910 operands[5] = operands[2];
16911 operands[2] = operands[4];
16913 else if (MEM_P (operands[3]))
16915 operands[5] = operands[3];
16916 operands[3] = operands[4];
16919 gcc_unreachable ();
16922 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16923 ;; the scalar versions to have only XMM registers as operands.
16925 ;; XOP conditional move
16926 (define_insn "*xop_pcmov_<mode>"
16927 [(set (match_operand:MODEF 0 "register_operand" "=x")
16928 (if_then_else:MODEF
16929 (match_operand:MODEF 1 "register_operand" "x")
16930 (match_operand:MODEF 2 "register_operand" "x")
16931 (match_operand:MODEF 3 "register_operand" "x")))]
16933 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16934 [(set_attr "type" "sse4arg")])
16936 ;; These versions of the min/max patterns are intentionally ignorant of
16937 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16938 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16939 ;; are undefined in this condition, we're certain this is correct.
16941 (define_insn "<code><mode>3"
16942 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16944 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16945 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16946 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16948 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16949 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16950 [(set_attr "isa" "noavx,avx")
16951 (set_attr "prefix" "orig,vex")
16952 (set_attr "type" "sseadd")
16953 (set_attr "mode" "<MODE>")])
16955 ;; These versions of the min/max patterns implement exactly the operations
16956 ;; min = (op1 < op2 ? op1 : op2)
16957 ;; max = (!(op1 < op2) ? op1 : op2)
16958 ;; Their operands are not commutative, and thus they may be used in the
16959 ;; presence of -0.0 and NaN.
16961 (define_int_iterator IEEE_MAXMIN
16965 (define_int_attr ieee_maxmin
16966 [(UNSPEC_IEEE_MAX "max")
16967 (UNSPEC_IEEE_MIN "min")])
16969 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16970 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16972 [(match_operand:MODEF 1 "register_operand" "0,v")
16973 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
16975 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16977 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16978 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16979 [(set_attr "isa" "noavx,avx")
16980 (set_attr "prefix" "orig,maybe_evex")
16981 (set_attr "type" "sseadd")
16982 (set_attr "mode" "<MODE>")])
16984 ;; Make two stack loads independent:
16986 ;; fld %st(0) -> fld bb
16987 ;; fmul bb fmul %st(1), %st
16989 ;; Actually we only match the last two instructions for simplicity.
16991 [(set (match_operand 0 "fp_register_operand")
16992 (match_operand 1 "fp_register_operand"))
16994 (match_operator 2 "binary_fp_operator"
16996 (match_operand 3 "memory_operand")]))]
16997 "REGNO (operands[0]) != REGNO (operands[1])"
16998 [(set (match_dup 0) (match_dup 3))
16999 (set (match_dup 0) (match_dup 4))]
17001 ;; The % modifier is not operational anymore in peephole2's, so we have to
17002 ;; swap the operands manually in the case of addition and multiplication.
17006 if (COMMUTATIVE_ARITH_P (operands[2]))
17007 op0 = operands[0], op1 = operands[1];
17009 op0 = operands[1], op1 = operands[0];
17011 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
17012 GET_MODE (operands[2]),
17016 ;; Conditional addition patterns
17017 (define_expand "add<mode>cc"
17018 [(match_operand:SWI 0 "register_operand")
17019 (match_operand 1 "ordered_comparison_operator")
17020 (match_operand:SWI 2 "register_operand")
17021 (match_operand:SWI 3 "const_int_operand")]
17023 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17025 ;; Misc patterns (?)
17027 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17028 ;; Otherwise there will be nothing to keep
17030 ;; [(set (reg ebp) (reg esp))]
17031 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17032 ;; (clobber (eflags)]
17033 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17035 ;; in proper program order.
17037 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
17038 [(set (match_operand:P 0 "register_operand" "=r,r")
17039 (plus:P (match_operand:P 1 "register_operand" "0,r")
17040 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17041 (clobber (reg:CC FLAGS_REG))
17042 (clobber (mem:BLK (scratch)))]
17045 switch (get_attr_type (insn))
17048 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17051 gcc_assert (rtx_equal_p (operands[0], operands[1]));
17052 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17053 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17055 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17058 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17059 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17062 [(set (attr "type")
17063 (cond [(and (eq_attr "alternative" "0")
17064 (not (match_test "TARGET_OPT_AGU")))
17065 (const_string "alu")
17066 (match_operand:<MODE> 2 "const0_operand")
17067 (const_string "imov")
17069 (const_string "lea")))
17070 (set (attr "length_immediate")
17071 (cond [(eq_attr "type" "imov")
17073 (and (eq_attr "type" "alu")
17074 (match_operand 2 "const128_operand"))
17077 (const_string "*")))
17078 (set_attr "mode" "<MODE>")])
17080 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
17081 [(set (match_operand:P 0 "register_operand" "=r")
17082 (minus:P (match_operand:P 1 "register_operand" "0")
17083 (match_operand:P 2 "register_operand" "r")))
17084 (clobber (reg:CC FLAGS_REG))
17085 (clobber (mem:BLK (scratch)))]
17087 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17088 [(set_attr "type" "alu")
17089 (set_attr "mode" "<MODE>")])
17091 (define_insn "allocate_stack_worker_probe_<mode>"
17092 [(set (match_operand:P 0 "register_operand" "=a")
17093 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17094 UNSPECV_STACK_PROBE))
17095 (clobber (reg:CC FLAGS_REG))]
17096 "ix86_target_stack_probe ()"
17097 "call\t___chkstk_ms"
17098 [(set_attr "type" "multi")
17099 (set_attr "length" "5")])
17101 (define_expand "allocate_stack"
17102 [(match_operand 0 "register_operand")
17103 (match_operand 1 "general_operand")]
17104 "ix86_target_stack_probe ()"
17108 #ifndef CHECK_STACK_LIMIT
17109 #define CHECK_STACK_LIMIT 0
17112 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17113 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17117 rtx (*insn) (rtx, rtx);
17119 x = copy_to_mode_reg (Pmode, operands[1]);
17121 insn = (TARGET_64BIT
17122 ? gen_allocate_stack_worker_probe_di
17123 : gen_allocate_stack_worker_probe_si);
17125 emit_insn (insn (x, x));
17128 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17129 stack_pointer_rtx, 0, OPTAB_DIRECT);
17131 if (x != stack_pointer_rtx)
17132 emit_move_insn (stack_pointer_rtx, x);
17134 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17138 ;; Use IOR for stack probes, this is shorter.
17139 (define_expand "probe_stack"
17140 [(match_operand 0 "memory_operand")]
17143 rtx (*gen_ior3) (rtx, rtx, rtx);
17145 gen_ior3 = (GET_MODE (operands[0]) == DImode
17146 ? gen_iordi3 : gen_iorsi3);
17148 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
17152 (define_insn "adjust_stack_and_probe<mode>"
17153 [(set (match_operand:P 0 "register_operand" "=r")
17154 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17155 UNSPECV_PROBE_STACK_RANGE))
17156 (set (reg:P SP_REG)
17157 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17158 (clobber (reg:CC FLAGS_REG))
17159 (clobber (mem:BLK (scratch)))]
17161 "* return output_adjust_stack_and_probe (operands[0]);"
17162 [(set_attr "type" "multi")])
17164 (define_insn "probe_stack_range<mode>"
17165 [(set (match_operand:P 0 "register_operand" "=r")
17166 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17167 (match_operand:P 2 "const_int_operand" "n")]
17168 UNSPECV_PROBE_STACK_RANGE))
17169 (clobber (reg:CC FLAGS_REG))]
17171 "* return output_probe_stack_range (operands[0], operands[2]);"
17172 [(set_attr "type" "multi")])
17174 (define_expand "builtin_setjmp_receiver"
17175 [(label_ref (match_operand 0))]
17176 "!TARGET_64BIT && flag_pic"
17182 rtx_code_label *label_rtx = gen_label_rtx ();
17183 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17184 xops[0] = xops[1] = pic_offset_table_rtx;
17185 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17186 ix86_expand_binary_operator (MINUS, SImode, xops);
17190 emit_insn (gen_set_got (pic_offset_table_rtx));
17194 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17195 ;; Do not split instructions with mask registers.
17197 [(set (match_operand 0 "general_reg_operand")
17198 (match_operator 3 "promotable_binary_operator"
17199 [(match_operand 1 "general_reg_operand")
17200 (match_operand 2 "aligned_operand")]))
17201 (clobber (reg:CC FLAGS_REG))]
17202 "! TARGET_PARTIAL_REG_STALL && reload_completed
17203 && ((GET_MODE (operands[0]) == HImode
17204 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17205 /* ??? next two lines just !satisfies_constraint_K (...) */
17206 || !CONST_INT_P (operands[2])
17207 || satisfies_constraint_K (operands[2])))
17208 || (GET_MODE (operands[0]) == QImode
17209 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17210 [(parallel [(set (match_dup 0)
17211 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17212 (clobber (reg:CC FLAGS_REG))])]
17214 operands[0] = gen_lowpart (SImode, operands[0]);
17215 operands[1] = gen_lowpart (SImode, operands[1]);
17216 if (GET_CODE (operands[3]) != ASHIFT)
17217 operands[2] = gen_lowpart (SImode, operands[2]);
17218 operands[3] = shallow_copy_rtx (operands[3]);
17219 PUT_MODE (operands[3], SImode);
17222 ; Promote the QImode tests, as i386 has encoding of the AND
17223 ; instruction with 32-bit sign-extended immediate and thus the
17224 ; instruction size is unchanged, except in the %eax case for
17225 ; which it is increased by one byte, hence the ! optimize_size.
17227 [(set (match_operand 0 "flags_reg_operand")
17228 (match_operator 2 "compare_operator"
17229 [(and (match_operand 3 "aligned_operand")
17230 (match_operand 4 "const_int_operand"))
17232 (set (match_operand 1 "register_operand")
17233 (and (match_dup 3) (match_dup 4)))]
17234 "! TARGET_PARTIAL_REG_STALL && reload_completed
17235 && optimize_insn_for_speed_p ()
17236 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17237 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17238 /* Ensure that the operand will remain sign-extended immediate. */
17239 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17240 [(parallel [(set (match_dup 0)
17241 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17244 (and:SI (match_dup 3) (match_dup 4)))])]
17247 = gen_int_mode (INTVAL (operands[4])
17248 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17249 operands[1] = gen_lowpart (SImode, operands[1]);
17250 operands[3] = gen_lowpart (SImode, operands[3]);
17253 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17254 ; the TEST instruction with 32-bit sign-extended immediate and thus
17255 ; the instruction size would at least double, which is not what we
17256 ; want even with ! optimize_size.
17258 [(set (match_operand 0 "flags_reg_operand")
17259 (match_operator 1 "compare_operator"
17260 [(and (match_operand:HI 2 "aligned_operand")
17261 (match_operand:HI 3 "const_int_operand"))
17263 "! TARGET_PARTIAL_REG_STALL && reload_completed
17264 && ! TARGET_FAST_PREFIX
17265 && optimize_insn_for_speed_p ()
17266 /* Ensure that the operand will remain sign-extended immediate. */
17267 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17268 [(set (match_dup 0)
17269 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17273 = gen_int_mode (INTVAL (operands[3])
17274 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17275 operands[2] = gen_lowpart (SImode, operands[2]);
17279 [(set (match_operand 0 "register_operand")
17280 (neg (match_operand 1 "register_operand")))
17281 (clobber (reg:CC FLAGS_REG))]
17282 "! TARGET_PARTIAL_REG_STALL && reload_completed
17283 && (GET_MODE (operands[0]) == HImode
17284 || (GET_MODE (operands[0]) == QImode
17285 && (TARGET_PROMOTE_QImode
17286 || optimize_insn_for_size_p ())))"
17287 [(parallel [(set (match_dup 0)
17288 (neg:SI (match_dup 1)))
17289 (clobber (reg:CC FLAGS_REG))])]
17291 operands[0] = gen_lowpart (SImode, operands[0]);
17292 operands[1] = gen_lowpart (SImode, operands[1]);
17295 ;; Do not split instructions with mask regs.
17297 [(set (match_operand 0 "general_reg_operand")
17298 (not (match_operand 1 "general_reg_operand")))]
17299 "! TARGET_PARTIAL_REG_STALL && reload_completed
17300 && (GET_MODE (operands[0]) == HImode
17301 || (GET_MODE (operands[0]) == QImode
17302 && (TARGET_PROMOTE_QImode
17303 || optimize_insn_for_size_p ())))"
17304 [(set (match_dup 0)
17305 (not:SI (match_dup 1)))]
17307 operands[0] = gen_lowpart (SImode, operands[0]);
17308 operands[1] = gen_lowpart (SImode, operands[1]);
17311 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17312 ;; transform a complex memory operation into two memory to register operations.
17314 ;; Don't push memory operands
17316 [(set (match_operand:SWI 0 "push_operand")
17317 (match_operand:SWI 1 "memory_operand"))
17318 (match_scratch:SWI 2 "<r>")]
17319 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17320 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17321 [(set (match_dup 2) (match_dup 1))
17322 (set (match_dup 0) (match_dup 2))])
17324 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17327 [(set (match_operand:SF 0 "push_operand")
17328 (match_operand:SF 1 "memory_operand"))
17329 (match_scratch:SF 2 "r")]
17330 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17331 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17332 [(set (match_dup 2) (match_dup 1))
17333 (set (match_dup 0) (match_dup 2))])
17335 ;; Don't move an immediate directly to memory when the instruction
17336 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17338 [(match_scratch:SWI124 1 "<r>")
17339 (set (match_operand:SWI124 0 "memory_operand")
17341 "optimize_insn_for_speed_p ()
17342 && ((<MODE>mode == HImode
17343 && TARGET_LCP_STALL)
17344 || (!TARGET_USE_MOV0
17345 && TARGET_SPLIT_LONG_MOVES
17346 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17347 && peep2_regno_dead_p (0, FLAGS_REG)"
17348 [(parallel [(set (match_dup 2) (const_int 0))
17349 (clobber (reg:CC FLAGS_REG))])
17350 (set (match_dup 0) (match_dup 1))]
17351 "operands[2] = gen_lowpart (SImode, operands[1]);")
17354 [(match_scratch:SWI124 2 "<r>")
17355 (set (match_operand:SWI124 0 "memory_operand")
17356 (match_operand:SWI124 1 "immediate_operand"))]
17357 "optimize_insn_for_speed_p ()
17358 && ((<MODE>mode == HImode
17359 && TARGET_LCP_STALL)
17360 || (TARGET_SPLIT_LONG_MOVES
17361 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17362 [(set (match_dup 2) (match_dup 1))
17363 (set (match_dup 0) (match_dup 2))])
17365 ;; Don't compare memory with zero, load and use a test instead.
17367 [(set (match_operand 0 "flags_reg_operand")
17368 (match_operator 1 "compare_operator"
17369 [(match_operand:SI 2 "memory_operand")
17371 (match_scratch:SI 3 "r")]
17372 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17373 [(set (match_dup 3) (match_dup 2))
17374 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17376 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17377 ;; Don't split NOTs with a displacement operand, because resulting XOR
17378 ;; will not be pairable anyway.
17380 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17381 ;; represented using a modRM byte. The XOR replacement is long decoded,
17382 ;; so this split helps here as well.
17384 ;; Note: Can't do this as a regular split because we can't get proper
17385 ;; lifetime information then.
17388 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
17389 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
17390 "optimize_insn_for_speed_p ()
17391 && ((TARGET_NOT_UNPAIRABLE
17392 && (!MEM_P (operands[0])
17393 || !memory_displacement_operand (operands[0], <MODE>mode)))
17394 || (TARGET_NOT_VECTORMODE
17395 && long_memory_operand (operands[0], <MODE>mode)))
17396 && peep2_regno_dead_p (0, FLAGS_REG)"
17397 [(parallel [(set (match_dup 0)
17398 (xor:SWI124 (match_dup 1) (const_int -1)))
17399 (clobber (reg:CC FLAGS_REG))])])
17401 ;; Non pairable "test imm, reg" instructions can be translated to
17402 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17403 ;; byte opcode instead of two, have a short form for byte operands),
17404 ;; so do it for other CPUs as well. Given that the value was dead,
17405 ;; this should not create any new dependencies. Pass on the sub-word
17406 ;; versions if we're concerned about partial register stalls.
17409 [(set (match_operand 0 "flags_reg_operand")
17410 (match_operator 1 "compare_operator"
17411 [(and:SI (match_operand:SI 2 "register_operand")
17412 (match_operand:SI 3 "immediate_operand"))
17414 "ix86_match_ccmode (insn, CCNOmode)
17415 && (true_regnum (operands[2]) != AX_REG
17416 || satisfies_constraint_K (operands[3]))
17417 && peep2_reg_dead_p (1, operands[2])"
17419 [(set (match_dup 0)
17420 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17423 (and:SI (match_dup 2) (match_dup 3)))])])
17425 ;; We don't need to handle HImode case, because it will be promoted to SImode
17426 ;; on ! TARGET_PARTIAL_REG_STALL
17429 [(set (match_operand 0 "flags_reg_operand")
17430 (match_operator 1 "compare_operator"
17431 [(and:QI (match_operand:QI 2 "register_operand")
17432 (match_operand:QI 3 "immediate_operand"))
17434 "! TARGET_PARTIAL_REG_STALL
17435 && ix86_match_ccmode (insn, CCNOmode)
17436 && true_regnum (operands[2]) != AX_REG
17437 && peep2_reg_dead_p (1, operands[2])"
17439 [(set (match_dup 0)
17440 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17443 (and:QI (match_dup 2) (match_dup 3)))])])
17446 [(set (match_operand 0 "flags_reg_operand")
17447 (match_operator 1 "compare_operator"
17450 (match_operand 2 "QIreg_operand")
17453 (match_operand 3 "const_int_operand"))
17455 "! TARGET_PARTIAL_REG_STALL
17456 && ix86_match_ccmode (insn, CCNOmode)
17457 && true_regnum (operands[2]) != AX_REG
17458 && peep2_reg_dead_p (1, operands[2])"
17459 [(parallel [(set (match_dup 0)
17468 (set (zero_extract:SI (match_dup 2)
17476 (match_dup 3)))])])
17478 ;; Don't do logical operations with memory inputs.
17480 [(match_scratch:SI 2 "r")
17481 (parallel [(set (match_operand:SI 0 "register_operand")
17482 (match_operator:SI 3 "arith_or_logical_operator"
17484 (match_operand:SI 1 "memory_operand")]))
17485 (clobber (reg:CC FLAGS_REG))])]
17486 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17487 [(set (match_dup 2) (match_dup 1))
17488 (parallel [(set (match_dup 0)
17489 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17490 (clobber (reg:CC FLAGS_REG))])])
17493 [(match_scratch:SI 2 "r")
17494 (parallel [(set (match_operand:SI 0 "register_operand")
17495 (match_operator:SI 3 "arith_or_logical_operator"
17496 [(match_operand:SI 1 "memory_operand")
17498 (clobber (reg:CC FLAGS_REG))])]
17499 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17500 [(set (match_dup 2) (match_dup 1))
17501 (parallel [(set (match_dup 0)
17502 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17503 (clobber (reg:CC FLAGS_REG))])])
17505 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17506 ;; refers to the destination of the load!
17509 [(set (match_operand:SI 0 "register_operand")
17510 (match_operand:SI 1 "register_operand"))
17511 (parallel [(set (match_dup 0)
17512 (match_operator:SI 3 "commutative_operator"
17514 (match_operand:SI 2 "memory_operand")]))
17515 (clobber (reg:CC FLAGS_REG))])]
17516 "REGNO (operands[0]) != REGNO (operands[1])
17517 && GENERAL_REGNO_P (REGNO (operands[0]))
17518 && GENERAL_REGNO_P (REGNO (operands[1]))"
17519 [(set (match_dup 0) (match_dup 4))
17520 (parallel [(set (match_dup 0)
17521 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17522 (clobber (reg:CC FLAGS_REG))])]
17523 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17526 [(set (match_operand 0 "register_operand")
17527 (match_operand 1 "register_operand"))
17529 (match_operator 3 "commutative_operator"
17531 (match_operand 2 "memory_operand")]))]
17532 "REGNO (operands[0]) != REGNO (operands[1])
17533 && ((MMX_REGNO_P (REGNO (operands[0]))
17534 && MMX_REGNO_P (REGNO (operands[1])))
17535 || (SSE_REGNO_P (REGNO (operands[0]))
17536 && SSE_REGNO_P (REGNO (operands[1]))))"
17537 [(set (match_dup 0) (match_dup 2))
17539 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17541 ; Don't do logical operations with memory outputs
17543 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17544 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17545 ; the same decoder scheduling characteristics as the original.
17548 [(match_scratch:SI 2 "r")
17549 (parallel [(set (match_operand:SI 0 "memory_operand")
17550 (match_operator:SI 3 "arith_or_logical_operator"
17552 (match_operand:SI 1 "nonmemory_operand")]))
17553 (clobber (reg:CC FLAGS_REG))])]
17554 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17555 /* Do not split stack checking probes. */
17556 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17557 [(set (match_dup 2) (match_dup 0))
17558 (parallel [(set (match_dup 2)
17559 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17560 (clobber (reg:CC FLAGS_REG))])
17561 (set (match_dup 0) (match_dup 2))])
17564 [(match_scratch:SI 2 "r")
17565 (parallel [(set (match_operand:SI 0 "memory_operand")
17566 (match_operator:SI 3 "arith_or_logical_operator"
17567 [(match_operand:SI 1 "nonmemory_operand")
17569 (clobber (reg:CC FLAGS_REG))])]
17570 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17571 /* Do not split stack checking probes. */
17572 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17573 [(set (match_dup 2) (match_dup 0))
17574 (parallel [(set (match_dup 2)
17575 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17576 (clobber (reg:CC FLAGS_REG))])
17577 (set (match_dup 0) (match_dup 2))])
17579 ;; Attempt to use arith or logical operations with memory outputs with
17580 ;; setting of flags.
17582 [(set (match_operand:SWI 0 "register_operand")
17583 (match_operand:SWI 1 "memory_operand"))
17584 (parallel [(set (match_dup 0)
17585 (match_operator:SWI 3 "plusminuslogic_operator"
17587 (match_operand:SWI 2 "<nonmemory_operand>")]))
17588 (clobber (reg:CC FLAGS_REG))])
17589 (set (match_dup 1) (match_dup 0))
17590 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17591 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17592 && peep2_reg_dead_p (4, operands[0])
17593 && !reg_overlap_mentioned_p (operands[0], operands[1])
17594 && !reg_overlap_mentioned_p (operands[0], operands[2])
17595 && (<MODE>mode != QImode
17596 || immediate_operand (operands[2], QImode)
17597 || any_QIreg_operand (operands[2], QImode))
17598 && ix86_match_ccmode (peep2_next_insn (3),
17599 (GET_CODE (operands[3]) == PLUS
17600 || GET_CODE (operands[3]) == MINUS)
17601 ? CCGOCmode : CCNOmode)"
17602 [(parallel [(set (match_dup 4) (match_dup 5))
17603 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17604 (match_dup 2)]))])]
17606 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17607 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17608 copy_rtx (operands[1]),
17609 copy_rtx (operands[2]));
17610 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17611 operands[5], const0_rtx);
17615 [(parallel [(set (match_operand:SWI 0 "register_operand")
17616 (match_operator:SWI 2 "plusminuslogic_operator"
17618 (match_operand:SWI 1 "memory_operand")]))
17619 (clobber (reg:CC FLAGS_REG))])
17620 (set (match_dup 1) (match_dup 0))
17621 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17622 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17623 && GET_CODE (operands[2]) != MINUS
17624 && peep2_reg_dead_p (3, operands[0])
17625 && !reg_overlap_mentioned_p (operands[0], operands[1])
17626 && ix86_match_ccmode (peep2_next_insn (2),
17627 GET_CODE (operands[2]) == PLUS
17628 ? CCGOCmode : CCNOmode)"
17629 [(parallel [(set (match_dup 3) (match_dup 4))
17630 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17631 (match_dup 0)]))])]
17633 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17634 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17635 copy_rtx (operands[1]),
17636 copy_rtx (operands[0]));
17637 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17638 operands[4], const0_rtx);
17642 [(set (match_operand:SWI12 0 "register_operand")
17643 (match_operand:SWI12 1 "memory_operand"))
17644 (parallel [(set (match_operand:SI 4 "register_operand")
17645 (match_operator:SI 3 "plusminuslogic_operator"
17647 (match_operand:SI 2 "nonmemory_operand")]))
17648 (clobber (reg:CC FLAGS_REG))])
17649 (set (match_dup 1) (match_dup 0))
17650 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17651 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17652 && REG_P (operands[0]) && REG_P (operands[4])
17653 && REGNO (operands[0]) == REGNO (operands[4])
17654 && peep2_reg_dead_p (4, operands[0])
17655 && (<MODE>mode != QImode
17656 || immediate_operand (operands[2], SImode)
17657 || any_QIreg_operand (operands[2], SImode))
17658 && !reg_overlap_mentioned_p (operands[0], operands[1])
17659 && !reg_overlap_mentioned_p (operands[0], operands[2])
17660 && ix86_match_ccmode (peep2_next_insn (3),
17661 (GET_CODE (operands[3]) == PLUS
17662 || GET_CODE (operands[3]) == MINUS)
17663 ? CCGOCmode : CCNOmode)"
17664 [(parallel [(set (match_dup 4) (match_dup 5))
17665 (set (match_dup 1) (match_dup 6))])]
17667 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17668 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17669 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17670 copy_rtx (operands[1]), operands[2]);
17671 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17672 operands[5], const0_rtx);
17673 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17674 copy_rtx (operands[1]),
17675 copy_rtx (operands[2]));
17678 ;; Attempt to always use XOR for zeroing registers.
17680 [(set (match_operand 0 "register_operand")
17681 (match_operand 1 "const0_operand"))]
17682 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17683 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17684 && GENERAL_REGNO_P (REGNO (operands[0]))
17685 && peep2_regno_dead_p (0, FLAGS_REG)"
17686 [(parallel [(set (match_dup 0) (const_int 0))
17687 (clobber (reg:CC FLAGS_REG))])]
17688 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17691 [(set (strict_low_part (match_operand 0 "register_operand"))
17693 "(GET_MODE (operands[0]) == QImode
17694 || GET_MODE (operands[0]) == HImode)
17695 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17696 && peep2_regno_dead_p (0, FLAGS_REG)"
17697 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17698 (clobber (reg:CC FLAGS_REG))])])
17700 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17702 [(set (match_operand:SWI248 0 "register_operand")
17704 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17705 && GENERAL_REGNO_P (REGNO (operands[0]))
17706 && peep2_regno_dead_p (0, FLAGS_REG)"
17707 [(parallel [(set (match_dup 0) (const_int -1))
17708 (clobber (reg:CC FLAGS_REG))])]
17710 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
17711 operands[0] = gen_lowpart (SImode, operands[0]);
17714 ;; Attempt to convert simple lea to add/shift.
17715 ;; These can be created by move expanders.
17716 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17717 ;; relevant lea instructions were already split.
17720 [(set (match_operand:SWI48 0 "register_operand")
17721 (plus:SWI48 (match_dup 0)
17722 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17724 && peep2_regno_dead_p (0, FLAGS_REG)"
17725 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17726 (clobber (reg:CC FLAGS_REG))])])
17729 [(set (match_operand:SWI48 0 "register_operand")
17730 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17733 && peep2_regno_dead_p (0, FLAGS_REG)"
17734 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17735 (clobber (reg:CC FLAGS_REG))])])
17738 [(set (match_operand:DI 0 "register_operand")
17740 (plus:SI (match_operand:SI 1 "register_operand")
17741 (match_operand:SI 2 "nonmemory_operand"))))]
17742 "TARGET_64BIT && !TARGET_OPT_AGU
17743 && REGNO (operands[0]) == REGNO (operands[1])
17744 && peep2_regno_dead_p (0, FLAGS_REG)"
17745 [(parallel [(set (match_dup 0)
17746 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17747 (clobber (reg:CC FLAGS_REG))])])
17750 [(set (match_operand:DI 0 "register_operand")
17752 (plus:SI (match_operand:SI 1 "nonmemory_operand")
17753 (match_operand:SI 2 "register_operand"))))]
17754 "TARGET_64BIT && !TARGET_OPT_AGU
17755 && REGNO (operands[0]) == REGNO (operands[2])
17756 && peep2_regno_dead_p (0, FLAGS_REG)"
17757 [(parallel [(set (match_dup 0)
17758 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17759 (clobber (reg:CC FLAGS_REG))])])
17762 [(set (match_operand:SWI48 0 "register_operand")
17763 (mult:SWI48 (match_dup 0)
17764 (match_operand:SWI48 1 "const_int_operand")))]
17765 "exact_log2 (INTVAL (operands[1])) >= 0
17766 && peep2_regno_dead_p (0, FLAGS_REG)"
17767 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17768 (clobber (reg:CC FLAGS_REG))])]
17769 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17772 [(set (match_operand:DI 0 "register_operand")
17774 (mult:SI (match_operand:SI 1 "register_operand")
17775 (match_operand:SI 2 "const_int_operand"))))]
17777 && exact_log2 (INTVAL (operands[2])) >= 0
17778 && REGNO (operands[0]) == REGNO (operands[1])
17779 && peep2_regno_dead_p (0, FLAGS_REG)"
17780 [(parallel [(set (match_dup 0)
17781 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17782 (clobber (reg:CC FLAGS_REG))])]
17783 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17785 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17786 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17787 ;; On many CPUs it is also faster, since special hardware to avoid esp
17788 ;; dependencies is present.
17790 ;; While some of these conversions may be done using splitters, we use
17791 ;; peepholes in order to allow combine_stack_adjustments pass to see
17792 ;; nonobfuscated RTL.
17794 ;; Convert prologue esp subtractions to push.
17795 ;; We need register to push. In order to keep verify_flow_info happy we have
17797 ;; - use scratch and clobber it in order to avoid dependencies
17798 ;; - use already live register
17799 ;; We can't use the second way right now, since there is no reliable way how to
17800 ;; verify that given register is live. First choice will also most likely in
17801 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17802 ;; call clobbered registers are dead. We may want to use base pointer as an
17803 ;; alternative when no register is available later.
17806 [(match_scratch:W 1 "r")
17807 (parallel [(set (reg:P SP_REG)
17808 (plus:P (reg:P SP_REG)
17809 (match_operand:P 0 "const_int_operand")))
17810 (clobber (reg:CC FLAGS_REG))
17811 (clobber (mem:BLK (scratch)))])]
17812 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17813 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17814 [(clobber (match_dup 1))
17815 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17816 (clobber (mem:BLK (scratch)))])])
17819 [(match_scratch:W 1 "r")
17820 (parallel [(set (reg:P SP_REG)
17821 (plus:P (reg:P SP_REG)
17822 (match_operand:P 0 "const_int_operand")))
17823 (clobber (reg:CC FLAGS_REG))
17824 (clobber (mem:BLK (scratch)))])]
17825 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17826 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17827 [(clobber (match_dup 1))
17828 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17829 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17830 (clobber (mem:BLK (scratch)))])])
17832 ;; Convert esp subtractions to push.
17834 [(match_scratch:W 1 "r")
17835 (parallel [(set (reg:P SP_REG)
17836 (plus:P (reg:P SP_REG)
17837 (match_operand:P 0 "const_int_operand")))
17838 (clobber (reg:CC FLAGS_REG))])]
17839 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17840 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17841 [(clobber (match_dup 1))
17842 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17845 [(match_scratch:W 1 "r")
17846 (parallel [(set (reg:P SP_REG)
17847 (plus:P (reg:P SP_REG)
17848 (match_operand:P 0 "const_int_operand")))
17849 (clobber (reg:CC FLAGS_REG))])]
17850 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17851 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17852 [(clobber (match_dup 1))
17853 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17854 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17856 ;; Convert epilogue deallocator to pop.
17858 [(match_scratch:W 1 "r")
17859 (parallel [(set (reg:P SP_REG)
17860 (plus:P (reg:P SP_REG)
17861 (match_operand:P 0 "const_int_operand")))
17862 (clobber (reg:CC FLAGS_REG))
17863 (clobber (mem:BLK (scratch)))])]
17864 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17865 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17866 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17867 (clobber (mem:BLK (scratch)))])])
17869 ;; Two pops case is tricky, since pop causes dependency
17870 ;; on destination register. We use two registers if available.
17872 [(match_scratch:W 1 "r")
17873 (match_scratch:W 2 "r")
17874 (parallel [(set (reg:P SP_REG)
17875 (plus:P (reg:P SP_REG)
17876 (match_operand:P 0 "const_int_operand")))
17877 (clobber (reg:CC FLAGS_REG))
17878 (clobber (mem:BLK (scratch)))])]
17879 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17880 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17881 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17882 (clobber (mem:BLK (scratch)))])
17883 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17886 [(match_scratch:W 1 "r")
17887 (parallel [(set (reg:P SP_REG)
17888 (plus:P (reg:P SP_REG)
17889 (match_operand:P 0 "const_int_operand")))
17890 (clobber (reg:CC FLAGS_REG))
17891 (clobber (mem:BLK (scratch)))])]
17892 "optimize_insn_for_size_p ()
17893 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17894 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17895 (clobber (mem:BLK (scratch)))])
17896 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17898 ;; Convert esp additions to pop.
17900 [(match_scratch:W 1 "r")
17901 (parallel [(set (reg:P SP_REG)
17902 (plus:P (reg:P SP_REG)
17903 (match_operand:P 0 "const_int_operand")))
17904 (clobber (reg:CC FLAGS_REG))])]
17905 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17906 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17908 ;; Two pops case is tricky, since pop causes dependency
17909 ;; on destination register. We use two registers if available.
17911 [(match_scratch:W 1 "r")
17912 (match_scratch:W 2 "r")
17913 (parallel [(set (reg:P SP_REG)
17914 (plus:P (reg:P SP_REG)
17915 (match_operand:P 0 "const_int_operand")))
17916 (clobber (reg:CC FLAGS_REG))])]
17917 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17918 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17919 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17922 [(match_scratch:W 1 "r")
17923 (parallel [(set (reg:P SP_REG)
17924 (plus:P (reg:P SP_REG)
17925 (match_operand:P 0 "const_int_operand")))
17926 (clobber (reg:CC FLAGS_REG))])]
17927 "optimize_insn_for_size_p ()
17928 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17929 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17930 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17932 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17933 ;; required and register dies. Similarly for 128 to -128.
17935 [(set (match_operand 0 "flags_reg_operand")
17936 (match_operator 1 "compare_operator"
17937 [(match_operand 2 "register_operand")
17938 (match_operand 3 "const_int_operand")]))]
17939 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17940 && incdec_operand (operands[3], GET_MODE (operands[3])))
17941 || (!TARGET_FUSE_CMP_AND_BRANCH
17942 && INTVAL (operands[3]) == 128))
17943 && ix86_match_ccmode (insn, CCGCmode)
17944 && peep2_reg_dead_p (1, operands[2])"
17945 [(parallel [(set (match_dup 0)
17946 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17947 (clobber (match_dup 2))])])
17949 ;; Convert imul by three, five and nine into lea
17952 [(set (match_operand:SWI48 0 "register_operand")
17953 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17954 (match_operand:SWI48 2 "const359_operand")))
17955 (clobber (reg:CC FLAGS_REG))])]
17956 "!TARGET_PARTIAL_REG_STALL
17957 || <MODE>mode == SImode
17958 || optimize_function_for_size_p (cfun)"
17959 [(set (match_dup 0)
17960 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17962 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17966 [(set (match_operand:SWI48 0 "register_operand")
17967 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17968 (match_operand:SWI48 2 "const359_operand")))
17969 (clobber (reg:CC FLAGS_REG))])]
17970 "optimize_insn_for_speed_p ()
17971 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17972 [(set (match_dup 0) (match_dup 1))
17974 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17976 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17978 ;; imul $32bit_imm, mem, reg is vector decoded, while
17979 ;; imul $32bit_imm, reg, reg is direct decoded.
17981 [(match_scratch:SWI48 3 "r")
17982 (parallel [(set (match_operand:SWI48 0 "register_operand")
17983 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17984 (match_operand:SWI48 2 "immediate_operand")))
17985 (clobber (reg:CC FLAGS_REG))])]
17986 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17987 && !satisfies_constraint_K (operands[2])"
17988 [(set (match_dup 3) (match_dup 1))
17989 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17990 (clobber (reg:CC FLAGS_REG))])])
17993 [(match_scratch:SI 3 "r")
17994 (parallel [(set (match_operand:DI 0 "register_operand")
17996 (mult:SI (match_operand:SI 1 "memory_operand")
17997 (match_operand:SI 2 "immediate_operand"))))
17998 (clobber (reg:CC FLAGS_REG))])]
18000 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18001 && !satisfies_constraint_K (operands[2])"
18002 [(set (match_dup 3) (match_dup 1))
18003 (parallel [(set (match_dup 0)
18004 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18005 (clobber (reg:CC FLAGS_REG))])])
18007 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18008 ;; Convert it into imul reg, reg
18009 ;; It would be better to force assembler to encode instruction using long
18010 ;; immediate, but there is apparently no way to do so.
18012 [(parallel [(set (match_operand:SWI248 0 "register_operand")
18014 (match_operand:SWI248 1 "nonimmediate_operand")
18015 (match_operand:SWI248 2 "const_int_operand")))
18016 (clobber (reg:CC FLAGS_REG))])
18017 (match_scratch:SWI248 3 "r")]
18018 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18019 && satisfies_constraint_K (operands[2])"
18020 [(set (match_dup 3) (match_dup 2))
18021 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
18022 (clobber (reg:CC FLAGS_REG))])]
18024 if (!rtx_equal_p (operands[0], operands[1]))
18025 emit_move_insn (operands[0], operands[1]);
18028 ;; After splitting up read-modify operations, array accesses with memory
18029 ;; operands might end up in form:
18031 ;; movl 4(%esp), %edx
18033 ;; instead of pre-splitting:
18035 ;; addl 4(%esp), %eax
18037 ;; movl 4(%esp), %edx
18038 ;; leal (%edx,%eax,4), %eax
18041 [(match_scratch:W 5 "r")
18042 (parallel [(set (match_operand 0 "register_operand")
18043 (ashift (match_operand 1 "register_operand")
18044 (match_operand 2 "const_int_operand")))
18045 (clobber (reg:CC FLAGS_REG))])
18046 (parallel [(set (match_operand 3 "register_operand")
18047 (plus (match_dup 0)
18048 (match_operand 4 "x86_64_general_operand")))
18049 (clobber (reg:CC FLAGS_REG))])]
18050 "IN_RANGE (INTVAL (operands[2]), 1, 3)
18051 /* Validate MODE for lea. */
18052 && ((!TARGET_PARTIAL_REG_STALL
18053 && (GET_MODE (operands[0]) == QImode
18054 || GET_MODE (operands[0]) == HImode))
18055 || GET_MODE (operands[0]) == SImode
18056 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18057 && (rtx_equal_p (operands[0], operands[3])
18058 || peep2_reg_dead_p (2, operands[0]))
18059 /* We reorder load and the shift. */
18060 && !reg_overlap_mentioned_p (operands[0], operands[4])"
18061 [(set (match_dup 5) (match_dup 4))
18062 (set (match_dup 0) (match_dup 1))]
18064 machine_mode op1mode = GET_MODE (operands[1]);
18065 machine_mode mode = op1mode == DImode ? DImode : SImode;
18066 int scale = 1 << INTVAL (operands[2]);
18067 rtx index = gen_lowpart (word_mode, operands[1]);
18068 rtx base = gen_lowpart (word_mode, operands[5]);
18069 rtx dest = gen_lowpart (mode, operands[3]);
18071 operands[1] = gen_rtx_PLUS (word_mode, base,
18072 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
18073 if (mode != word_mode)
18074 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18076 operands[5] = base;
18077 if (op1mode != word_mode)
18078 operands[5] = gen_lowpart (op1mode, operands[5]);
18080 operands[0] = dest;
18083 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18084 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18085 ;; caught for use by garbage collectors and the like. Using an insn that
18086 ;; maps to SIGILL makes it more likely the program will rightfully die.
18087 ;; Keeping with tradition, "6" is in honor of #UD.
18088 (define_insn "trap"
18089 [(trap_if (const_int 1) (const_int 6))]
18092 #ifdef HAVE_AS_IX86_UD2
18095 return ASM_SHORT "0x0b0f";
18098 [(set_attr "length" "2")])
18100 (define_expand "prefetch"
18101 [(prefetch (match_operand 0 "address_operand")
18102 (match_operand:SI 1 "const_int_operand")
18103 (match_operand:SI 2 "const_int_operand"))]
18104 "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18106 bool write = INTVAL (operands[1]) != 0;
18107 int locality = INTVAL (operands[2]);
18109 gcc_assert (IN_RANGE (locality, 0, 3));
18111 /* Use 3dNOW prefetch in case we are asking for write prefetch not
18112 supported by SSE counterpart or the SSE prefetch is not available
18113 (K6 machines). Otherwise use SSE prefetch as it allows specifying
18115 if (TARGET_PREFETCHWT1 && write && locality <= 2)
18116 operands[2] = const2_rtx;
18117 else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
18118 operands[2] = GEN_INT (3);
18120 operands[1] = const0_rtx;
18123 (define_insn "*prefetch_sse"
18124 [(prefetch (match_operand 0 "address_operand" "p")
18126 (match_operand:SI 1 "const_int_operand"))]
18127 "TARGET_PREFETCH_SSE"
18129 static const char * const patterns[4] = {
18130 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18133 int locality = INTVAL (operands[1]);
18134 gcc_assert (IN_RANGE (locality, 0, 3));
18136 return patterns[locality];
18138 [(set_attr "type" "sse")
18139 (set_attr "atom_sse_attr" "prefetch")
18140 (set (attr "length_address")
18141 (symbol_ref "memory_address_length (operands[0], false)"))
18142 (set_attr "memory" "none")])
18144 (define_insn "*prefetch_3dnow"
18145 [(prefetch (match_operand 0 "address_operand" "p")
18146 (match_operand:SI 1 "const_int_operand" "n")
18150 if (INTVAL (operands[1]) == 0)
18151 return "prefetch\t%a0";
18153 return "prefetchw\t%a0";
18155 [(set_attr "type" "mmx")
18156 (set (attr "length_address")
18157 (symbol_ref "memory_address_length (operands[0], false)"))
18158 (set_attr "memory" "none")])
18160 (define_insn "*prefetch_prefetchwt1"
18161 [(prefetch (match_operand 0 "address_operand" "p")
18164 "TARGET_PREFETCHWT1"
18165 "prefetchwt1\t%a0";
18166 [(set_attr "type" "sse")
18167 (set (attr "length_address")
18168 (symbol_ref "memory_address_length (operands[0], false)"))
18169 (set_attr "memory" "none")])
18171 (define_expand "stack_protect_set"
18172 [(match_operand 0 "memory_operand")
18173 (match_operand 1 "memory_operand")]
18174 "TARGET_SSP_TLS_GUARD"
18176 rtx (*insn)(rtx, rtx);
18178 #ifdef TARGET_THREAD_SSP_OFFSET
18179 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18180 insn = (TARGET_LP64
18181 ? gen_stack_tls_protect_set_di
18182 : gen_stack_tls_protect_set_si);
18184 insn = (TARGET_LP64
18185 ? gen_stack_protect_set_di
18186 : gen_stack_protect_set_si);
18189 emit_insn (insn (operands[0], operands[1]));
18193 (define_insn "stack_protect_set_<mode>"
18194 [(set (match_operand:PTR 0 "memory_operand" "=m")
18195 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18197 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18198 (clobber (reg:CC FLAGS_REG))]
18199 "TARGET_SSP_TLS_GUARD"
18200 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18201 [(set_attr "type" "multi")])
18203 (define_insn "stack_tls_protect_set_<mode>"
18204 [(set (match_operand:PTR 0 "memory_operand" "=m")
18205 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
18206 UNSPEC_SP_TLS_SET))
18207 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18208 (clobber (reg:CC FLAGS_REG))]
18210 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18211 [(set_attr "type" "multi")])
18213 (define_expand "stack_protect_test"
18214 [(match_operand 0 "memory_operand")
18215 (match_operand 1 "memory_operand")
18217 "TARGET_SSP_TLS_GUARD"
18219 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18221 rtx (*insn)(rtx, rtx, rtx);
18223 #ifdef TARGET_THREAD_SSP_OFFSET
18224 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18225 insn = (TARGET_LP64
18226 ? gen_stack_tls_protect_test_di
18227 : gen_stack_tls_protect_test_si);
18229 insn = (TARGET_LP64
18230 ? gen_stack_protect_test_di
18231 : gen_stack_protect_test_si);
18234 emit_insn (insn (flags, operands[0], operands[1]));
18236 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18237 flags, const0_rtx, operands[2]));
18241 (define_insn "stack_protect_test_<mode>"
18242 [(set (match_operand:CCZ 0 "flags_reg_operand")
18243 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18244 (match_operand:PTR 2 "memory_operand" "m")]
18246 (clobber (match_scratch:PTR 3 "=&r"))]
18247 "TARGET_SSP_TLS_GUARD"
18248 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18249 [(set_attr "type" "multi")])
18251 (define_insn "stack_tls_protect_test_<mode>"
18252 [(set (match_operand:CCZ 0 "flags_reg_operand")
18253 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18254 (match_operand:PTR 2 "const_int_operand" "i")]
18255 UNSPEC_SP_TLS_TEST))
18256 (clobber (match_scratch:PTR 3 "=r"))]
18258 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18259 [(set_attr "type" "multi")])
18261 (define_insn "sse4_2_crc32<mode>"
18262 [(set (match_operand:SI 0 "register_operand" "=r")
18264 [(match_operand:SI 1 "register_operand" "0")
18265 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18267 "TARGET_SSE4_2 || TARGET_CRC32"
18268 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18269 [(set_attr "type" "sselog1")
18270 (set_attr "prefix_rep" "1")
18271 (set_attr "prefix_extra" "1")
18272 (set (attr "prefix_data16")
18273 (if_then_else (match_operand:HI 2)
18275 (const_string "*")))
18276 (set (attr "prefix_rex")
18277 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18279 (const_string "*")))
18280 (set_attr "mode" "SI")])
18282 (define_insn "sse4_2_crc32di"
18283 [(set (match_operand:DI 0 "register_operand" "=r")
18285 [(match_operand:DI 1 "register_operand" "0")
18286 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18288 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18289 "crc32{q}\t{%2, %0|%0, %2}"
18290 [(set_attr "type" "sselog1")
18291 (set_attr "prefix_rep" "1")
18292 (set_attr "prefix_extra" "1")
18293 (set_attr "mode" "DI")])
18295 (define_insn "rdpmc"
18296 [(set (match_operand:DI 0 "register_operand" "=A")
18297 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18301 [(set_attr "type" "other")
18302 (set_attr "length" "2")])
18304 (define_insn "rdpmc_rex64"
18305 [(set (match_operand:DI 0 "register_operand" "=a")
18306 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18308 (set (match_operand:DI 1 "register_operand" "=d")
18309 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18312 [(set_attr "type" "other")
18313 (set_attr "length" "2")])
18315 (define_insn "rdtsc"
18316 [(set (match_operand:DI 0 "register_operand" "=A")
18317 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18320 [(set_attr "type" "other")
18321 (set_attr "length" "2")])
18323 (define_insn "rdtsc_rex64"
18324 [(set (match_operand:DI 0 "register_operand" "=a")
18325 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18326 (set (match_operand:DI 1 "register_operand" "=d")
18327 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18330 [(set_attr "type" "other")
18331 (set_attr "length" "2")])
18333 (define_insn "rdtscp"
18334 [(set (match_operand:DI 0 "register_operand" "=A")
18335 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18336 (set (match_operand:SI 1 "register_operand" "=c")
18337 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18340 [(set_attr "type" "other")
18341 (set_attr "length" "3")])
18343 (define_insn "rdtscp_rex64"
18344 [(set (match_operand:DI 0 "register_operand" "=a")
18345 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18346 (set (match_operand:DI 1 "register_operand" "=d")
18347 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18348 (set (match_operand:SI 2 "register_operand" "=c")
18349 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18352 [(set_attr "type" "other")
18353 (set_attr "length" "3")])
18355 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18357 ;; FXSR, XSAVE and XSAVEOPT instructions
18359 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18361 (define_insn "fxsave"
18362 [(set (match_operand:BLK 0 "memory_operand" "=m")
18363 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18366 [(set_attr "type" "other")
18367 (set_attr "memory" "store")
18368 (set (attr "length")
18369 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18371 (define_insn "fxsave64"
18372 [(set (match_operand:BLK 0 "memory_operand" "=m")
18373 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18374 "TARGET_64BIT && TARGET_FXSR"
18376 [(set_attr "type" "other")
18377 (set_attr "memory" "store")
18378 (set (attr "length")
18379 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18381 (define_insn "fxrstor"
18382 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18386 [(set_attr "type" "other")
18387 (set_attr "memory" "load")
18388 (set (attr "length")
18389 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18391 (define_insn "fxrstor64"
18392 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18393 UNSPECV_FXRSTOR64)]
18394 "TARGET_64BIT && TARGET_FXSR"
18396 [(set_attr "type" "other")
18397 (set_attr "memory" "load")
18398 (set (attr "length")
18399 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18401 (define_int_iterator ANY_XSAVE
18403 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18404 (UNSPECV_XSAVEC "TARGET_XSAVEC")
18405 (UNSPECV_XSAVES "TARGET_XSAVES")])
18407 (define_int_iterator ANY_XSAVE64
18409 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18410 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18411 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18413 (define_int_attr xsave
18414 [(UNSPECV_XSAVE "xsave")
18415 (UNSPECV_XSAVE64 "xsave64")
18416 (UNSPECV_XSAVEOPT "xsaveopt")
18417 (UNSPECV_XSAVEOPT64 "xsaveopt64")
18418 (UNSPECV_XSAVEC "xsavec")
18419 (UNSPECV_XSAVEC64 "xsavec64")
18420 (UNSPECV_XSAVES "xsaves")
18421 (UNSPECV_XSAVES64 "xsaves64")])
18423 (define_int_iterator ANY_XRSTOR
18425 (UNSPECV_XRSTORS "TARGET_XSAVES")])
18427 (define_int_iterator ANY_XRSTOR64
18429 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18431 (define_int_attr xrstor
18432 [(UNSPECV_XRSTOR "xrstor")
18433 (UNSPECV_XRSTOR64 "xrstor")
18434 (UNSPECV_XRSTORS "xrstors")
18435 (UNSPECV_XRSTORS64 "xrstors")])
18437 (define_insn "<xsave>"
18438 [(set (match_operand:BLK 0 "memory_operand" "=m")
18439 (unspec_volatile:BLK
18440 [(match_operand:DI 1 "register_operand" "A")]
18442 "!TARGET_64BIT && TARGET_XSAVE"
18444 [(set_attr "type" "other")
18445 (set_attr "memory" "store")
18446 (set (attr "length")
18447 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18449 (define_insn "<xsave>_rex64"
18450 [(set (match_operand:BLK 0 "memory_operand" "=m")
18451 (unspec_volatile:BLK
18452 [(match_operand:SI 1 "register_operand" "a")
18453 (match_operand:SI 2 "register_operand" "d")]
18455 "TARGET_64BIT && TARGET_XSAVE"
18457 [(set_attr "type" "other")
18458 (set_attr "memory" "store")
18459 (set (attr "length")
18460 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18462 (define_insn "<xsave>"
18463 [(set (match_operand:BLK 0 "memory_operand" "=m")
18464 (unspec_volatile:BLK
18465 [(match_operand:SI 1 "register_operand" "a")
18466 (match_operand:SI 2 "register_operand" "d")]
18468 "TARGET_64BIT && TARGET_XSAVE"
18470 [(set_attr "type" "other")
18471 (set_attr "memory" "store")
18472 (set (attr "length")
18473 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18475 (define_insn "<xrstor>"
18476 [(unspec_volatile:BLK
18477 [(match_operand:BLK 0 "memory_operand" "m")
18478 (match_operand:DI 1 "register_operand" "A")]
18480 "!TARGET_64BIT && TARGET_XSAVE"
18482 [(set_attr "type" "other")
18483 (set_attr "memory" "load")
18484 (set (attr "length")
18485 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18487 (define_insn "<xrstor>_rex64"
18488 [(unspec_volatile:BLK
18489 [(match_operand:BLK 0 "memory_operand" "m")
18490 (match_operand:SI 1 "register_operand" "a")
18491 (match_operand:SI 2 "register_operand" "d")]
18493 "TARGET_64BIT && TARGET_XSAVE"
18495 [(set_attr "type" "other")
18496 (set_attr "memory" "load")
18497 (set (attr "length")
18498 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18500 (define_insn "<xrstor>64"
18501 [(unspec_volatile:BLK
18502 [(match_operand:BLK 0 "memory_operand" "m")
18503 (match_operand:SI 1 "register_operand" "a")
18504 (match_operand:SI 2 "register_operand" "d")]
18506 "TARGET_64BIT && TARGET_XSAVE"
18508 [(set_attr "type" "other")
18509 (set_attr "memory" "load")
18510 (set (attr "length")
18511 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18513 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18515 ;; Floating-point instructions for atomic compound assignments
18517 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18519 ; Clobber all floating-point registers on environment save and restore
18520 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18521 (define_insn "fnstenv"
18522 [(set (match_operand:BLK 0 "memory_operand" "=m")
18523 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18524 (clobber (reg:HI FPCR_REG))
18525 (clobber (reg:XF ST0_REG))
18526 (clobber (reg:XF ST1_REG))
18527 (clobber (reg:XF ST2_REG))
18528 (clobber (reg:XF ST3_REG))
18529 (clobber (reg:XF ST4_REG))
18530 (clobber (reg:XF ST5_REG))
18531 (clobber (reg:XF ST6_REG))
18532 (clobber (reg:XF ST7_REG))]
18535 [(set_attr "type" "other")
18536 (set_attr "memory" "store")
18537 (set (attr "length")
18538 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18540 (define_insn "fldenv"
18541 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18543 (clobber (reg:CCFP FPSR_REG))
18544 (clobber (reg:HI FPCR_REG))
18545 (clobber (reg:XF ST0_REG))
18546 (clobber (reg:XF ST1_REG))
18547 (clobber (reg:XF ST2_REG))
18548 (clobber (reg:XF ST3_REG))
18549 (clobber (reg:XF ST4_REG))
18550 (clobber (reg:XF ST5_REG))
18551 (clobber (reg:XF ST6_REG))
18552 (clobber (reg:XF ST7_REG))]
18555 [(set_attr "type" "other")
18556 (set_attr "memory" "load")
18557 (set (attr "length")
18558 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18560 (define_insn "fnstsw"
18561 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18562 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18565 [(set_attr "type" "other,other")
18566 (set_attr "memory" "none,store")
18567 (set (attr "length")
18568 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18570 (define_insn "fnclex"
18571 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18574 [(set_attr "type" "other")
18575 (set_attr "memory" "none")
18576 (set_attr "length" "2")])
18578 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18580 ;; LWP instructions
18582 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18584 (define_expand "lwp_llwpcb"
18585 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18586 UNSPECV_LLWP_INTRINSIC)]
18589 (define_insn "*lwp_llwpcb<mode>1"
18590 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18591 UNSPECV_LLWP_INTRINSIC)]
18594 [(set_attr "type" "lwp")
18595 (set_attr "mode" "<MODE>")
18596 (set_attr "length" "5")])
18598 (define_expand "lwp_slwpcb"
18599 [(set (match_operand 0 "register_operand" "=r")
18600 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18605 insn = (Pmode == DImode
18607 : gen_lwp_slwpcbsi);
18609 emit_insn (insn (operands[0]));
18613 (define_insn "lwp_slwpcb<mode>"
18614 [(set (match_operand:P 0 "register_operand" "=r")
18615 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18618 [(set_attr "type" "lwp")
18619 (set_attr "mode" "<MODE>")
18620 (set_attr "length" "5")])
18622 (define_expand "lwp_lwpval<mode>3"
18623 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18624 (match_operand:SI 2 "nonimmediate_operand" "rm")
18625 (match_operand:SI 3 "const_int_operand" "i")]
18626 UNSPECV_LWPVAL_INTRINSIC)]
18628 ;; Avoid unused variable warning.
18629 "(void) operands[0];")
18631 (define_insn "*lwp_lwpval<mode>3_1"
18632 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18633 (match_operand:SI 1 "nonimmediate_operand" "rm")
18634 (match_operand:SI 2 "const_int_operand" "i")]
18635 UNSPECV_LWPVAL_INTRINSIC)]
18637 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18638 [(set_attr "type" "lwp")
18639 (set_attr "mode" "<MODE>")
18640 (set (attr "length")
18641 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18643 (define_expand "lwp_lwpins<mode>3"
18644 [(set (reg:CCC FLAGS_REG)
18645 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18646 (match_operand:SI 2 "nonimmediate_operand" "rm")
18647 (match_operand:SI 3 "const_int_operand" "i")]
18648 UNSPECV_LWPINS_INTRINSIC))
18649 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18650 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18653 (define_insn "*lwp_lwpins<mode>3_1"
18654 [(set (reg:CCC FLAGS_REG)
18655 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18656 (match_operand:SI 1 "nonimmediate_operand" "rm")
18657 (match_operand:SI 2 "const_int_operand" "i")]
18658 UNSPECV_LWPINS_INTRINSIC))]
18660 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18661 [(set_attr "type" "lwp")
18662 (set_attr "mode" "<MODE>")
18663 (set (attr "length")
18664 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18666 (define_int_iterator RDFSGSBASE
18670 (define_int_iterator WRFSGSBASE
18674 (define_int_attr fsgs
18675 [(UNSPECV_RDFSBASE "fs")
18676 (UNSPECV_RDGSBASE "gs")
18677 (UNSPECV_WRFSBASE "fs")
18678 (UNSPECV_WRGSBASE "gs")])
18680 (define_insn "rd<fsgs>base<mode>"
18681 [(set (match_operand:SWI48 0 "register_operand" "=r")
18682 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18683 "TARGET_64BIT && TARGET_FSGSBASE"
18685 [(set_attr "type" "other")
18686 (set_attr "prefix_extra" "2")])
18688 (define_insn "wr<fsgs>base<mode>"
18689 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18691 "TARGET_64BIT && TARGET_FSGSBASE"
18693 [(set_attr "type" "other")
18694 (set_attr "prefix_extra" "2")])
18696 (define_insn "rdrand<mode>_1"
18697 [(set (match_operand:SWI248 0 "register_operand" "=r")
18698 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18699 (set (reg:CCC FLAGS_REG)
18700 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18703 [(set_attr "type" "other")
18704 (set_attr "prefix_extra" "1")])
18706 (define_insn "rdseed<mode>_1"
18707 [(set (match_operand:SWI248 0 "register_operand" "=r")
18708 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18709 (set (reg:CCC FLAGS_REG)
18710 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18713 [(set_attr "type" "other")
18714 (set_attr "prefix_extra" "1")])
18716 (define_expand "pause"
18717 [(set (match_dup 0)
18718 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18721 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18722 MEM_VOLATILE_P (operands[0]) = 1;
18725 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18726 ;; They have the same encoding.
18727 (define_insn "*pause"
18728 [(set (match_operand:BLK 0)
18729 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18732 [(set_attr "length" "2")
18733 (set_attr "memory" "unknown")])
18735 (define_expand "xbegin"
18736 [(set (match_operand:SI 0 "register_operand")
18737 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18740 rtx_code_label *label = gen_label_rtx ();
18742 /* xbegin is emitted as jump_insn, so reload won't be able
18743 to reload its operand. Force the value into AX hard register. */
18744 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18745 emit_move_insn (ax_reg, constm1_rtx);
18747 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18749 emit_label (label);
18750 LABEL_NUSES (label) = 1;
18752 emit_move_insn (operands[0], ax_reg);
18757 (define_insn "xbegin_1"
18759 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18761 (label_ref (match_operand 1))
18763 (set (match_operand:SI 0 "register_operand" "+a")
18764 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18767 [(set_attr "type" "other")
18768 (set_attr "length" "6")])
18770 (define_insn "xend"
18771 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18774 [(set_attr "type" "other")
18775 (set_attr "length" "3")])
18777 (define_insn "xabort"
18778 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18782 [(set_attr "type" "other")
18783 (set_attr "length" "3")])
18785 (define_expand "xtest"
18786 [(set (match_operand:QI 0 "register_operand")
18787 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18790 emit_insn (gen_xtest_1 ());
18792 ix86_expand_setcc (operands[0], NE,
18793 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18797 (define_insn "xtest_1"
18798 [(set (reg:CCZ FLAGS_REG)
18799 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18802 [(set_attr "type" "other")
18803 (set_attr "length" "3")])
18805 (define_insn "pcommit"
18806 [(unspec_volatile [(const_int 0)] UNSPECV_PCOMMIT)]
18809 [(set_attr "type" "other")
18810 (set_attr "length" "4")])
18812 (define_insn "clwb"
18813 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18817 [(set_attr "type" "sse")
18818 (set_attr "atom_sse_attr" "fence")
18819 (set_attr "memory" "unknown")])
18821 (define_insn "clflushopt"
18822 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18823 UNSPECV_CLFLUSHOPT)]
18824 "TARGET_CLFLUSHOPT"
18826 [(set_attr "type" "sse")
18827 (set_attr "atom_sse_attr" "fence")
18828 (set_attr "memory" "unknown")])
18830 ;; MONITORX and MWAITX
18831 (define_insn "mwaitx"
18832 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
18833 (match_operand:SI 1 "register_operand" "a")
18834 (match_operand:SI 2 "register_operand" "b")]
18837 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
18838 ;; Since 32bit register operands are implicitly zero extended to 64bit,
18839 ;; we only need to set up 32bit registers.
18841 [(set_attr "length" "3")])
18843 (define_insn "monitorx_<mode>"
18844 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
18845 (match_operand:SI 1 "register_operand" "c")
18846 (match_operand:SI 2 "register_operand" "d")]
18849 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
18850 ;; RCX and RDX are used. Since 32bit register operands are implicitly
18851 ;; zero extended to 64bit, we only need to set up 32bit registers.
18853 [(set (attr "length")
18854 (symbol_ref ("(Pmode != word_mode) + 3")))])
18856 ;; MPX instructions
18858 (define_expand "<mode>_mk"
18859 [(set (match_operand:BND 0 "register_operand")
18863 [(match_operand:<bnd_ptr> 1 "register_operand")
18864 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
18868 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18870 UNSPEC_BNDMK_ADDR);
18873 (define_insn "*<mode>_mk"
18874 [(set (match_operand:BND 0 "register_operand" "=w")
18876 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18878 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
18879 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
18880 UNSPEC_BNDMK_ADDR)])]
18883 "bndmk\t{%3, %0|%0, %3}"
18884 [(set_attr "type" "mpxmk")])
18886 (define_expand "mov<mode>"
18887 [(set (match_operand:BND 0 "general_operand")
18888 (match_operand:BND 1 "general_operand"))]
18890 "ix86_expand_move (<MODE>mode, operands); DONE;")
18892 (define_insn "*mov<mode>_internal_mpx"
18893 [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
18894 (match_operand:BND 1 "general_operand" "wm,w"))]
18896 "bndmov\t{%1, %0|%0, %1}"
18897 [(set_attr "type" "mpxmov")])
18899 (define_expand "<mode>_<bndcheck>"
18902 [(match_operand:BND 0 "register_operand")
18903 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
18905 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18908 operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
18909 MEM_VOLATILE_P (operands[2]) = 1;
18912 (define_insn "*<mode>_<bndcheck>"
18914 [(match_operand:BND 0 "register_operand" "w")
18915 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
18916 (set (match_operand:BLK 2 "bnd_mem_operator")
18917 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))]
18919 "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
18920 [(set_attr "type" "mpxchk")])
18922 (define_expand "<mode>_ldx"
18924 [(set (match_operand:BND 0 "register_operand")
18928 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
18929 (match_operand:<bnd_ptr> 2 "register_operand")]))]
18931 (use (mem:BLK (match_dup 1)))])]
18934 /* Avoid registers which cannot be used as index. */
18935 if (!index_register_operand (operands[2], Pmode))
18936 operands[2] = copy_addr_to_reg (operands[2]);
18938 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18940 UNSPEC_BNDLDX_ADDR);
18943 (define_insn "*<mode>_ldx"
18944 [(set (match_operand:BND 0 "register_operand" "=w")
18946 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18948 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
18949 (match_operand:<bnd_ptr> 2 "register_operand" "l")]
18950 UNSPEC_BNDLDX_ADDR)])]
18952 (use (mem:BLK (match_dup 1)))]
18954 "bndldx\t{%3, %0|%0, %3}"
18955 [(set_attr "type" "mpxld")])
18957 (define_expand "<mode>_stx"
18962 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
18963 (match_operand:<bnd_ptr> 1 "register_operand")]))
18964 (match_operand:BND 2 "register_operand")]
18967 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18970 /* Avoid registers which cannot be used as index. */
18971 if (!index_register_operand (operands[1], Pmode))
18972 operands[1] = copy_addr_to_reg (operands[1]);
18974 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
18976 UNSPEC_BNDLDX_ADDR);
18977 operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
18978 MEM_VOLATILE_P (operands[4]) = 1;
18981 (define_insn "*<mode>_stx"
18983 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18985 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
18986 (match_operand:<bnd_ptr> 1 "register_operand" "l")]
18987 UNSPEC_BNDLDX_ADDR)])
18988 (match_operand:BND 2 "register_operand" "w")]
18990 (set (match_operand:BLK 4 "bnd_mem_operator")
18991 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))]
18993 "bndstx\t{%2, %3|%3, %2}"
18994 [(set_attr "type" "mpxst")])
18996 (define_insn "move_size_reloc_<mode>"
18997 [(set (match_operand:SWI48 0 "register_operand" "=r")
18999 [(match_operand:SWI48 1 "symbol_operand")]
19003 if (x86_64_immediate_size_operand (operands[1], VOIDmode))
19004 return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
19006 return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
19008 [(set_attr "type" "imov")
19009 (set_attr "mode" "<MODE>")])
19013 (include "sync.md")