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.
395 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
398 ;; In C guard expressions, put expressions which may be compile-time
399 ;; constants first. This allows for better optimization. For
400 ;; example, write "TARGET_64BIT && reload_completed", not
401 ;; "reload_completed && TARGET_64BIT".
405 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
406 atom,slm,generic,amdfam10,bdver1,bdver2,bdver3,bdver4,
408 (const (symbol_ref "ix86_schedule")))
410 ;; A basic instruction type. Refinements due to arguments to be
411 ;; provided in other attributes.
414 alu,alu1,negnot,imov,imovx,lea,
415 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
416 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
417 push,pop,call,callv,leave,
419 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
420 fxch,fistp,fisttp,frndint,
421 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
422 ssemul,sseimul,ssediv,sselog,sselog1,
423 sseishft,sseishft1,ssecmp,ssecomi,
424 ssecvt,ssecvt1,sseicvt,sseins,
425 sseshuf,sseshuf1,ssemuladd,sse4arg,
427 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
428 mpxmov,mpxmk,mpxchk,mpxld,mpxst"
429 (const_string "other"))
431 ;; Main data type used by the insn
433 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
435 (const_string "unknown"))
437 ;; The CPU unit operations uses.
438 (define_attr "unit" "integer,i387,sse,mmx,unknown"
439 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
440 fxch,fistp,fisttp,frndint")
441 (const_string "i387")
442 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
443 ssemul,sseimul,ssediv,sselog,sselog1,
444 sseishft,sseishft1,ssecmp,ssecomi,
445 ssecvt,ssecvt1,sseicvt,sseins,
446 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
448 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
450 (eq_attr "type" "other")
451 (const_string "unknown")]
452 (const_string "integer")))
454 ;; The minimum required alignment of vector mode memory operands of the SSE
455 ;; (non-VEX/EVEX) instruction in bits, if it is different from
456 ;; GET_MODE_ALIGNMENT of the operand, otherwise 0. If an instruction has
457 ;; multiple alternatives, this should be conservative maximum of those minimum
458 ;; required alignments.
459 (define_attr "ssememalign" "" (const_int 0))
461 ;; The (bounding maximum) length of an instruction immediate.
462 (define_attr "length_immediate" ""
463 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
464 bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
467 (eq_attr "unit" "i387,sse,mmx")
469 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
470 rotate,rotatex,rotate1,imul,icmp,push,pop")
471 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
472 (eq_attr "type" "imov,test")
473 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
474 (eq_attr "type" "call")
475 (if_then_else (match_operand 0 "constant_call_address_operand")
478 (eq_attr "type" "callv")
479 (if_then_else (match_operand 1 "constant_call_address_operand")
482 ;; We don't know the size before shorten_branches. Expect
483 ;; the instruction to fit for better scheduling.
484 (eq_attr "type" "ibr")
487 (symbol_ref "/* Update immediate_length and other attributes! */
488 gcc_unreachable (),1")))
490 ;; The (bounding maximum) length of an instruction address.
491 (define_attr "length_address" ""
492 (cond [(eq_attr "type" "str,other,multi,fxch")
494 (and (eq_attr "type" "call")
495 (match_operand 0 "constant_call_address_operand"))
497 (and (eq_attr "type" "callv")
498 (match_operand 1 "constant_call_address_operand"))
501 (symbol_ref "ix86_attr_length_address_default (insn)")))
503 ;; Set when length prefix is used.
504 (define_attr "prefix_data16" ""
505 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
507 (eq_attr "mode" "HI")
509 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
514 ;; Set when string REP prefix is used.
515 (define_attr "prefix_rep" ""
516 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
518 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
520 (and (eq_attr "type" "ibr,call,callv")
521 (match_test "ix86_bnd_prefixed_insn_p (insn)"))
526 ;; Set when 0f opcode prefix is used.
527 (define_attr "prefix_0f" ""
529 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
530 mpxmk,mpxmov,mpxchk,mpxld,mpxst")
531 (eq_attr "unit" "sse,mmx"))
535 ;; Set when REX opcode prefix is used.
536 (define_attr "prefix_rex" ""
537 (cond [(not (match_test "TARGET_64BIT"))
539 (and (eq_attr "mode" "DI")
540 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
541 (eq_attr "unit" "!mmx")))
543 (and (eq_attr "mode" "QI")
544 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
546 (match_test "x86_extended_reg_mentioned_p (insn)")
548 (and (eq_attr "type" "imovx")
549 (match_operand:QI 1 "ext_QIreg_operand"))
554 ;; There are also additional prefixes in 3DNOW, SSSE3.
555 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
556 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
557 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
558 (define_attr "prefix_extra" ""
559 (cond [(eq_attr "type" "ssemuladd,sse4arg")
561 (eq_attr "type" "sseiadd1,ssecvt1")
566 ;; Prefix used: original, VEX or maybe VEX.
567 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
568 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
570 (eq_attr "mode" "XI,V16SF,V8DF")
571 (const_string "evex")
573 (const_string "orig")))
575 ;; VEX W bit is used.
576 (define_attr "prefix_vex_w" "" (const_int 0))
578 ;; The length of VEX prefix
579 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
580 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
581 ;; still prefix_0f 1, with prefix_extra 1.
582 (define_attr "length_vex" ""
583 (if_then_else (and (eq_attr "prefix_0f" "1")
584 (eq_attr "prefix_extra" "0"))
585 (if_then_else (eq_attr "prefix_vex_w" "1")
586 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
587 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
588 (if_then_else (eq_attr "prefix_vex_w" "1")
589 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
590 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
592 ;; 4-bytes evex prefix and 1 byte opcode.
593 (define_attr "length_evex" "" (const_int 5))
595 ;; Set when modrm byte is used.
596 (define_attr "modrm" ""
597 (cond [(eq_attr "type" "str,leave")
599 (eq_attr "unit" "i387")
601 (and (eq_attr "type" "incdec")
602 (and (not (match_test "TARGET_64BIT"))
603 (ior (match_operand:SI 1 "register_operand")
604 (match_operand:HI 1 "register_operand"))))
606 (and (eq_attr "type" "push")
607 (not (match_operand 1 "memory_operand")))
609 (and (eq_attr "type" "pop")
610 (not (match_operand 0 "memory_operand")))
612 (and (eq_attr "type" "imov")
613 (and (not (eq_attr "mode" "DI"))
614 (ior (and (match_operand 0 "register_operand")
615 (match_operand 1 "immediate_operand"))
616 (ior (and (match_operand 0 "ax_reg_operand")
617 (match_operand 1 "memory_displacement_only_operand"))
618 (and (match_operand 0 "memory_displacement_only_operand")
619 (match_operand 1 "ax_reg_operand"))))))
621 (and (eq_attr "type" "call")
622 (match_operand 0 "constant_call_address_operand"))
624 (and (eq_attr "type" "callv")
625 (match_operand 1 "constant_call_address_operand"))
627 (and (eq_attr "type" "alu,alu1,icmp,test")
628 (match_operand 0 "ax_reg_operand"))
629 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
633 ;; When this attribute is set, calculate total insn length from
634 ;; length_nobnd attribute, prefixed with eventual bnd prefix byte
635 (define_attr "length_nobnd" "" (const_int 0))
637 ;; The (bounding maximum) length of an instruction in bytes.
638 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
639 ;; Later we may want to split them and compute proper length as for
641 (define_attr "length" ""
642 (cond [(eq_attr "length_nobnd" "!0")
643 (plus (symbol_ref ("ix86_bnd_prefixed_insn_p (insn)"))
644 (attr "length_nobnd"))
645 (eq_attr "type" "other,multi,fistp,frndint")
647 (eq_attr "type" "fcmp")
649 (eq_attr "unit" "i387")
651 (plus (attr "prefix_data16")
652 (attr "length_address")))
653 (ior (eq_attr "prefix" "evex")
654 (and (ior (eq_attr "prefix" "maybe_evex")
655 (eq_attr "prefix" "maybe_vex"))
656 (match_test "TARGET_AVX512F")))
657 (plus (attr "length_evex")
658 (plus (attr "length_immediate")
660 (attr "length_address"))))
661 (ior (eq_attr "prefix" "vex")
662 (and (ior (eq_attr "prefix" "maybe_vex")
663 (eq_attr "prefix" "maybe_evex"))
664 (match_test "TARGET_AVX")))
665 (plus (attr "length_vex")
666 (plus (attr "length_immediate")
668 (attr "length_address"))))]
669 (plus (plus (attr "modrm")
670 (plus (attr "prefix_0f")
671 (plus (attr "prefix_rex")
672 (plus (attr "prefix_extra")
674 (plus (attr "prefix_rep")
675 (plus (attr "prefix_data16")
676 (plus (attr "length_immediate")
677 (attr "length_address")))))))
679 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
680 ;; `store' if there is a simple memory reference therein, or `unknown'
681 ;; if the instruction is complex.
683 (define_attr "memory" "none,load,store,both,unknown"
684 (cond [(eq_attr "type" "other,multi,str,lwp")
685 (const_string "unknown")
686 (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
687 (const_string "none")
688 (eq_attr "type" "fistp,leave")
689 (const_string "both")
690 (eq_attr "type" "frndint")
691 (const_string "load")
692 (eq_attr "type" "mpxld")
693 (const_string "load")
694 (eq_attr "type" "mpxst")
695 (const_string "store")
696 (eq_attr "type" "push")
697 (if_then_else (match_operand 1 "memory_operand")
698 (const_string "both")
699 (const_string "store"))
700 (eq_attr "type" "pop")
701 (if_then_else (match_operand 0 "memory_operand")
702 (const_string "both")
703 (const_string "load"))
704 (eq_attr "type" "setcc")
705 (if_then_else (match_operand 0 "memory_operand")
706 (const_string "store")
707 (const_string "none"))
708 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
709 (if_then_else (ior (match_operand 0 "memory_operand")
710 (match_operand 1 "memory_operand"))
711 (const_string "load")
712 (const_string "none"))
713 (eq_attr "type" "ibr")
714 (if_then_else (match_operand 0 "memory_operand")
715 (const_string "load")
716 (const_string "none"))
717 (eq_attr "type" "call")
718 (if_then_else (match_operand 0 "constant_call_address_operand")
719 (const_string "none")
720 (const_string "load"))
721 (eq_attr "type" "callv")
722 (if_then_else (match_operand 1 "constant_call_address_operand")
723 (const_string "none")
724 (const_string "load"))
725 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
726 (match_operand 1 "memory_operand"))
727 (const_string "both")
728 (and (match_operand 0 "memory_operand")
729 (match_operand 1 "memory_operand"))
730 (const_string "both")
731 (match_operand 0 "memory_operand")
732 (const_string "store")
733 (match_operand 1 "memory_operand")
734 (const_string "load")
736 "!alu1,negnot,ishift1,
737 imov,imovx,icmp,test,bitmanip,
739 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
740 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
741 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
742 (match_operand 2 "memory_operand"))
743 (const_string "load")
744 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
745 (match_operand 3 "memory_operand"))
746 (const_string "load")
748 (const_string "none")))
750 ;; Indicates if an instruction has both an immediate and a displacement.
752 (define_attr "imm_disp" "false,true,unknown"
753 (cond [(eq_attr "type" "other,multi")
754 (const_string "unknown")
755 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
756 (and (match_operand 0 "memory_displacement_operand")
757 (match_operand 1 "immediate_operand")))
758 (const_string "true")
759 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
760 (and (match_operand 0 "memory_displacement_operand")
761 (match_operand 2 "immediate_operand")))
762 (const_string "true")
764 (const_string "false")))
766 ;; Indicates if an FP operation has an integer source.
768 (define_attr "fp_int_src" "false,true"
769 (const_string "false"))
771 ;; Defines rounding mode of an FP operation.
773 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
774 (const_string "any"))
776 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
777 (define_attr "use_carry" "0,1" (const_string "0"))
779 ;; Define attribute to indicate unaligned ssemov insns
780 (define_attr "movu" "0,1" (const_string "0"))
782 ;; Used to control the "enabled" attribute on a per-instruction basis.
783 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
784 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
785 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
786 fma_avx512f,avx512bw,noavx512bw,avx512dq,noavx512dq"
787 (const_string "base"))
789 (define_attr "enabled" ""
790 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
791 (eq_attr "isa" "x64_sse4")
792 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
793 (eq_attr "isa" "x64_sse4_noavx")
794 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
795 (eq_attr "isa" "x64_avx")
796 (symbol_ref "TARGET_64BIT && TARGET_AVX")
797 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
798 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
799 (eq_attr "isa" "sse2_noavx")
800 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
801 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
802 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
803 (eq_attr "isa" "sse4_noavx")
804 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
805 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
806 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
807 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
808 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
809 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
810 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
811 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
812 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
813 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
814 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
815 (eq_attr "isa" "fma_avx512f")
816 (symbol_ref "TARGET_FMA || TARGET_AVX512F")
817 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
818 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
819 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
820 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
824 (define_attr "preferred_for_size" "" (const_int 1))
825 (define_attr "preferred_for_speed" "" (const_int 1))
827 ;; Describe a user's asm statement.
828 (define_asm_attributes
829 [(set_attr "length" "128")
830 (set_attr "type" "multi")])
832 (define_code_iterator plusminus [plus minus])
834 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
836 (define_code_iterator multdiv [mult div])
838 ;; Base name for define_insn
839 (define_code_attr plusminus_insn
840 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
841 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
843 ;; Base name for insn mnemonic.
844 (define_code_attr plusminus_mnemonic
845 [(plus "add") (ss_plus "adds") (us_plus "addus")
846 (minus "sub") (ss_minus "subs") (us_minus "subus")])
847 (define_code_attr plusminus_carry_mnemonic
848 [(plus "adc") (minus "sbb")])
849 (define_code_attr multdiv_mnemonic
850 [(mult "mul") (div "div")])
852 ;; Mark commutative operators as such in constraints.
853 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
854 (minus "") (ss_minus "") (us_minus "")])
856 ;; Mapping of max and min
857 (define_code_iterator maxmin [smax smin umax umin])
859 ;; Mapping of signed max and min
860 (define_code_iterator smaxmin [smax smin])
862 ;; Mapping of unsigned max and min
863 (define_code_iterator umaxmin [umax umin])
865 ;; Base name for integer and FP insn mnemonic
866 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
867 (umax "maxu") (umin "minu")])
868 (define_code_attr maxmin_float [(smax "max") (smin "min")])
870 ;; Mapping of logic operators
871 (define_code_iterator any_logic [and ior xor])
872 (define_code_iterator any_or [ior xor])
873 (define_code_iterator fpint_logic [and xor])
875 ;; Base name for insn mnemonic.
876 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
878 ;; Mapping of logic-shift operators
879 (define_code_iterator any_lshift [ashift lshiftrt])
881 ;; Mapping of shift-right operators
882 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
884 ;; Mapping of all shift operators
885 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
887 ;; Base name for define_insn
888 (define_code_attr shift_insn
889 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
891 ;; Base name for insn mnemonic.
892 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
893 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
895 ;; Mapping of rotate operators
896 (define_code_iterator any_rotate [rotate rotatert])
898 ;; Base name for define_insn
899 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
901 ;; Base name for insn mnemonic.
902 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
904 ;; Mapping of abs neg operators
905 (define_code_iterator absneg [abs neg])
907 ;; Base name for x87 insn mnemonic.
908 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
910 ;; Used in signed and unsigned widening multiplications.
911 (define_code_iterator any_extend [sign_extend zero_extend])
913 ;; Prefix for insn menmonic.
914 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
916 ;; Prefix for define_insn
917 (define_code_attr u [(sign_extend "") (zero_extend "u")])
918 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
919 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
921 ;; Used in signed and unsigned truncations.
922 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
923 ;; Instruction suffix for truncations.
924 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
926 ;; Used in signed and unsigned fix.
927 (define_code_iterator any_fix [fix unsigned_fix])
928 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
930 ;; Used in signed and unsigned float.
931 (define_code_iterator any_float [float unsigned_float])
932 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
934 ;; All integer modes.
935 (define_mode_iterator SWI1248x [QI HI SI DI])
937 ;; All integer modes with AVX512BW.
938 (define_mode_iterator SWI1248_AVX512BW
939 [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
941 ;; All integer modes without QImode.
942 (define_mode_iterator SWI248x [HI SI DI])
944 ;; All integer modes without QImode and HImode.
945 (define_mode_iterator SWI48x [SI DI])
947 ;; All integer modes without SImode and DImode.
948 (define_mode_iterator SWI12 [QI HI])
950 ;; All integer modes without DImode.
951 (define_mode_iterator SWI124 [QI HI SI])
953 ;; All integer modes without QImode and DImode.
954 (define_mode_iterator SWI24 [HI SI])
956 ;; Single word integer modes.
957 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
959 ;; Single word integer modes without QImode.
960 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
962 ;; Single word integer modes without QImode and HImode.
963 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
965 ;; All math-dependant single and double word integer modes.
966 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
967 (HI "TARGET_HIMODE_MATH")
968 SI DI (TI "TARGET_64BIT")])
970 ;; Math-dependant single word integer modes.
971 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
972 (HI "TARGET_HIMODE_MATH")
973 SI (DI "TARGET_64BIT")])
975 ;; Math-dependant integer modes without DImode.
976 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
977 (HI "TARGET_HIMODE_MATH")
980 ;; Math-dependant single word integer modes without QImode.
981 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
982 SI (DI "TARGET_64BIT")])
984 ;; Double word integer modes.
985 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
986 (TI "TARGET_64BIT")])
988 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
989 ;; compile time constant, it is faster to use <MODE_SIZE> than
990 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
991 ;; command line options just use GET_MODE_SIZE macro.
992 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
993 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
994 (V16QI "16") (V32QI "32") (V64QI "64")
995 (V8HI "16") (V16HI "32") (V32HI "64")
996 (V4SI "16") (V8SI "32") (V16SI "64")
997 (V2DI "16") (V4DI "32") (V8DI "64")
998 (V1TI "16") (V2TI "32") (V4TI "64")
999 (V2DF "16") (V4DF "32") (V8DF "64")
1000 (V4SF "16") (V8SF "32") (V16SF "64")])
1002 ;; Double word integer modes as mode attribute.
1003 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1004 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1006 ;; Half mode for double word integer modes.
1007 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1008 (DI "TARGET_64BIT")])
1011 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1012 (BND64 "TARGET_LP64")])
1014 ;; Pointer mode corresponding to bound mode.
1015 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1018 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1021 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1023 (UNSPEC_BNDCN "cn")])
1025 ;; Instruction suffix for integer modes.
1026 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1028 ;; Instruction suffix for masks.
1029 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1031 ;; Pointer size prefix for integer modes (Intel asm dialect)
1032 (define_mode_attr iptrsize [(QI "BYTE")
1037 ;; Register class for integer modes.
1038 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1040 ;; Immediate operand constraint for integer modes.
1041 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1043 ;; General operand constraint for word modes.
1044 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1046 ;; Immediate operand constraint for double integer modes.
1047 (define_mode_attr di [(SI "nF") (DI "e")])
1049 ;; Immediate operand constraint for shifts.
1050 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1052 ;; General operand predicate for integer modes.
1053 (define_mode_attr general_operand
1054 [(QI "general_operand")
1055 (HI "general_operand")
1056 (SI "x86_64_general_operand")
1057 (DI "x86_64_general_operand")
1058 (TI "x86_64_general_operand")])
1060 ;; General sign extend operand predicate for integer modes,
1061 ;; which disallows VOIDmode operands and thus it is suitable
1062 ;; for use inside sign_extend.
1063 (define_mode_attr general_sext_operand
1064 [(QI "sext_operand")
1066 (SI "x86_64_sext_operand")
1067 (DI "x86_64_sext_operand")])
1069 ;; General sign/zero extend operand predicate for integer modes.
1070 (define_mode_attr general_szext_operand
1071 [(QI "general_operand")
1072 (HI "general_operand")
1073 (SI "x86_64_szext_general_operand")
1074 (DI "x86_64_szext_general_operand")])
1076 ;; Immediate operand predicate for integer modes.
1077 (define_mode_attr immediate_operand
1078 [(QI "immediate_operand")
1079 (HI "immediate_operand")
1080 (SI "x86_64_immediate_operand")
1081 (DI "x86_64_immediate_operand")])
1083 ;; Nonmemory operand predicate for integer modes.
1084 (define_mode_attr nonmemory_operand
1085 [(QI "nonmemory_operand")
1086 (HI "nonmemory_operand")
1087 (SI "x86_64_nonmemory_operand")
1088 (DI "x86_64_nonmemory_operand")])
1090 ;; Operand predicate for shifts.
1091 (define_mode_attr shift_operand
1092 [(QI "nonimmediate_operand")
1093 (HI "nonimmediate_operand")
1094 (SI "nonimmediate_operand")
1095 (DI "shiftdi_operand")
1096 (TI "register_operand")])
1098 ;; Operand predicate for shift argument.
1099 (define_mode_attr shift_immediate_operand
1100 [(QI "const_1_to_31_operand")
1101 (HI "const_1_to_31_operand")
1102 (SI "const_1_to_31_operand")
1103 (DI "const_1_to_63_operand")])
1105 ;; Input operand predicate for arithmetic left shifts.
1106 (define_mode_attr ashl_input_operand
1107 [(QI "nonimmediate_operand")
1108 (HI "nonimmediate_operand")
1109 (SI "nonimmediate_operand")
1110 (DI "ashldi_input_operand")
1111 (TI "reg_or_pm1_operand")])
1113 ;; SSE and x87 SFmode and DFmode floating point modes
1114 (define_mode_iterator MODEF [SF DF])
1116 ;; All x87 floating point modes
1117 (define_mode_iterator X87MODEF [SF DF XF])
1119 ;; SSE instruction suffix for various modes
1120 (define_mode_attr ssemodesuffix
1121 [(SF "ss") (DF "sd")
1122 (V16SF "ps") (V8DF "pd")
1123 (V8SF "ps") (V4DF "pd")
1124 (V4SF "ps") (V2DF "pd")
1125 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1126 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1127 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1129 ;; SSE vector suffix for floating point modes
1130 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1132 ;; SSE vector mode corresponding to a scalar mode
1133 (define_mode_attr ssevecmode
1134 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1135 (define_mode_attr ssevecmodelower
1136 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1138 ;; Instruction suffix for REX 64bit operators.
1139 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1141 ;; This mode iterator allows :P to be used for patterns that operate on
1142 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1143 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1145 ;; This mode iterator allows :W to be used for patterns that operate on
1146 ;; word_mode sized quantities.
1147 (define_mode_iterator W
1148 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1150 ;; This mode iterator allows :PTR to be used for patterns that operate on
1151 ;; ptr_mode sized quantities.
1152 (define_mode_iterator PTR
1153 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1155 ;; Scheduling descriptions
1157 (include "pentium.md")
1160 (include "athlon.md")
1161 (include "bdver1.md")
1162 (include "bdver3.md")
1163 (include "btver2.md")
1164 (include "geode.md")
1167 (include "core2.md")
1170 ;; Operand and operator predicates and constraints
1172 (include "predicates.md")
1173 (include "constraints.md")
1176 ;; Compare and branch/compare and store instructions.
1178 (define_expand "cbranch<mode>4"
1179 [(set (reg:CC FLAGS_REG)
1180 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1181 (match_operand:SDWIM 2 "<general_operand>")))
1182 (set (pc) (if_then_else
1183 (match_operator 0 "ordered_comparison_operator"
1184 [(reg:CC FLAGS_REG) (const_int 0)])
1185 (label_ref (match_operand 3))
1189 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1190 operands[1] = force_reg (<MODE>mode, operands[1]);
1191 ix86_expand_branch (GET_CODE (operands[0]),
1192 operands[1], operands[2], operands[3]);
1196 (define_expand "cstore<mode>4"
1197 [(set (reg:CC FLAGS_REG)
1198 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1199 (match_operand:SWIM 3 "<general_operand>")))
1200 (set (match_operand:QI 0 "register_operand")
1201 (match_operator 1 "ordered_comparison_operator"
1202 [(reg:CC FLAGS_REG) (const_int 0)]))]
1205 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1206 operands[2] = force_reg (<MODE>mode, operands[2]);
1207 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1208 operands[2], operands[3]);
1212 (define_expand "cmp<mode>_1"
1213 [(set (reg:CC FLAGS_REG)
1214 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1215 (match_operand:SWI48 1 "<general_operand>")))])
1217 (define_insn "*cmp<mode>_ccno_1"
1218 [(set (reg FLAGS_REG)
1219 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1220 (match_operand:SWI 1 "const0_operand")))]
1221 "ix86_match_ccmode (insn, CCNOmode)"
1223 test{<imodesuffix>}\t%0, %0
1224 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1225 [(set_attr "type" "test,icmp")
1226 (set_attr "length_immediate" "0,1")
1227 (set_attr "mode" "<MODE>")])
1229 (define_insn "*cmp<mode>_1"
1230 [(set (reg FLAGS_REG)
1231 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1232 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1233 "ix86_match_ccmode (insn, CCmode)"
1234 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1235 [(set_attr "type" "icmp")
1236 (set_attr "mode" "<MODE>")])
1238 (define_insn "*cmp<mode>_minus_1"
1239 [(set (reg FLAGS_REG)
1241 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1242 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1244 "ix86_match_ccmode (insn, CCGOCmode)"
1245 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1246 [(set_attr "type" "icmp")
1247 (set_attr "mode" "<MODE>")])
1249 (define_insn "*cmpqi_ext_1"
1250 [(set (reg FLAGS_REG)
1252 (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1255 (match_operand 1 "ext_register_operand" "Q,Q")
1257 (const_int 8)) 0)))]
1258 "ix86_match_ccmode (insn, CCmode)"
1259 "cmp{b}\t{%h1, %0|%0, %h1}"
1260 [(set_attr "isa" "*,nox64")
1261 (set_attr "type" "icmp")
1262 (set_attr "mode" "QI")])
1264 (define_insn "*cmpqi_ext_2"
1265 [(set (reg FLAGS_REG)
1269 (match_operand 0 "ext_register_operand" "Q")
1272 (match_operand:QI 1 "const0_operand")))]
1273 "ix86_match_ccmode (insn, CCNOmode)"
1275 [(set_attr "type" "test")
1276 (set_attr "length_immediate" "0")
1277 (set_attr "mode" "QI")])
1279 (define_expand "cmpqi_ext_3"
1280 [(set (reg:CC FLAGS_REG)
1284 (match_operand 0 "ext_register_operand")
1287 (match_operand:QI 1 "const_int_operand")))])
1289 (define_insn "*cmpqi_ext_3"
1290 [(set (reg FLAGS_REG)
1294 (match_operand 0 "ext_register_operand" "Q,Q")
1297 (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1298 "ix86_match_ccmode (insn, CCmode)"
1299 "cmp{b}\t{%1, %h0|%h0, %1}"
1300 [(set_attr "isa" "*,nox64")
1301 (set_attr "type" "icmp")
1302 (set_attr "modrm" "1")
1303 (set_attr "mode" "QI")])
1305 (define_insn "*cmpqi_ext_4"
1306 [(set (reg FLAGS_REG)
1310 (match_operand 0 "ext_register_operand" "Q")
1315 (match_operand 1 "ext_register_operand" "Q")
1317 (const_int 8)) 0)))]
1318 "ix86_match_ccmode (insn, CCmode)"
1319 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1320 [(set_attr "type" "icmp")
1321 (set_attr "mode" "QI")])
1323 ;; These implement float point compares.
1324 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1325 ;; which would allow mix and match FP modes on the compares. Which is what
1326 ;; the old patterns did, but with many more of them.
1328 (define_expand "cbranchxf4"
1329 [(set (reg:CC FLAGS_REG)
1330 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1331 (match_operand:XF 2 "nonmemory_operand")))
1332 (set (pc) (if_then_else
1333 (match_operator 0 "ix86_fp_comparison_operator"
1336 (label_ref (match_operand 3))
1340 ix86_expand_branch (GET_CODE (operands[0]),
1341 operands[1], operands[2], operands[3]);
1345 (define_expand "cstorexf4"
1346 [(set (reg:CC FLAGS_REG)
1347 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1348 (match_operand:XF 3 "nonmemory_operand")))
1349 (set (match_operand:QI 0 "register_operand")
1350 (match_operator 1 "ix86_fp_comparison_operator"
1355 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1356 operands[2], operands[3]);
1360 (define_expand "cbranch<mode>4"
1361 [(set (reg:CC FLAGS_REG)
1362 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1363 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1364 (set (pc) (if_then_else
1365 (match_operator 0 "ix86_fp_comparison_operator"
1368 (label_ref (match_operand 3))
1370 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1372 ix86_expand_branch (GET_CODE (operands[0]),
1373 operands[1], operands[2], operands[3]);
1377 (define_expand "cstore<mode>4"
1378 [(set (reg:CC FLAGS_REG)
1379 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1380 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1381 (set (match_operand:QI 0 "register_operand")
1382 (match_operator 1 "ix86_fp_comparison_operator"
1385 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1387 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1388 operands[2], operands[3]);
1392 (define_expand "cbranchcc4"
1393 [(set (pc) (if_then_else
1394 (match_operator 0 "comparison_operator"
1395 [(match_operand 1 "flags_reg_operand")
1396 (match_operand 2 "const0_operand")])
1397 (label_ref (match_operand 3))
1401 ix86_expand_branch (GET_CODE (operands[0]),
1402 operands[1], operands[2], operands[3]);
1406 (define_expand "cstorecc4"
1407 [(set (match_operand:QI 0 "register_operand")
1408 (match_operator 1 "comparison_operator"
1409 [(match_operand 2 "flags_reg_operand")
1410 (match_operand 3 "const0_operand")]))]
1413 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1414 operands[2], operands[3]);
1419 ;; FP compares, step 1:
1420 ;; Set the FP condition codes.
1422 ;; CCFPmode compare with exceptions
1423 ;; CCFPUmode compare with no exceptions
1425 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1426 ;; used to manage the reg stack popping would not be preserved.
1428 (define_insn "*cmp<mode>_0_i387"
1429 [(set (match_operand:HI 0 "register_operand" "=a")
1432 (match_operand:X87MODEF 1 "register_operand" "f")
1433 (match_operand:X87MODEF 2 "const0_operand"))]
1436 "* return output_fp_compare (insn, operands, false, false);"
1437 [(set_attr "type" "multi")
1438 (set_attr "unit" "i387")
1439 (set_attr "mode" "<MODE>")])
1441 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1442 [(set (reg:CCFP FLAGS_REG)
1444 (match_operand:X87MODEF 1 "register_operand" "f")
1445 (match_operand:X87MODEF 2 "const0_operand")))
1446 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1447 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1449 "&& reload_completed"
1452 [(compare:CCFP (match_dup 1)(match_dup 2))]
1454 (set (reg:CC FLAGS_REG)
1455 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1457 [(set_attr "type" "multi")
1458 (set_attr "unit" "i387")
1459 (set_attr "mode" "<MODE>")])
1461 (define_insn "*cmpxf_i387"
1462 [(set (match_operand:HI 0 "register_operand" "=a")
1465 (match_operand:XF 1 "register_operand" "f")
1466 (match_operand:XF 2 "register_operand" "f"))]
1469 "* return output_fp_compare (insn, operands, false, false);"
1470 [(set_attr "type" "multi")
1471 (set_attr "unit" "i387")
1472 (set_attr "mode" "XF")])
1474 (define_insn_and_split "*cmpxf_cc_i387"
1475 [(set (reg:CCFP FLAGS_REG)
1477 (match_operand:XF 1 "register_operand" "f")
1478 (match_operand:XF 2 "register_operand" "f")))
1479 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1480 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1482 "&& reload_completed"
1485 [(compare:CCFP (match_dup 1)(match_dup 2))]
1487 (set (reg:CC FLAGS_REG)
1488 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1490 [(set_attr "type" "multi")
1491 (set_attr "unit" "i387")
1492 (set_attr "mode" "XF")])
1494 (define_insn "*cmp<mode>_i387"
1495 [(set (match_operand:HI 0 "register_operand" "=a")
1498 (match_operand:MODEF 1 "register_operand" "f")
1499 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1502 "* return output_fp_compare (insn, operands, false, false);"
1503 [(set_attr "type" "multi")
1504 (set_attr "unit" "i387")
1505 (set_attr "mode" "<MODE>")])
1507 (define_insn_and_split "*cmp<mode>_cc_i387"
1508 [(set (reg:CCFP FLAGS_REG)
1510 (match_operand:MODEF 1 "register_operand" "f")
1511 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1512 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1513 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1515 "&& reload_completed"
1518 [(compare:CCFP (match_dup 1)(match_dup 2))]
1520 (set (reg:CC FLAGS_REG)
1521 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1523 [(set_attr "type" "multi")
1524 (set_attr "unit" "i387")
1525 (set_attr "mode" "<MODE>")])
1527 (define_insn "*cmpu<mode>_i387"
1528 [(set (match_operand:HI 0 "register_operand" "=a")
1531 (match_operand:X87MODEF 1 "register_operand" "f")
1532 (match_operand:X87MODEF 2 "register_operand" "f"))]
1535 "* return output_fp_compare (insn, operands, false, true);"
1536 [(set_attr "type" "multi")
1537 (set_attr "unit" "i387")
1538 (set_attr "mode" "<MODE>")])
1540 (define_insn_and_split "*cmpu<mode>_cc_i387"
1541 [(set (reg:CCFPU FLAGS_REG)
1543 (match_operand:X87MODEF 1 "register_operand" "f")
1544 (match_operand:X87MODEF 2 "register_operand" "f")))
1545 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1546 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1548 "&& reload_completed"
1551 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1553 (set (reg:CC FLAGS_REG)
1554 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1556 [(set_attr "type" "multi")
1557 (set_attr "unit" "i387")
1558 (set_attr "mode" "<MODE>")])
1560 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1561 [(set (match_operand:HI 0 "register_operand" "=a")
1564 (match_operand:X87MODEF 1 "register_operand" "f")
1565 (match_operator:X87MODEF 3 "float_operator"
1566 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1569 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1570 || optimize_function_for_size_p (cfun))"
1571 "* return output_fp_compare (insn, operands, false, false);"
1572 [(set_attr "type" "multi")
1573 (set_attr "unit" "i387")
1574 (set_attr "fp_int_src" "true")
1575 (set_attr "mode" "<SWI24:MODE>")])
1577 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1578 [(set (reg:CCFP FLAGS_REG)
1580 (match_operand:X87MODEF 1 "register_operand" "f")
1581 (match_operator:X87MODEF 3 "float_operator"
1582 [(match_operand:SWI24 2 "memory_operand" "m")])))
1583 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1584 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1585 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1586 || optimize_function_for_size_p (cfun))"
1588 "&& reload_completed"
1593 (match_op_dup 3 [(match_dup 2)]))]
1595 (set (reg:CC FLAGS_REG)
1596 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1598 [(set_attr "type" "multi")
1599 (set_attr "unit" "i387")
1600 (set_attr "fp_int_src" "true")
1601 (set_attr "mode" "<SWI24:MODE>")])
1603 ;; FP compares, step 2
1604 ;; Move the fpsw to ax.
1606 (define_insn "x86_fnstsw_1"
1607 [(set (match_operand:HI 0 "register_operand" "=a")
1608 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1611 [(set_attr "length" "2")
1612 (set_attr "mode" "SI")
1613 (set_attr "unit" "i387")])
1615 ;; FP compares, step 3
1616 ;; Get ax into flags, general case.
1618 (define_insn "x86_sahf_1"
1619 [(set (reg:CC FLAGS_REG)
1620 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1624 #ifndef HAVE_AS_IX86_SAHF
1626 return ASM_BYTE "0x9e";
1631 [(set_attr "length" "1")
1632 (set_attr "athlon_decode" "vector")
1633 (set_attr "amdfam10_decode" "direct")
1634 (set_attr "bdver1_decode" "direct")
1635 (set_attr "mode" "SI")])
1637 ;; Pentium Pro can do steps 1 through 3 in one go.
1638 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1639 ;; (these i387 instructions set flags directly)
1641 (define_mode_iterator FPCMP [CCFP CCFPU])
1642 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1644 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1645 [(set (reg:FPCMP FLAGS_REG)
1647 (match_operand:MODEF 0 "register_operand" "f,x")
1648 (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1649 "TARGET_MIX_SSE_I387
1650 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1651 "* return output_fp_compare (insn, operands, true,
1652 <FPCMP:MODE>mode == CCFPUmode);"
1653 [(set_attr "type" "fcmp,ssecomi")
1654 (set_attr "prefix" "orig,maybe_vex")
1655 (set_attr "mode" "<MODEF:MODE>")
1656 (set (attr "prefix_rep")
1657 (if_then_else (eq_attr "type" "ssecomi")
1659 (const_string "*")))
1660 (set (attr "prefix_data16")
1661 (cond [(eq_attr "type" "fcmp")
1663 (eq_attr "mode" "DF")
1666 (const_string "0")))
1667 (set_attr "athlon_decode" "vector")
1668 (set_attr "amdfam10_decode" "direct")
1669 (set_attr "bdver1_decode" "double")])
1671 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1672 [(set (reg:FPCMP FLAGS_REG)
1674 (match_operand:MODEF 0 "register_operand" "x")
1675 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1677 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1678 "* return output_fp_compare (insn, operands, true,
1679 <FPCMP:MODE>mode == CCFPUmode);"
1680 [(set_attr "type" "ssecomi")
1681 (set_attr "prefix" "maybe_vex")
1682 (set_attr "mode" "<MODEF:MODE>")
1683 (set_attr "prefix_rep" "0")
1684 (set (attr "prefix_data16")
1685 (if_then_else (eq_attr "mode" "DF")
1687 (const_string "0")))
1688 (set_attr "athlon_decode" "vector")
1689 (set_attr "amdfam10_decode" "direct")
1690 (set_attr "bdver1_decode" "double")])
1692 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1693 [(set (reg:FPCMP FLAGS_REG)
1695 (match_operand:X87MODEF 0 "register_operand" "f")
1696 (match_operand:X87MODEF 1 "register_operand" "f")))]
1697 "TARGET_80387 && TARGET_CMOVE
1698 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1699 "* return output_fp_compare (insn, operands, true,
1700 <FPCMP:MODE>mode == CCFPUmode);"
1701 [(set_attr "type" "fcmp")
1702 (set_attr "mode" "<X87MODEF:MODE>")
1703 (set_attr "athlon_decode" "vector")
1704 (set_attr "amdfam10_decode" "direct")
1705 (set_attr "bdver1_decode" "double")])
1707 ;; Push/pop instructions.
1709 (define_insn "*push<mode>2"
1710 [(set (match_operand:DWI 0 "push_operand" "=<")
1711 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1714 [(set_attr "type" "multi")
1715 (set_attr "mode" "<MODE>")])
1718 [(set (match_operand:TI 0 "push_operand")
1719 (match_operand:TI 1 "general_operand"))]
1720 "TARGET_64BIT && reload_completed
1721 && !SSE_REG_P (operands[1])"
1723 "ix86_split_long_move (operands); DONE;")
1725 (define_insn "*pushdi2_rex64"
1726 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1727 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1732 [(set_attr "type" "push,multi")
1733 (set_attr "mode" "DI")])
1735 ;; Convert impossible pushes of immediate to existing instructions.
1736 ;; First try to get scratch register and go through it. In case this
1737 ;; fails, push sign extended lower part first and then overwrite
1738 ;; upper part by 32bit move.
1740 [(match_scratch:DI 2 "r")
1741 (set (match_operand:DI 0 "push_operand")
1742 (match_operand:DI 1 "immediate_operand"))]
1743 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1744 && !x86_64_immediate_operand (operands[1], DImode)"
1745 [(set (match_dup 2) (match_dup 1))
1746 (set (match_dup 0) (match_dup 2))])
1748 ;; We need to define this as both peepholer and splitter for case
1749 ;; peephole2 pass is not run.
1750 ;; "&& 1" is needed to keep it from matching the previous pattern.
1752 [(set (match_operand:DI 0 "push_operand")
1753 (match_operand:DI 1 "immediate_operand"))]
1754 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1755 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1756 [(set (match_dup 0) (match_dup 1))
1757 (set (match_dup 2) (match_dup 3))]
1759 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1761 operands[1] = gen_lowpart (DImode, operands[2]);
1762 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1767 [(set (match_operand:DI 0 "push_operand")
1768 (match_operand:DI 1 "immediate_operand"))]
1769 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1770 ? epilogue_completed : reload_completed)
1771 && !symbolic_operand (operands[1], DImode)
1772 && !x86_64_immediate_operand (operands[1], DImode)"
1773 [(set (match_dup 0) (match_dup 1))
1774 (set (match_dup 2) (match_dup 3))]
1776 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1778 operands[1] = gen_lowpart (DImode, operands[2]);
1779 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1784 [(set (match_operand:DI 0 "push_operand")
1785 (match_operand:DI 1 "general_operand"))]
1786 "!TARGET_64BIT && reload_completed
1787 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1789 "ix86_split_long_move (operands); DONE;")
1791 (define_insn "*pushsi2"
1792 [(set (match_operand:SI 0 "push_operand" "=<")
1793 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1796 [(set_attr "type" "push")
1797 (set_attr "mode" "SI")])
1799 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1800 ;; "push a byte/word". But actually we use pushl, which has the effect
1801 ;; of rounding the amount pushed up to a word.
1803 ;; For TARGET_64BIT we always round up to 8 bytes.
1804 (define_insn "*push<mode>2_rex64"
1805 [(set (match_operand:SWI124 0 "push_operand" "=X")
1806 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1809 [(set_attr "type" "push")
1810 (set_attr "mode" "DI")])
1812 (define_insn "*push<mode>2"
1813 [(set (match_operand:SWI12 0 "push_operand" "=X")
1814 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1817 [(set_attr "type" "push")
1818 (set_attr "mode" "SI")])
1820 (define_insn "*push<mode>2_prologue"
1821 [(set (match_operand:W 0 "push_operand" "=<")
1822 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1823 (clobber (mem:BLK (scratch)))]
1825 "push{<imodesuffix>}\t%1"
1826 [(set_attr "type" "push")
1827 (set_attr "mode" "<MODE>")])
1829 (define_insn "*pop<mode>1"
1830 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1831 (match_operand:W 1 "pop_operand" ">"))]
1833 "pop{<imodesuffix>}\t%0"
1834 [(set_attr "type" "pop")
1835 (set_attr "mode" "<MODE>")])
1837 (define_insn "*pop<mode>1_epilogue"
1838 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1839 (match_operand:W 1 "pop_operand" ">"))
1840 (clobber (mem:BLK (scratch)))]
1842 "pop{<imodesuffix>}\t%0"
1843 [(set_attr "type" "pop")
1844 (set_attr "mode" "<MODE>")])
1846 (define_insn "*pushfl<mode>2"
1847 [(set (match_operand:W 0 "push_operand" "=<")
1848 (match_operand:W 1 "flags_reg_operand"))]
1850 "pushf{<imodesuffix>}"
1851 [(set_attr "type" "push")
1852 (set_attr "mode" "<MODE>")])
1854 (define_insn "*popfl<mode>1"
1855 [(set (match_operand:W 0 "flags_reg_operand")
1856 (match_operand:W 1 "pop_operand" ">"))]
1858 "popf{<imodesuffix>}"
1859 [(set_attr "type" "pop")
1860 (set_attr "mode" "<MODE>")])
1863 ;; Move instructions.
1865 (define_expand "movxi"
1866 [(set (match_operand:XI 0 "nonimmediate_operand")
1867 (match_operand:XI 1 "general_operand"))]
1869 "ix86_expand_move (XImode, operands); DONE;")
1871 ;; Reload patterns to support multi-word load/store
1872 ;; with non-offsetable address.
1873 (define_expand "reload_noff_store"
1874 [(parallel [(match_operand 0 "memory_operand" "=m")
1875 (match_operand 1 "register_operand" "r")
1876 (match_operand:DI 2 "register_operand" "=&r")])]
1879 rtx mem = operands[0];
1880 rtx addr = XEXP (mem, 0);
1882 emit_move_insn (operands[2], addr);
1883 mem = replace_equiv_address_nv (mem, operands[2]);
1885 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1889 (define_expand "reload_noff_load"
1890 [(parallel [(match_operand 0 "register_operand" "=r")
1891 (match_operand 1 "memory_operand" "m")
1892 (match_operand:DI 2 "register_operand" "=r")])]
1895 rtx mem = operands[1];
1896 rtx addr = XEXP (mem, 0);
1898 emit_move_insn (operands[2], addr);
1899 mem = replace_equiv_address_nv (mem, operands[2]);
1901 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1905 (define_expand "movoi"
1906 [(set (match_operand:OI 0 "nonimmediate_operand")
1907 (match_operand:OI 1 "general_operand"))]
1909 "ix86_expand_move (OImode, operands); DONE;")
1911 (define_expand "movti"
1912 [(set (match_operand:TI 0 "nonimmediate_operand")
1913 (match_operand:TI 1 "nonimmediate_operand"))]
1914 "TARGET_64BIT || TARGET_SSE"
1917 ix86_expand_move (TImode, operands);
1919 ix86_expand_vector_move (TImode, operands);
1923 ;; This expands to what emit_move_complex would generate if we didn't
1924 ;; have a movti pattern. Having this avoids problems with reload on
1925 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1926 ;; to have around all the time.
1927 (define_expand "movcdi"
1928 [(set (match_operand:CDI 0 "nonimmediate_operand")
1929 (match_operand:CDI 1 "general_operand"))]
1932 if (push_operand (operands[0], CDImode))
1933 emit_move_complex_push (CDImode, operands[0], operands[1]);
1935 emit_move_complex_parts (operands[0], operands[1]);
1939 (define_expand "mov<mode>"
1940 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1941 (match_operand:SWI1248x 1 "general_operand"))]
1943 "ix86_expand_move (<MODE>mode, operands); DONE;")
1945 (define_insn "*mov<mode>_xor"
1946 [(set (match_operand:SWI48 0 "register_operand" "=r")
1947 (match_operand:SWI48 1 "const0_operand"))
1948 (clobber (reg:CC FLAGS_REG))]
1951 [(set_attr "type" "alu1")
1952 (set_attr "mode" "SI")
1953 (set_attr "length_immediate" "0")])
1955 (define_insn "*mov<mode>_or"
1956 [(set (match_operand:SWI48 0 "register_operand" "=r")
1957 (match_operand:SWI48 1 "const_int_operand"))
1958 (clobber (reg:CC FLAGS_REG))]
1960 && operands[1] == constm1_rtx"
1961 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1962 [(set_attr "type" "alu1")
1963 (set_attr "mode" "<MODE>")
1964 (set_attr "length_immediate" "1")])
1966 (define_insn "*movxi_internal_avx512f"
1967 [(set (match_operand:XI 0 "nonimmediate_operand" "=x,x ,m")
1968 (match_operand:XI 1 "vector_move_operand" "C ,xm,x"))]
1969 "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1971 switch (which_alternative)
1974 return standard_sse_constant_opcode (insn, operands[1]);
1977 if (misaligned_operand (operands[0], XImode)
1978 || misaligned_operand (operands[1], XImode))
1979 return "vmovdqu32\t{%1, %0|%0, %1}";
1981 return "vmovdqa32\t{%1, %0|%0, %1}";
1986 [(set_attr "type" "sselog1,ssemov,ssemov")
1987 (set_attr "prefix" "evex")
1988 (set_attr "mode" "XI")])
1990 (define_insn "*movoi_internal_avx"
1991 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,m")
1992 (match_operand:OI 1 "vector_move_operand" "C ,vm,v"))]
1993 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1995 switch (get_attr_type (insn))
1998 return standard_sse_constant_opcode (insn, operands[1]);
2001 if (misaligned_operand (operands[0], OImode)
2002 || misaligned_operand (operands[1], OImode))
2004 if (get_attr_mode (insn) == MODE_V8SF)
2005 return "vmovups\t{%1, %0|%0, %1}";
2006 else if (get_attr_mode (insn) == MODE_XI)
2007 return "vmovdqu32\t{%1, %0|%0, %1}";
2009 return "vmovdqu\t{%1, %0|%0, %1}";
2013 if (get_attr_mode (insn) == MODE_V8SF)
2014 return "vmovaps\t{%1, %0|%0, %1}";
2015 else if (get_attr_mode (insn) == MODE_XI)
2016 return "vmovdqa32\t{%1, %0|%0, %1}";
2018 return "vmovdqa\t{%1, %0|%0, %1}";
2025 [(set_attr "type" "sselog1,ssemov,ssemov")
2026 (set_attr "prefix" "vex")
2028 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2029 (match_operand 1 "ext_sse_reg_operand"))
2031 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2032 (const_string "V8SF")
2033 (and (eq_attr "alternative" "2")
2034 (match_test "TARGET_SSE_TYPELESS_STORES"))
2035 (const_string "V8SF")
2037 (const_string "OI")))])
2039 (define_insn "*movti_internal"
2040 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,m")
2041 (match_operand:TI 1 "general_operand" "riFo,re,C,vm,v"))]
2042 "(TARGET_64BIT || TARGET_SSE)
2043 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2045 switch (get_attr_type (insn))
2051 return standard_sse_constant_opcode (insn, operands[1]);
2054 /* TDmode values are passed as TImode on the stack. Moving them
2055 to stack may result in unaligned memory access. */
2056 if (misaligned_operand (operands[0], TImode)
2057 || misaligned_operand (operands[1], TImode))
2059 if (get_attr_mode (insn) == MODE_V4SF)
2060 return "%vmovups\t{%1, %0|%0, %1}";
2061 else if (get_attr_mode (insn) == MODE_XI)
2062 return "vmovdqu32\t{%1, %0|%0, %1}";
2064 return "%vmovdqu\t{%1, %0|%0, %1}";
2068 if (get_attr_mode (insn) == MODE_V4SF)
2069 return "%vmovaps\t{%1, %0|%0, %1}";
2070 else if (get_attr_mode (insn) == MODE_XI)
2071 return "vmovdqa32\t{%1, %0|%0, %1}";
2073 return "%vmovdqa\t{%1, %0|%0, %1}";
2080 [(set_attr "isa" "x64,x64,*,*,*")
2081 (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
2082 (set (attr "prefix")
2083 (if_then_else (eq_attr "type" "sselog1,ssemov")
2084 (const_string "maybe_vex")
2085 (const_string "orig")))
2087 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2088 (match_operand 1 "ext_sse_reg_operand"))
2090 (eq_attr "alternative" "0,1")
2092 (ior (not (match_test "TARGET_SSE2"))
2093 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2094 (const_string "V4SF")
2095 (and (eq_attr "alternative" "4")
2096 (match_test "TARGET_SSE_TYPELESS_STORES"))
2097 (const_string "V4SF")
2098 (match_test "TARGET_AVX")
2100 (match_test "optimize_function_for_size_p (cfun)")
2101 (const_string "V4SF")
2103 (const_string "TI")))])
2106 [(set (match_operand:TI 0 "nonimmediate_operand")
2107 (match_operand:TI 1 "general_operand"))]
2109 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2111 "ix86_split_long_move (operands); DONE;")
2113 (define_insn "*movdi_internal"
2114 [(set (match_operand:DI 0 "nonimmediate_operand"
2115 "=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")
2116 (match_operand:DI 1 "general_operand"
2117 "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"))]
2118 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2120 switch (get_attr_type (insn))
2123 return "kmovq\t{%1, %0|%0, %1}";
2129 return "pxor\t%0, %0";
2132 /* Handle broken assemblers that require movd instead of movq. */
2133 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2134 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2135 return "movd\t{%1, %0|%0, %1}";
2136 return "movq\t{%1, %0|%0, %1}";
2139 if (GENERAL_REG_P (operands[0]))
2140 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2142 return standard_sse_constant_opcode (insn, operands[1]);
2145 switch (get_attr_mode (insn))
2148 /* Handle broken assemblers that require movd instead of movq. */
2149 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2150 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2151 return "%vmovd\t{%1, %0|%0, %1}";
2152 return "%vmovq\t{%1, %0|%0, %1}";
2154 return "%vmovdqa\t{%1, %0|%0, %1}";
2156 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2159 gcc_assert (!TARGET_AVX);
2160 return "movlps\t{%1, %0|%0, %1}";
2162 return "%vmovaps\t{%1, %0|%0, %1}";
2169 if (SSE_REG_P (operands[0]))
2170 return "movq2dq\t{%1, %0|%0, %1}";
2172 return "movdq2q\t{%1, %0|%0, %1}";
2175 return "lea{q}\t{%E1, %0|%0, %E1}";
2178 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2179 if (get_attr_mode (insn) == MODE_SI)
2180 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2181 else if (which_alternative == 4)
2182 return "movabs{q}\t{%1, %0|%0, %1}";
2183 else if (ix86_use_lea_for_mov (insn, operands))
2184 return "lea{q}\t{%E1, %0|%0, %E1}";
2186 return "mov{q}\t{%1, %0|%0, %1}";
2193 (cond [(eq_attr "alternative" "0,1")
2194 (const_string "nox64")
2195 (eq_attr "alternative" "2,3,4,5,10,11,16,18,21,23")
2196 (const_string "x64")
2197 (eq_attr "alternative" "17")
2198 (const_string "x64_sse4")
2200 (const_string "*")))
2202 (cond [(eq_attr "alternative" "0,1")
2203 (const_string "multi")
2204 (eq_attr "alternative" "6")
2205 (const_string "mmx")
2206 (eq_attr "alternative" "7,8,9,10,11")
2207 (const_string "mmxmov")
2208 (eq_attr "alternative" "12,17")
2209 (const_string "sselog1")
2210 (eq_attr "alternative" "13,14,15,16,18")
2211 (const_string "ssemov")
2212 (eq_attr "alternative" "19,20")
2213 (const_string "ssecvt")
2214 (eq_attr "alternative" "21,22,23,24")
2215 (const_string "mskmov")
2216 (and (match_operand 0 "register_operand")
2217 (match_operand 1 "pic_32bit_operand"))
2218 (const_string "lea")
2220 (const_string "imov")))
2223 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2225 (const_string "*")))
2226 (set (attr "length_immediate")
2227 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2229 (eq_attr "alternative" "17")
2232 (const_string "*")))
2233 (set (attr "prefix_rex")
2234 (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2236 (const_string "*")))
2237 (set (attr "prefix_extra")
2238 (if_then_else (eq_attr "alternative" "17")
2240 (const_string "*")))
2241 (set (attr "prefix")
2242 (if_then_else (eq_attr "type" "sselog1,ssemov")
2243 (const_string "maybe_vex")
2244 (const_string "orig")))
2245 (set (attr "prefix_data16")
2246 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2248 (const_string "*")))
2250 (cond [(eq_attr "alternative" "2")
2252 (eq_attr "alternative" "12,13")
2253 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2254 (match_operand 1 "ext_sse_reg_operand"))
2256 (ior (not (match_test "TARGET_SSE2"))
2257 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2258 (const_string "V4SF")
2259 (match_test "TARGET_AVX")
2261 (match_test "optimize_function_for_size_p (cfun)")
2262 (const_string "V4SF")
2264 (const_string "TI"))
2266 (and (eq_attr "alternative" "14,15")
2267 (not (match_test "TARGET_SSE2")))
2268 (const_string "V2SF")
2269 (eq_attr "alternative" "17")
2272 (const_string "DI")))])
2275 [(set (match_operand:DI 0 "nonimmediate_operand")
2276 (match_operand:DI 1 "general_operand"))]
2277 "!TARGET_64BIT && reload_completed
2278 && !(MMX_REG_P (operands[0])
2279 || SSE_REG_P (operands[0])
2280 || MASK_REG_P (operands[0]))
2281 && !(MMX_REG_P (operands[1])
2282 || SSE_REG_P (operands[1])
2283 || MASK_REG_P (operands[1]))"
2285 "ix86_split_long_move (operands); DONE;")
2287 (define_insn "*movsi_internal"
2288 [(set (match_operand:SI 0 "nonimmediate_operand"
2289 "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k ,*rm")
2290 (match_operand:SI 1 "general_operand"
2291 "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r ,*krm,*k"))]
2292 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2294 switch (get_attr_type (insn))
2297 if (GENERAL_REG_P (operands[0]))
2298 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2300 return standard_sse_constant_opcode (insn, operands[1]);
2303 return "kmovd\t{%1, %0|%0, %1}";
2306 switch (get_attr_mode (insn))
2309 return "%vmovd\t{%1, %0|%0, %1}";
2311 return "%vmovdqa\t{%1, %0|%0, %1}";
2313 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2316 return "%vmovaps\t{%1, %0|%0, %1}";
2319 gcc_assert (!TARGET_AVX);
2320 return "movss\t{%1, %0|%0, %1}";
2327 return "pxor\t%0, %0";
2330 switch (get_attr_mode (insn))
2333 return "movq\t{%1, %0|%0, %1}";
2335 return "movd\t{%1, %0|%0, %1}";
2342 return "lea{l}\t{%E1, %0|%0, %E1}";
2345 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2346 if (ix86_use_lea_for_mov (insn, operands))
2347 return "lea{l}\t{%E1, %0|%0, %E1}";
2349 return "mov{l}\t{%1, %0|%0, %1}";
2356 (if_then_else (eq_attr "alternative" "11")
2357 (const_string "sse4")
2358 (const_string "*")))
2360 (cond [(eq_attr "alternative" "2")
2361 (const_string "mmx")
2362 (eq_attr "alternative" "3,4,5")
2363 (const_string "mmxmov")
2364 (eq_attr "alternative" "6,11")
2365 (const_string "sselog1")
2366 (eq_attr "alternative" "7,8,9,10,12")
2367 (const_string "ssemov")
2368 (eq_attr "alternative" "13,14")
2369 (const_string "mskmov")
2370 (and (match_operand 0 "register_operand")
2371 (match_operand 1 "pic_32bit_operand"))
2372 (const_string "lea")
2374 (const_string "imov")))
2375 (set (attr "length_immediate")
2376 (if_then_else (eq_attr "alternative" "11")
2378 (const_string "*")))
2379 (set (attr "prefix_extra")
2380 (if_then_else (eq_attr "alternative" "11")
2382 (const_string "*")))
2383 (set (attr "prefix")
2384 (if_then_else (eq_attr "type" "sselog1,ssemov")
2385 (const_string "maybe_vex")
2386 (const_string "orig")))
2387 (set (attr "prefix_data16")
2388 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2390 (const_string "*")))
2392 (cond [(eq_attr "alternative" "2,3")
2394 (eq_attr "alternative" "6,7")
2395 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2396 (match_operand 1 "ext_sse_reg_operand"))
2398 (ior (not (match_test "TARGET_SSE2"))
2399 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2400 (const_string "V4SF")
2401 (match_test "TARGET_AVX")
2403 (match_test "optimize_function_for_size_p (cfun)")
2404 (const_string "V4SF")
2406 (const_string "TI"))
2408 (and (eq_attr "alternative" "8,9")
2409 (not (match_test "TARGET_SSE2")))
2411 (eq_attr "alternative" "11")
2414 (const_string "SI")))])
2416 (define_insn "kmovw"
2417 [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2419 [(match_operand:HI 1 "nonimmediate_operand" "rm,k")]
2421 "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2423 kmovw\t{%k1, %0|%0, %k1}
2424 kmovw\t{%1, %0|%0, %1}";
2425 [(set_attr "mode" "HI")
2426 (set_attr "type" "mskmov")
2427 (set_attr "prefix" "vex")])
2430 (define_insn "*movhi_internal"
2431 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k,rm")
2432 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,rm,k,k"))]
2433 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2435 switch (get_attr_type (insn))
2438 /* movzwl is faster than movw on p2 due to partial word stalls,
2439 though not as fast as an aligned movl. */
2440 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2443 switch (which_alternative)
2445 case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2446 case 5: return "kmovw\t{%1, %0|%0, %1}";
2447 case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2448 default: gcc_unreachable ();
2452 if (get_attr_mode (insn) == MODE_SI)
2453 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2455 return "mov{w}\t{%1, %0|%0, %1}";
2459 (cond [(eq_attr "alternative" "4,5,6")
2460 (const_string "mskmov")
2461 (match_test "optimize_function_for_size_p (cfun)")
2462 (const_string "imov")
2463 (and (eq_attr "alternative" "0")
2464 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2465 (not (match_test "TARGET_HIMODE_MATH"))))
2466 (const_string "imov")
2467 (and (eq_attr "alternative" "1,2")
2468 (match_operand:HI 1 "aligned_operand"))
2469 (const_string "imov")
2470 (and (match_test "TARGET_MOVX")
2471 (eq_attr "alternative" "0,2"))
2472 (const_string "imovx")
2474 (const_string "imov")))
2475 (set (attr "prefix")
2476 (if_then_else (eq_attr "alternative" "4,5,6")
2477 (const_string "vex")
2478 (const_string "orig")))
2480 (cond [(eq_attr "type" "imovx")
2482 (and (eq_attr "alternative" "1,2")
2483 (match_operand:HI 1 "aligned_operand"))
2485 (and (eq_attr "alternative" "0")
2486 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2487 (not (match_test "TARGET_HIMODE_MATH"))))
2490 (const_string "HI")))])
2492 ;; Situation is quite tricky about when to choose full sized (SImode) move
2493 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2494 ;; partial register dependency machines (such as AMD Athlon), where QImode
2495 ;; moves issue extra dependency and for partial register stalls machines
2496 ;; that don't use QImode patterns (and QImode move cause stall on the next
2499 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2500 ;; register stall machines with, where we use QImode instructions, since
2501 ;; partial register stall can be caused there. Then we use movzx.
2503 (define_insn "*movqi_internal"
2504 [(set (match_operand:QI 0 "nonimmediate_operand"
2505 "=q,q ,q ,r,r ,?r,m ,k,k,r ,m,k")
2506 (match_operand:QI 1 "general_operand"
2507 "q ,qn,qm,q,rn,qm,qn,r ,k,k,k,m"))]
2508 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2510 switch (get_attr_type (insn))
2513 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2514 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2517 switch (which_alternative)
2519 case 7: return TARGET_AVX512DQ ? "kmovb\t{%k1, %0|%0, %k1}"
2520 : "kmovw\t{%k1, %0|%0, %k1}";
2521 case 8: return TARGET_AVX512DQ ? "kmovb\t{%1, %0|%0, %1}"
2522 : "kmovw\t{%1, %0|%0, %1}";
2523 case 9: return TARGET_AVX512DQ ? "kmovb\t{%1, %k0|%k0, %1}"
2524 : "kmovw\t{%1, %k0|%k0, %1}";
2527 gcc_assert (TARGET_AVX512DQ);
2528 return "kmovb\t{%1, %0|%0, %1}";
2529 default: gcc_unreachable ();
2533 if (get_attr_mode (insn) == MODE_SI)
2534 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2536 return "mov{b}\t{%1, %0|%0, %1}";
2539 [(set_attr "isa" "*,*,*,*,*,*,*,*,*,*,avx512dq,avx512dq")
2541 (cond [(eq_attr "alternative" "7,8,9,10,11")
2542 (const_string "mskmov")
2543 (and (eq_attr "alternative" "5")
2544 (not (match_operand:QI 1 "aligned_operand")))
2545 (const_string "imovx")
2546 (match_test "optimize_function_for_size_p (cfun)")
2547 (const_string "imov")
2548 (and (eq_attr "alternative" "3")
2549 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2550 (not (match_test "TARGET_QIMODE_MATH"))))
2551 (const_string "imov")
2552 (eq_attr "alternative" "3,5")
2553 (const_string "imovx")
2554 (and (match_test "TARGET_MOVX")
2555 (eq_attr "alternative" "2"))
2556 (const_string "imovx")
2558 (const_string "imov")))
2559 (set (attr "prefix")
2560 (if_then_else (eq_attr "alternative" "7,8,9")
2561 (const_string "vex")
2562 (const_string "orig")))
2564 (cond [(eq_attr "alternative" "3,4,5")
2566 (eq_attr "alternative" "6")
2568 (eq_attr "type" "imovx")
2570 (and (eq_attr "type" "imov")
2571 (and (eq_attr "alternative" "0,1")
2572 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2573 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2574 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2576 ;; Avoid partial register stalls when not using QImode arithmetic
2577 (and (eq_attr "type" "imov")
2578 (and (eq_attr "alternative" "0,1")
2579 (and (match_test "TARGET_PARTIAL_REG_STALL")
2580 (not (match_test "TARGET_QIMODE_MATH")))))
2583 (const_string "QI")))])
2585 ;; Stores and loads of ax to arbitrary constant address.
2586 ;; We fake an second form of instruction to force reload to load address
2587 ;; into register when rax is not available
2588 (define_insn "*movabs<mode>_1"
2589 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2590 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2591 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2593 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2594 mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2595 [(set_attr "type" "imov")
2596 (set_attr "modrm" "0,*")
2597 (set_attr "length_address" "8,0")
2598 (set_attr "length_immediate" "0,*")
2599 (set_attr "memory" "store")
2600 (set_attr "mode" "<MODE>")])
2602 (define_insn "*movabs<mode>_2"
2603 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2604 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2605 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2607 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2608 mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2609 [(set_attr "type" "imov")
2610 (set_attr "modrm" "0,*")
2611 (set_attr "length_address" "8,0")
2612 (set_attr "length_immediate" "0")
2613 (set_attr "memory" "load")
2614 (set_attr "mode" "<MODE>")])
2616 (define_insn "*swap<mode>"
2617 [(set (match_operand:SWI48 0 "register_operand" "+r")
2618 (match_operand:SWI48 1 "register_operand" "+r"))
2622 "xchg{<imodesuffix>}\t%1, %0"
2623 [(set_attr "type" "imov")
2624 (set_attr "mode" "<MODE>")
2625 (set_attr "pent_pair" "np")
2626 (set_attr "athlon_decode" "vector")
2627 (set_attr "amdfam10_decode" "double")
2628 (set_attr "bdver1_decode" "double")])
2630 (define_insn "*swap<mode>_1"
2631 [(set (match_operand:SWI12 0 "register_operand" "+r")
2632 (match_operand:SWI12 1 "register_operand" "+r"))
2635 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2637 [(set_attr "type" "imov")
2638 (set_attr "mode" "SI")
2639 (set_attr "pent_pair" "np")
2640 (set_attr "athlon_decode" "vector")
2641 (set_attr "amdfam10_decode" "double")
2642 (set_attr "bdver1_decode" "double")])
2644 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2645 ;; is disabled for AMDFAM10
2646 (define_insn "*swap<mode>_2"
2647 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2648 (match_operand:SWI12 1 "register_operand" "+<r>"))
2651 "TARGET_PARTIAL_REG_STALL"
2652 "xchg{<imodesuffix>}\t%1, %0"
2653 [(set_attr "type" "imov")
2654 (set_attr "mode" "<MODE>")
2655 (set_attr "pent_pair" "np")
2656 (set_attr "athlon_decode" "vector")])
2658 (define_expand "movstrict<mode>"
2659 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2660 (match_operand:SWI12 1 "general_operand"))]
2663 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2665 if (GET_CODE (operands[0]) == SUBREG
2666 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2668 /* Don't generate memory->memory moves, go through a register */
2669 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2670 operands[1] = force_reg (<MODE>mode, operands[1]);
2673 (define_insn "*movstrict<mode>_1"
2674 [(set (strict_low_part
2675 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2676 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2677 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2678 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2679 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2680 [(set_attr "type" "imov")
2681 (set_attr "mode" "<MODE>")])
2683 (define_insn "*movstrict<mode>_xor"
2684 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2685 (match_operand:SWI12 1 "const0_operand"))
2686 (clobber (reg:CC FLAGS_REG))]
2688 "xor{<imodesuffix>}\t%0, %0"
2689 [(set_attr "type" "alu1")
2690 (set_attr "mode" "<MODE>")
2691 (set_attr "length_immediate" "0")])
2693 (define_insn "*mov<mode>_extv_1"
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 "*movqi_extv_1"
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_insn "*mov<mode>_extzv_1"
2731 [(set (match_operand:SWI48 0 "register_operand" "=R")
2732 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2736 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2737 [(set_attr "type" "imovx")
2738 (set_attr "mode" "SI")])
2740 (define_insn "*movqi_extzv_2"
2741 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2743 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2748 switch (get_attr_type (insn))
2751 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2753 return "mov{b}\t{%h1, %0|%0, %h1}";
2756 [(set_attr "isa" "*,*,nox64")
2758 (if_then_else (and (match_operand:QI 0 "register_operand")
2759 (ior (not (match_operand:QI 0 "QIreg_operand"))
2760 (match_test "TARGET_MOVX")))
2761 (const_string "imovx")
2762 (const_string "imov")))
2764 (if_then_else (eq_attr "type" "imovx")
2766 (const_string "QI")))])
2768 (define_insn "mov<mode>_insv_1"
2769 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2772 (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2775 if (CONST_INT_P (operands[1]))
2776 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2777 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2779 [(set_attr "isa" "*,nox64")
2780 (set_attr "type" "imov")
2781 (set_attr "mode" "QI")])
2783 (define_insn "*movqi_insv_2"
2784 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2787 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2790 "mov{b}\t{%h1, %h0|%h0, %h1}"
2791 [(set_attr "type" "imov")
2792 (set_attr "mode" "QI")])
2794 ;; Floating point push instructions.
2796 (define_insn "*pushtf"
2797 [(set (match_operand:TF 0 "push_operand" "=<,<")
2798 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2799 "TARGET_64BIT || TARGET_SSE"
2801 /* This insn should be already split before reg-stack. */
2804 [(set_attr "isa" "*,x64")
2805 (set_attr "type" "multi")
2806 (set_attr "unit" "sse,*")
2807 (set_attr "mode" "TF,DI")])
2809 ;; %%% Kill this when call knows how to work this out.
2811 [(set (match_operand:TF 0 "push_operand")
2812 (match_operand:TF 1 "sse_reg_operand"))]
2813 "TARGET_SSE && reload_completed"
2814 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2815 (set (match_dup 0) (match_dup 1))]
2817 /* Preserve memory attributes. */
2818 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2821 (define_insn "*pushxf"
2822 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<")
2823 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF"))]
2826 /* This insn should be already split before reg-stack. */
2829 [(set_attr "type" "multi")
2830 (set_attr "unit" "i387,*,*,*")
2832 (cond [(eq_attr "alternative" "1,2,3")
2833 (if_then_else (match_test "TARGET_64BIT")
2835 (const_string "SI"))
2837 (const_string "XF")))
2838 (set (attr "preferred_for_size")
2839 (cond [(eq_attr "alternative" "1")
2840 (symbol_ref "false")]
2841 (symbol_ref "true")))])
2843 ;; %%% Kill this when call knows how to work this out.
2845 [(set (match_operand:XF 0 "push_operand")
2846 (match_operand:XF 1 "fp_register_operand"))]
2848 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2849 (set (match_dup 0) (match_dup 1))]
2851 operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2852 /* Preserve memory attributes. */
2853 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2856 (define_insn "*pushdf"
2857 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
2858 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmF,x"))]
2861 /* This insn should be already split before reg-stack. */
2864 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
2865 (set_attr "type" "multi")
2866 (set_attr "unit" "i387,*,*,*,*,sse")
2867 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
2868 (set (attr "preferred_for_size")
2869 (cond [(eq_attr "alternative" "1")
2870 (symbol_ref "false")]
2871 (symbol_ref "true")))
2872 (set (attr "preferred_for_speed")
2873 (cond [(eq_attr "alternative" "1")
2874 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
2875 (symbol_ref "true")))])
2877 ;; %%% Kill this when call knows how to work this out.
2879 [(set (match_operand:DF 0 "push_operand")
2880 (match_operand:DF 1 "any_fp_register_operand"))]
2882 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2883 (set (match_dup 0) (match_dup 1))]
2885 /* Preserve memory attributes. */
2886 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2889 (define_insn "*pushsf_rex64"
2890 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2891 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2894 /* Anything else should be already split before reg-stack. */
2895 gcc_assert (which_alternative == 1);
2896 return "push{q}\t%q1";
2898 [(set_attr "type" "multi,push,multi")
2899 (set_attr "unit" "i387,*,*")
2900 (set_attr "mode" "SF,DI,SF")])
2902 (define_insn "*pushsf"
2903 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2904 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2907 /* Anything else should be already split before reg-stack. */
2908 gcc_assert (which_alternative == 1);
2909 return "push{l}\t%1";
2911 [(set_attr "type" "multi,push,multi")
2912 (set_attr "unit" "i387,*,*")
2913 (set_attr "mode" "SF,SI,SF")])
2915 ;; %%% Kill this when call knows how to work this out.
2917 [(set (match_operand:SF 0 "push_operand")
2918 (match_operand:SF 1 "any_fp_register_operand"))]
2920 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2921 (set (match_dup 0) (match_dup 1))]
2923 rtx op = XEXP (operands[0], 0);
2924 if (GET_CODE (op) == PRE_DEC)
2926 gcc_assert (!TARGET_64BIT);
2931 op = XEXP (XEXP (op, 1), 1);
2932 gcc_assert (CONST_INT_P (op));
2935 /* Preserve memory attributes. */
2936 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2940 [(set (match_operand:SF 0 "push_operand")
2941 (match_operand:SF 1 "memory_operand"))]
2943 && (operands[2] = find_constant_src (insn))"
2944 [(set (match_dup 0) (match_dup 2))])
2947 [(set (match_operand 0 "push_operand")
2948 (match_operand 1 "general_operand"))]
2950 && (GET_MODE (operands[0]) == TFmode
2951 || GET_MODE (operands[0]) == XFmode
2952 || GET_MODE (operands[0]) == DFmode)
2953 && !ANY_FP_REG_P (operands[1])"
2955 "ix86_split_long_move (operands); DONE;")
2957 ;; Floating point move instructions.
2959 (define_expand "movtf"
2960 [(set (match_operand:TF 0 "nonimmediate_operand")
2961 (match_operand:TF 1 "nonimmediate_operand"))]
2962 "TARGET_64BIT || TARGET_SSE"
2963 "ix86_expand_move (TFmode, operands); DONE;")
2965 (define_expand "mov<mode>"
2966 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2967 (match_operand:X87MODEF 1 "general_operand"))]
2969 "ix86_expand_move (<MODE>mode, operands); DONE;")
2971 (define_insn "*movtf_internal"
2972 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2973 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
2974 "(TARGET_64BIT || TARGET_SSE)
2975 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2976 && (!can_create_pseudo_p ()
2977 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2978 || GET_CODE (operands[1]) != CONST_DOUBLE
2979 || (optimize_function_for_size_p (cfun)
2980 && standard_sse_constant_p (operands[1])
2981 && !memory_operand (operands[0], TFmode))
2982 || (!TARGET_MEMORY_MISMATCH_STALL
2983 && memory_operand (operands[0], TFmode)))"
2985 switch (get_attr_type (insn))
2988 return standard_sse_constant_opcode (insn, operands[1]);
2991 /* Handle misaligned load/store since we
2992 don't have movmisaligntf pattern. */
2993 if (misaligned_operand (operands[0], TFmode)
2994 || misaligned_operand (operands[1], TFmode))
2996 if (get_attr_mode (insn) == MODE_V4SF)
2997 return "%vmovups\t{%1, %0|%0, %1}";
2999 return "%vmovdqu\t{%1, %0|%0, %1}";
3003 if (get_attr_mode (insn) == MODE_V4SF)
3004 return "%vmovaps\t{%1, %0|%0, %1}";
3006 return "%vmovdqa\t{%1, %0|%0, %1}";
3016 [(set_attr "isa" "*,*,*,x64,x64")
3017 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3018 (set (attr "prefix")
3019 (if_then_else (eq_attr "type" "sselog1,ssemov")
3020 (const_string "maybe_vex")
3021 (const_string "orig")))
3023 (cond [(eq_attr "alternative" "3,4")
3025 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3026 (const_string "V4SF")
3027 (and (eq_attr "alternative" "2")
3028 (match_test "TARGET_SSE_TYPELESS_STORES"))
3029 (const_string "V4SF")
3030 (match_test "TARGET_AVX")
3032 (ior (not (match_test "TARGET_SSE2"))
3033 (match_test "optimize_function_for_size_p (cfun)"))
3034 (const_string "V4SF")
3036 (const_string "TI")))])
3038 ;; Possible store forwarding (partial memory) stall
3039 ;; in alternatives 4, 6, 7 and 8.
3040 (define_insn "*movxf_internal"
3041 [(set (match_operand:XF 0 "nonimmediate_operand"
3042 "=f,m,f,?r ,!o,?*r ,!o,!o,!o")
3043 (match_operand:XF 1 "general_operand"
3044 "fm,f,G,roF,r , *roF,*r,F ,C"))]
3045 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3046 && (!can_create_pseudo_p ()
3047 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3048 || GET_CODE (operands[1]) != CONST_DOUBLE
3049 || (optimize_function_for_size_p (cfun)
3050 && standard_80387_constant_p (operands[1]) > 0
3051 && !memory_operand (operands[0], XFmode))
3052 || (!TARGET_MEMORY_MISMATCH_STALL
3053 && memory_operand (operands[0], XFmode)))"
3055 switch (get_attr_type (insn))
3058 if (which_alternative == 2)
3059 return standard_80387_constant_opcode (operands[1]);
3060 return output_387_reg_move (insn, operands);
3070 (cond [(eq_attr "alternative" "7")
3071 (const_string "nox64")
3072 (eq_attr "alternative" "8")
3073 (const_string "x64")
3075 (const_string "*")))
3077 (cond [(eq_attr "alternative" "3,4,5,6,7,8")
3078 (const_string "multi")
3080 (const_string "fmov")))
3082 (cond [(eq_attr "alternative" "3,4,5,6,7,8")
3083 (if_then_else (match_test "TARGET_64BIT")
3085 (const_string "SI"))
3087 (const_string "XF")))
3088 (set (attr "preferred_for_size")
3089 (cond [(eq_attr "alternative" "3,4")
3090 (symbol_ref "false")]
3091 (symbol_ref "true")))])
3093 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3094 (define_insn "*movdf_internal"
3095 [(set (match_operand:DF 0 "nonimmediate_operand"
3096 "=Yf*f,m ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
3097 (match_operand:DF 1 "general_operand"
3098 "Yf*fm,Yf*f,G ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
3099 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3100 && (!can_create_pseudo_p ()
3101 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3102 || GET_CODE (operands[1]) != CONST_DOUBLE
3103 || (optimize_function_for_size_p (cfun)
3104 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3105 && standard_80387_constant_p (operands[1]) > 0)
3106 || (TARGET_SSE2 && TARGET_SSE_MATH
3107 && standard_sse_constant_p (operands[1])))
3108 && !memory_operand (operands[0], DFmode))
3109 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3110 && memory_operand (operands[0], DFmode)))"
3112 switch (get_attr_type (insn))
3115 if (which_alternative == 2)
3116 return standard_80387_constant_opcode (operands[1]);
3117 return output_387_reg_move (insn, operands);
3123 if (get_attr_mode (insn) == MODE_SI)
3124 return "mov{l}\t{%1, %k0|%k0, %1}";
3125 else if (which_alternative == 11)
3126 return "movabs{q}\t{%1, %0|%0, %1}";
3128 return "mov{q}\t{%1, %0|%0, %1}";
3131 return standard_sse_constant_opcode (insn, operands[1]);
3134 switch (get_attr_mode (insn))
3137 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3138 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3139 return "%vmovsd\t{%1, %0|%0, %1}";
3142 return "%vmovaps\t{%1, %0|%0, %1}";
3144 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3146 return "%vmovapd\t{%1, %0|%0, %1}";
3149 gcc_assert (!TARGET_AVX);
3150 return "movlps\t{%1, %0|%0, %1}";
3152 gcc_assert (!TARGET_AVX);
3153 return "movlpd\t{%1, %0|%0, %1}";
3156 /* Handle broken assemblers that require movd instead of movq. */
3157 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3158 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3159 return "%vmovd\t{%1, %0|%0, %1}";
3160 return "%vmovq\t{%1, %0|%0, %1}";
3171 (cond [(eq_attr "alternative" "3,4,5,6,7")
3172 (const_string "nox64")
3173 (eq_attr "alternative" "8,9,10,11,20,21")
3174 (const_string "x64")
3175 (eq_attr "alternative" "12,13,14,15")
3176 (const_string "sse2")
3178 (const_string "*")))
3180 (cond [(eq_attr "alternative" "0,1,2")
3181 (const_string "fmov")
3182 (eq_attr "alternative" "3,4,5,6,7")
3183 (const_string "multi")
3184 (eq_attr "alternative" "8,9,10,11")
3185 (const_string "imov")
3186 (eq_attr "alternative" "12,16")
3187 (const_string "sselog1")
3189 (const_string "ssemov")))
3191 (if_then_else (eq_attr "alternative" "11")
3193 (const_string "*")))
3194 (set (attr "length_immediate")
3195 (if_then_else (eq_attr "alternative" "11")
3197 (const_string "*")))
3198 (set (attr "prefix")
3199 (if_then_else (eq_attr "type" "sselog1,ssemov")
3200 (const_string "maybe_vex")
3201 (const_string "orig")))
3202 (set (attr "prefix_data16")
3204 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3205 (eq_attr "mode" "V1DF"))
3207 (const_string "*")))
3209 (cond [(eq_attr "alternative" "3,4,5,6,7,10")
3211 (eq_attr "alternative" "8,9,11,20,21")
3214 /* xorps is one byte shorter for non-AVX targets. */
3215 (eq_attr "alternative" "12,16")
3216 (cond [(not (match_test "TARGET_SSE2"))
3217 (const_string "V4SF")
3218 (match_test "TARGET_AVX512F")
3220 (match_test "TARGET_AVX")
3221 (const_string "V2DF")
3222 (match_test "optimize_function_for_size_p (cfun)")
3223 (const_string "V4SF")
3224 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3227 (const_string "V2DF"))
3229 /* For architectures resolving dependencies on
3230 whole SSE registers use movapd to break dependency
3231 chains, otherwise use short move to avoid extra work. */
3233 /* movaps is one byte shorter for non-AVX targets. */
3234 (eq_attr "alternative" "13,17")
3235 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3236 (match_operand 1 "ext_sse_reg_operand"))
3237 (const_string "V8DF")
3238 (ior (not (match_test "TARGET_SSE2"))
3239 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3240 (const_string "V4SF")
3241 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3242 (const_string "V2DF")
3243 (match_test "TARGET_AVX")
3245 (match_test "optimize_function_for_size_p (cfun)")
3246 (const_string "V4SF")
3248 (const_string "DF"))
3250 /* For architectures resolving dependencies on register
3251 parts we may avoid extra work to zero out upper part
3253 (eq_attr "alternative" "14,18")
3254 (cond [(not (match_test "TARGET_SSE2"))
3255 (const_string "V2SF")
3256 (match_test "TARGET_AVX")
3258 (match_test "TARGET_SSE_SPLIT_REGS")
3259 (const_string "V1DF")
3261 (const_string "DF"))
3263 (and (eq_attr "alternative" "15,19")
3264 (not (match_test "TARGET_SSE2")))
3265 (const_string "V2SF")
3267 (const_string "DF")))
3268 (set (attr "preferred_for_size")
3269 (cond [(eq_attr "alternative" "3,4")
3270 (symbol_ref "false")]
3271 (symbol_ref "true")))
3272 (set (attr "preferred_for_speed")
3273 (cond [(eq_attr "alternative" "3,4")
3274 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3275 (symbol_ref "true")))])
3277 (define_insn "*movsf_internal"
3278 [(set (match_operand:SF 0 "nonimmediate_operand"
3279 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3280 (match_operand:SF 1 "general_operand"
3281 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r"))]
3282 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3283 && (!can_create_pseudo_p ()
3284 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3285 || GET_CODE (operands[1]) != CONST_DOUBLE
3286 || (optimize_function_for_size_p (cfun)
3287 && ((!TARGET_SSE_MATH
3288 && standard_80387_constant_p (operands[1]) > 0)
3290 && standard_sse_constant_p (operands[1]))))
3291 || memory_operand (operands[0], SFmode))"
3293 switch (get_attr_type (insn))
3296 if (which_alternative == 2)
3297 return standard_80387_constant_opcode (operands[1]);
3298 return output_387_reg_move (insn, operands);
3301 return "mov{l}\t{%1, %0|%0, %1}";
3304 return standard_sse_constant_opcode (insn, operands[1]);
3307 switch (get_attr_mode (insn))
3310 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3311 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3312 return "%vmovss\t{%1, %0|%0, %1}";
3315 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3317 return "%vmovaps\t{%1, %0|%0, %1}";
3320 return "%vmovd\t{%1, %0|%0, %1}";
3327 switch (get_attr_mode (insn))
3330 return "movq\t{%1, %0|%0, %1}";
3332 return "movd\t{%1, %0|%0, %1}";
3343 (cond [(eq_attr "alternative" "0,1,2")
3344 (const_string "fmov")
3345 (eq_attr "alternative" "3,4")
3346 (const_string "imov")
3347 (eq_attr "alternative" "5")
3348 (const_string "sselog1")
3349 (eq_attr "alternative" "11,12,13,14,15")
3350 (const_string "mmxmov")
3352 (const_string "ssemov")))
3353 (set (attr "prefix")
3354 (if_then_else (eq_attr "type" "sselog1,ssemov")
3355 (const_string "maybe_vex")
3356 (const_string "orig")))
3357 (set (attr "prefix_data16")
3358 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3360 (const_string "*")))
3362 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15")
3364 (eq_attr "alternative" "11")
3366 (eq_attr "alternative" "5")
3367 (cond [(not (match_test "TARGET_SSE2"))
3368 (const_string "V4SF")
3369 (match_test "TARGET_AVX512F")
3370 (const_string "V16SF")
3371 (match_test "TARGET_AVX")
3372 (const_string "V4SF")
3373 (match_test "optimize_function_for_size_p (cfun)")
3374 (const_string "V4SF")
3375 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3378 (const_string "V4SF"))
3380 /* For architectures resolving dependencies on
3381 whole SSE registers use APS move to break dependency
3382 chains, otherwise use short move to avoid extra work.
3384 Do the same for architectures resolving dependencies on
3385 the parts. While in DF mode it is better to always handle
3386 just register parts, the SF mode is different due to lack
3387 of instructions to load just part of the register. It is
3388 better to maintain the whole registers in single format
3389 to avoid problems on using packed logical operations. */
3390 (eq_attr "alternative" "6")
3391 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3392 (match_operand 1 "ext_sse_reg_operand"))
3393 (const_string "V16SF")
3394 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3395 (match_test "TARGET_SSE_SPLIT_REGS"))
3396 (const_string "V4SF")
3398 (const_string "SF"))
3400 (const_string "SF")))])
3403 [(set (match_operand 0 "any_fp_register_operand")
3404 (match_operand 1 "memory_operand"))]
3406 && (GET_MODE (operands[0]) == TFmode
3407 || GET_MODE (operands[0]) == XFmode
3408 || GET_MODE (operands[0]) == DFmode
3409 || GET_MODE (operands[0]) == SFmode)
3410 && (operands[2] = find_constant_src (insn))"
3411 [(set (match_dup 0) (match_dup 2))]
3413 rtx c = operands[2];
3414 int r = REGNO (operands[0]);
3416 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3417 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3422 [(set (match_operand 0 "any_fp_register_operand")
3423 (float_extend (match_operand 1 "memory_operand")))]
3425 && (GET_MODE (operands[0]) == TFmode
3426 || GET_MODE (operands[0]) == XFmode
3427 || GET_MODE (operands[0]) == DFmode)
3428 && (operands[2] = find_constant_src (insn))"
3429 [(set (match_dup 0) (match_dup 2))]
3431 rtx c = operands[2];
3432 int r = REGNO (operands[0]);
3434 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3435 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3439 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3441 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3442 (match_operand:X87MODEF 1 "immediate_operand"))]
3444 && (standard_80387_constant_p (operands[1]) == 8
3445 || standard_80387_constant_p (operands[1]) == 9)"
3446 [(set (match_dup 0)(match_dup 1))
3448 (neg:X87MODEF (match_dup 0)))]
3452 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3453 if (real_isnegzero (&r))
3454 operands[1] = CONST0_RTX (<MODE>mode);
3456 operands[1] = CONST1_RTX (<MODE>mode);
3460 [(set (match_operand 0 "nonimmediate_operand")
3461 (match_operand 1 "general_operand"))]
3463 && (GET_MODE (operands[0]) == TFmode
3464 || GET_MODE (operands[0]) == XFmode
3465 || GET_MODE (operands[0]) == DFmode)
3466 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3468 "ix86_split_long_move (operands); DONE;")
3470 (define_insn "swapxf"
3471 [(set (match_operand:XF 0 "register_operand" "+f")
3472 (match_operand:XF 1 "register_operand" "+f"))
3477 if (STACK_TOP_P (operands[0]))
3482 [(set_attr "type" "fxch")
3483 (set_attr "mode" "XF")])
3485 (define_insn "*swap<mode>"
3486 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3487 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3490 "TARGET_80387 || reload_completed"
3492 if (STACK_TOP_P (operands[0]))
3497 [(set_attr "type" "fxch")
3498 (set_attr "mode" "<MODE>")])
3500 ;; Zero extension instructions
3502 (define_expand "zero_extendsidi2"
3503 [(set (match_operand:DI 0 "nonimmediate_operand")
3504 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3506 (define_insn "*zero_extendsidi2"
3507 [(set (match_operand:DI 0 "nonimmediate_operand"
3508 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3510 (match_operand:SI 1 "x86_64_zext_operand"
3511 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))]
3514 switch (get_attr_type (insn))
3517 if (ix86_use_lea_for_mov (insn, operands))
3518 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3520 return "mov{l}\t{%1, %k0|%k0, %1}";
3526 return "movd\t{%1, %0|%0, %1}";
3529 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3532 if (GENERAL_REG_P (operands[0]))
3533 return "%vmovd\t{%1, %k0|%k0, %1}";
3535 return "%vmovd\t{%1, %0|%0, %1}";
3542 (cond [(eq_attr "alternative" "0,1,2")
3543 (const_string "nox64")
3544 (eq_attr "alternative" "3,7")
3545 (const_string "x64")
3546 (eq_attr "alternative" "8")
3547 (const_string "x64_sse4")
3548 (eq_attr "alternative" "10")
3549 (const_string "sse2")
3551 (const_string "*")))
3553 (cond [(eq_attr "alternative" "0,1,2,4")
3554 (const_string "multi")
3555 (eq_attr "alternative" "5,6")
3556 (const_string "mmxmov")
3557 (eq_attr "alternative" "7,9,10")
3558 (const_string "ssemov")
3559 (eq_attr "alternative" "8")
3560 (const_string "sselog1")
3562 (const_string "imovx")))
3563 (set (attr "prefix_extra")
3564 (if_then_else (eq_attr "alternative" "8")
3566 (const_string "*")))
3567 (set (attr "length_immediate")
3568 (if_then_else (eq_attr "alternative" "8")
3570 (const_string "*")))
3571 (set (attr "prefix")
3572 (if_then_else (eq_attr "type" "ssemov,sselog1")
3573 (const_string "maybe_vex")
3574 (const_string "orig")))
3575 (set (attr "prefix_0f")
3576 (if_then_else (eq_attr "type" "imovx")
3578 (const_string "*")))
3580 (cond [(eq_attr "alternative" "5,6")
3582 (eq_attr "alternative" "7,8,9")
3585 (const_string "SI")))])
3588 [(set (match_operand:DI 0 "memory_operand")
3589 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3591 [(set (match_dup 4) (const_int 0))]
3592 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3595 [(set (match_operand:DI 0 "register_operand")
3596 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3597 "!TARGET_64BIT && reload_completed
3598 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3599 && true_regnum (operands[0]) == true_regnum (operands[1])"
3600 [(set (match_dup 4) (const_int 0))]
3601 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3604 [(set (match_operand:DI 0 "nonimmediate_operand")
3605 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3606 "!TARGET_64BIT && reload_completed
3607 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3608 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3609 [(set (match_dup 3) (match_dup 1))
3610 (set (match_dup 4) (const_int 0))]
3611 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3613 (define_insn "zero_extend<mode>di2"
3614 [(set (match_operand:DI 0 "register_operand" "=r")
3616 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3618 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3619 [(set_attr "type" "imovx")
3620 (set_attr "mode" "SI")])
3622 (define_expand "zero_extend<mode>si2"
3623 [(set (match_operand:SI 0 "register_operand")
3624 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3627 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3629 operands[1] = force_reg (<MODE>mode, operands[1]);
3630 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3635 (define_insn_and_split "zero_extend<mode>si2_and"
3636 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3638 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3639 (clobber (reg:CC FLAGS_REG))]
3640 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3642 "&& reload_completed"
3643 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3644 (clobber (reg:CC FLAGS_REG))])]
3646 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3648 ix86_expand_clear (operands[0]);
3650 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3651 emit_insn (gen_movstrict<mode>
3652 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3656 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3658 [(set_attr "type" "alu1")
3659 (set_attr "mode" "SI")])
3661 (define_insn "*zero_extend<mode>si2"
3662 [(set (match_operand:SI 0 "register_operand" "=r")
3664 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3665 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3666 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3667 [(set_attr "type" "imovx")
3668 (set_attr "mode" "SI")])
3670 (define_expand "zero_extendqihi2"
3671 [(set (match_operand:HI 0 "register_operand")
3672 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3675 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3677 operands[1] = force_reg (QImode, operands[1]);
3678 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3683 (define_insn_and_split "zero_extendqihi2_and"
3684 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3685 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3686 (clobber (reg:CC FLAGS_REG))]
3687 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3689 "&& reload_completed"
3690 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3691 (clobber (reg:CC FLAGS_REG))])]
3693 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3695 ix86_expand_clear (operands[0]);
3697 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3698 emit_insn (gen_movstrictqi
3699 (gen_lowpart (QImode, operands[0]), operands[1]));
3703 operands[0] = gen_lowpart (SImode, operands[0]);
3705 [(set_attr "type" "alu1")
3706 (set_attr "mode" "SI")])
3708 ; zero extend to SImode to avoid partial register stalls
3709 (define_insn "*zero_extendqihi2"
3710 [(set (match_operand:HI 0 "register_operand" "=r")
3711 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3712 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3713 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3714 [(set_attr "type" "imovx")
3715 (set_attr "mode" "SI")])
3717 ;; Sign extension instructions
3719 (define_expand "extendsidi2"
3720 [(set (match_operand:DI 0 "register_operand")
3721 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3726 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3731 (define_insn "*extendsidi2_rex64"
3732 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3733 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3737 movs{lq|x}\t{%1, %0|%0, %1}"
3738 [(set_attr "type" "imovx")
3739 (set_attr "mode" "DI")
3740 (set_attr "prefix_0f" "0")
3741 (set_attr "modrm" "0,1")])
3743 (define_insn "extendsidi2_1"
3744 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3745 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3746 (clobber (reg:CC FLAGS_REG))
3747 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3751 ;; Split the memory case. If the source register doesn't die, it will stay
3752 ;; this way, if it does die, following peephole2s take care of it.
3754 [(set (match_operand:DI 0 "memory_operand")
3755 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3756 (clobber (reg:CC FLAGS_REG))
3757 (clobber (match_operand:SI 2 "register_operand"))]
3761 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3763 emit_move_insn (operands[3], operands[1]);
3765 /* Generate a cltd if possible and doing so it profitable. */
3766 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3767 && true_regnum (operands[1]) == AX_REG
3768 && true_regnum (operands[2]) == DX_REG)
3770 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3774 emit_move_insn (operands[2], operands[1]);
3775 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3777 emit_move_insn (operands[4], operands[2]);
3781 ;; Peepholes for the case where the source register does die, after
3782 ;; being split with the above splitter.
3784 [(set (match_operand:SI 0 "memory_operand")
3785 (match_operand:SI 1 "register_operand"))
3786 (set (match_operand:SI 2 "register_operand") (match_dup 1))
3787 (parallel [(set (match_dup 2)
3788 (ashiftrt:SI (match_dup 2) (const_int 31)))
3789 (clobber (reg:CC FLAGS_REG))])
3790 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3791 "REGNO (operands[1]) != REGNO (operands[2])
3792 && peep2_reg_dead_p (2, operands[1])
3793 && peep2_reg_dead_p (4, operands[2])
3794 && !reg_mentioned_p (operands[2], operands[3])"
3795 [(set (match_dup 0) (match_dup 1))
3796 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3797 (clobber (reg:CC FLAGS_REG))])
3798 (set (match_dup 3) (match_dup 1))])
3801 [(set (match_operand:SI 0 "memory_operand")
3802 (match_operand:SI 1 "register_operand"))
3803 (parallel [(set (match_operand:SI 2 "register_operand")
3804 (ashiftrt:SI (match_dup 1) (const_int 31)))
3805 (clobber (reg:CC FLAGS_REG))])
3806 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3807 "/* cltd is shorter than sarl $31, %eax */
3808 !optimize_function_for_size_p (cfun)
3809 && true_regnum (operands[1]) == AX_REG
3810 && true_regnum (operands[2]) == DX_REG
3811 && peep2_reg_dead_p (2, operands[1])
3812 && peep2_reg_dead_p (3, operands[2])
3813 && !reg_mentioned_p (operands[2], operands[3])"
3814 [(set (match_dup 0) (match_dup 1))
3815 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3816 (clobber (reg:CC FLAGS_REG))])
3817 (set (match_dup 3) (match_dup 1))])
3819 ;; Extend to register case. Optimize case where source and destination
3820 ;; registers match and cases where we can use cltd.
3822 [(set (match_operand:DI 0 "register_operand")
3823 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3824 (clobber (reg:CC FLAGS_REG))
3825 (clobber (match_scratch:SI 2))]
3829 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3831 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3832 emit_move_insn (operands[3], operands[1]);
3834 /* Generate a cltd if possible and doing so it profitable. */
3835 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3836 && true_regnum (operands[3]) == AX_REG
3837 && true_regnum (operands[4]) == DX_REG)
3839 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3843 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3844 emit_move_insn (operands[4], operands[1]);
3846 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3850 (define_insn "extend<mode>di2"
3851 [(set (match_operand:DI 0 "register_operand" "=r")
3853 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3855 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3856 [(set_attr "type" "imovx")
3857 (set_attr "mode" "DI")])
3859 (define_insn "extendhisi2"
3860 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3861 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3864 switch (get_attr_prefix_0f (insn))
3867 return "{cwtl|cwde}";
3869 return "movs{wl|x}\t{%1, %0|%0, %1}";
3872 [(set_attr "type" "imovx")
3873 (set_attr "mode" "SI")
3874 (set (attr "prefix_0f")
3875 ;; movsx is short decodable while cwtl is vector decoded.
3876 (if_then_else (and (eq_attr "cpu" "!k6")
3877 (eq_attr "alternative" "0"))
3879 (const_string "1")))
3881 (if_then_else (eq_attr "prefix_0f" "0")
3883 (const_string "1")))])
3885 (define_insn "*extendhisi2_zext"
3886 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3889 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3892 switch (get_attr_prefix_0f (insn))
3895 return "{cwtl|cwde}";
3897 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3900 [(set_attr "type" "imovx")
3901 (set_attr "mode" "SI")
3902 (set (attr "prefix_0f")
3903 ;; movsx is short decodable while cwtl is vector decoded.
3904 (if_then_else (and (eq_attr "cpu" "!k6")
3905 (eq_attr "alternative" "0"))
3907 (const_string "1")))
3909 (if_then_else (eq_attr "prefix_0f" "0")
3911 (const_string "1")))])
3913 (define_insn "extendqisi2"
3914 [(set (match_operand:SI 0 "register_operand" "=r")
3915 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3917 "movs{bl|x}\t{%1, %0|%0, %1}"
3918 [(set_attr "type" "imovx")
3919 (set_attr "mode" "SI")])
3921 (define_insn "*extendqisi2_zext"
3922 [(set (match_operand:DI 0 "register_operand" "=r")
3924 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3926 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3927 [(set_attr "type" "imovx")
3928 (set_attr "mode" "SI")])
3930 (define_insn "extendqihi2"
3931 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3932 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3935 switch (get_attr_prefix_0f (insn))
3938 return "{cbtw|cbw}";
3940 return "movs{bw|x}\t{%1, %0|%0, %1}";
3943 [(set_attr "type" "imovx")
3944 (set_attr "mode" "HI")
3945 (set (attr "prefix_0f")
3946 ;; movsx is short decodable while cwtl is vector decoded.
3947 (if_then_else (and (eq_attr "cpu" "!k6")
3948 (eq_attr "alternative" "0"))
3950 (const_string "1")))
3952 (if_then_else (eq_attr "prefix_0f" "0")
3954 (const_string "1")))])
3956 ;; Conversions between float and double.
3958 ;; These are all no-ops in the model used for the 80387.
3959 ;; So just emit moves.
3961 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3963 [(set (match_operand:DF 0 "push_operand")
3964 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3966 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3967 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3970 [(set (match_operand:XF 0 "push_operand")
3971 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3973 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3974 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3975 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3977 (define_expand "extendsfdf2"
3978 [(set (match_operand:DF 0 "nonimmediate_operand")
3979 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3980 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3982 /* ??? Needed for compress_float_constant since all fp constants
3983 are TARGET_LEGITIMATE_CONSTANT_P. */
3984 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3986 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3987 && standard_80387_constant_p (operands[1]) > 0)
3989 operands[1] = simplify_const_unary_operation
3990 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3991 emit_move_insn_1 (operands[0], operands[1]);
3994 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3998 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4000 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4002 We do the conversion post reload to avoid producing of 128bit spills
4003 that might lead to ICE on 32bit target. The sequence unlikely combine
4006 [(set (match_operand:DF 0 "register_operand")
4008 (match_operand:SF 1 "nonimmediate_operand")))]
4009 "TARGET_USE_VECTOR_FP_CONVERTS
4010 && optimize_insn_for_speed_p ()
4011 && reload_completed && SSE_REG_P (operands[0])"
4016 (parallel [(const_int 0) (const_int 1)]))))]
4018 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4019 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4020 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4021 Try to avoid move when unpacking can be done in source. */
4022 if (REG_P (operands[1]))
4024 /* If it is unsafe to overwrite upper half of source, we need
4025 to move to destination and unpack there. */
4026 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4027 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4028 && true_regnum (operands[0]) != true_regnum (operands[1]))
4030 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4031 emit_move_insn (tmp, operands[1]);
4034 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4035 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4039 emit_insn (gen_vec_setv4sf_0 (operands[3],
4040 CONST0_RTX (V4SFmode), operands[1]));
4043 ;; It's more profitable to split and then extend in the same register.
4045 [(set (match_operand:DF 0 "register_operand")
4047 (match_operand:SF 1 "memory_operand")))]
4048 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4049 && optimize_insn_for_speed_p ()
4050 && SSE_REG_P (operands[0])"
4051 [(set (match_dup 2) (match_dup 1))
4052 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4053 "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
4055 (define_insn "*extendsfdf2_mixed"
4056 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4058 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4059 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4061 switch (which_alternative)
4065 return output_387_reg_move (insn, operands);
4068 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4074 [(set_attr "type" "fmov,fmov,ssecvt")
4075 (set_attr "prefix" "orig,orig,maybe_vex")
4076 (set_attr "mode" "SF,XF,DF")])
4078 (define_insn "*extendsfdf2_sse"
4079 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4080 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4081 "TARGET_SSE2 && TARGET_SSE_MATH"
4082 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4083 [(set_attr "type" "ssecvt")
4084 (set_attr "prefix" "maybe_vex")
4085 (set_attr "mode" "DF")])
4087 (define_insn "*extendsfdf2_i387"
4088 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4089 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4091 "* return output_387_reg_move (insn, operands);"
4092 [(set_attr "type" "fmov")
4093 (set_attr "mode" "SF,XF")])
4095 (define_expand "extend<mode>xf2"
4096 [(set (match_operand:XF 0 "nonimmediate_operand")
4097 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4100 /* ??? Needed for compress_float_constant since all fp constants
4101 are TARGET_LEGITIMATE_CONSTANT_P. */
4102 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4104 if (standard_80387_constant_p (operands[1]) > 0)
4106 operands[1] = simplify_const_unary_operation
4107 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4108 emit_move_insn_1 (operands[0], operands[1]);
4111 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4115 (define_insn "*extend<mode>xf2_i387"
4116 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4118 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4120 "* return output_387_reg_move (insn, operands);"
4121 [(set_attr "type" "fmov")
4122 (set_attr "mode" "<MODE>,XF")])
4124 ;; %%% This seems bad bad news.
4125 ;; This cannot output into an f-reg because there is no way to be sure
4126 ;; of truncating in that case. Otherwise this is just like a simple move
4127 ;; insn. So we pretend we can output to a reg in order to get better
4128 ;; register preferencing, but we really use a stack slot.
4130 ;; Conversion from DFmode to SFmode.
4132 (define_expand "truncdfsf2"
4133 [(set (match_operand:SF 0 "nonimmediate_operand")
4135 (match_operand:DF 1 "nonimmediate_operand")))]
4136 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4138 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4140 else if (flag_unsafe_math_optimizations)
4144 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4145 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4150 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4152 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4154 We do the conversion post reload to avoid producing of 128bit spills
4155 that might lead to ICE on 32bit target. The sequence unlikely combine
4158 [(set (match_operand:SF 0 "register_operand")
4160 (match_operand:DF 1 "nonimmediate_operand")))]
4161 "TARGET_USE_VECTOR_FP_CONVERTS
4162 && optimize_insn_for_speed_p ()
4163 && reload_completed && SSE_REG_P (operands[0])"
4166 (float_truncate:V2SF
4170 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4171 operands[3] = CONST0_RTX (V2SFmode);
4172 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4173 /* Use movsd for loading from memory, unpcklpd for registers.
4174 Try to avoid move when unpacking can be done in source, or SSE3
4175 movddup is available. */
4176 if (REG_P (operands[1]))
4179 && true_regnum (operands[0]) != true_regnum (operands[1])
4180 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4181 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4183 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4184 emit_move_insn (tmp, operands[1]);
4187 else if (!TARGET_SSE3)
4188 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4189 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4192 emit_insn (gen_sse2_loadlpd (operands[4],
4193 CONST0_RTX (V2DFmode), operands[1]));
4196 ;; It's more profitable to split and then extend in the same register.
4198 [(set (match_operand:SF 0 "register_operand")
4200 (match_operand:DF 1 "memory_operand")))]
4201 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4202 && optimize_insn_for_speed_p ()
4203 && SSE_REG_P (operands[0])"
4204 [(set (match_dup 2) (match_dup 1))
4205 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4206 "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4208 (define_expand "truncdfsf2_with_temp"
4209 [(parallel [(set (match_operand:SF 0)
4210 (float_truncate:SF (match_operand:DF 1)))
4211 (clobber (match_operand:SF 2))])])
4213 (define_insn "*truncdfsf_fast_mixed"
4214 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4216 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4217 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4219 switch (which_alternative)
4222 return output_387_reg_move (insn, operands);
4224 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4229 [(set_attr "type" "fmov,ssecvt")
4230 (set_attr "prefix" "orig,maybe_vex")
4231 (set_attr "mode" "SF")])
4233 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4234 ;; because nothing we do here is unsafe.
4235 (define_insn "*truncdfsf_fast_sse"
4236 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4238 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4239 "TARGET_SSE2 && TARGET_SSE_MATH"
4240 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4241 [(set_attr "type" "ssecvt")
4242 (set_attr "prefix" "maybe_vex")
4243 (set_attr "mode" "SF")])
4245 (define_insn "*truncdfsf_fast_i387"
4246 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4248 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4249 "TARGET_80387 && flag_unsafe_math_optimizations"
4250 "* return output_387_reg_move (insn, operands);"
4251 [(set_attr "type" "fmov")
4252 (set_attr "mode" "SF")])
4254 (define_insn "*truncdfsf_mixed"
4255 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4257 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4258 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4259 "TARGET_MIX_SSE_I387"
4261 switch (which_alternative)
4264 return output_387_reg_move (insn, operands);
4266 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4272 [(set_attr "isa" "*,sse2,*,*,*")
4273 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4274 (set_attr "unit" "*,*,i387,i387,i387")
4275 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4276 (set_attr "mode" "SF")])
4278 (define_insn "*truncdfsf_i387"
4279 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4281 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4282 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4285 switch (which_alternative)
4288 return output_387_reg_move (insn, operands);
4294 [(set_attr "type" "fmov,multi,multi,multi")
4295 (set_attr "unit" "*,i387,i387,i387")
4296 (set_attr "mode" "SF")])
4298 (define_insn "*truncdfsf2_i387_1"
4299 [(set (match_operand:SF 0 "memory_operand" "=m")
4301 (match_operand:DF 1 "register_operand" "f")))]
4303 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4304 && !TARGET_MIX_SSE_I387"
4305 "* return output_387_reg_move (insn, operands);"
4306 [(set_attr "type" "fmov")
4307 (set_attr "mode" "SF")])
4310 [(set (match_operand:SF 0 "register_operand")
4312 (match_operand:DF 1 "fp_register_operand")))
4313 (clobber (match_operand 2))]
4315 [(set (match_dup 2) (match_dup 1))
4316 (set (match_dup 0) (match_dup 2))]
4317 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4319 ;; Conversion from XFmode to {SF,DF}mode
4321 (define_expand "truncxf<mode>2"
4322 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4323 (float_truncate:MODEF
4324 (match_operand:XF 1 "register_operand")))
4325 (clobber (match_dup 2))])]
4328 if (flag_unsafe_math_optimizations)
4330 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4331 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4332 if (reg != operands[0])
4333 emit_move_insn (operands[0], reg);
4337 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4340 (define_insn "*truncxfsf2_mixed"
4341 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4343 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4344 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4347 gcc_assert (!which_alternative);
4348 return output_387_reg_move (insn, operands);
4350 [(set_attr "type" "fmov,multi,multi,multi")
4351 (set_attr "unit" "*,i387,i387,i387")
4352 (set_attr "mode" "SF")])
4354 (define_insn "*truncxfdf2_mixed"
4355 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4357 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4358 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4361 gcc_assert (!which_alternative);
4362 return output_387_reg_move (insn, operands);
4364 [(set_attr "isa" "*,*,sse2,*")
4365 (set_attr "type" "fmov,multi,multi,multi")
4366 (set_attr "unit" "*,i387,i387,i387")
4367 (set_attr "mode" "DF")])
4369 (define_insn "truncxf<mode>2_i387_noop"
4370 [(set (match_operand:MODEF 0 "register_operand" "=f")
4371 (float_truncate:MODEF
4372 (match_operand:XF 1 "register_operand" "f")))]
4373 "TARGET_80387 && flag_unsafe_math_optimizations"
4374 "* return output_387_reg_move (insn, operands);"
4375 [(set_attr "type" "fmov")
4376 (set_attr "mode" "<MODE>")])
4378 (define_insn "*truncxf<mode>2_i387"
4379 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4380 (float_truncate:MODEF
4381 (match_operand:XF 1 "register_operand" "f")))]
4383 "* return output_387_reg_move (insn, operands);"
4384 [(set_attr "type" "fmov")
4385 (set_attr "mode" "<MODE>")])
4388 [(set (match_operand:MODEF 0 "register_operand")
4389 (float_truncate:MODEF
4390 (match_operand:XF 1 "register_operand")))
4391 (clobber (match_operand:MODEF 2 "memory_operand"))]
4392 "TARGET_80387 && reload_completed"
4393 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4394 (set (match_dup 0) (match_dup 2))])
4397 [(set (match_operand:MODEF 0 "memory_operand")
4398 (float_truncate:MODEF
4399 (match_operand:XF 1 "register_operand")))
4400 (clobber (match_operand:MODEF 2 "memory_operand"))]
4402 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4404 ;; Signed conversion to DImode.
4406 (define_expand "fix_truncxfdi2"
4407 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4408 (fix:DI (match_operand:XF 1 "register_operand")))
4409 (clobber (reg:CC FLAGS_REG))])]
4414 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4419 (define_expand "fix_trunc<mode>di2"
4420 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4421 (fix:DI (match_operand:MODEF 1 "register_operand")))
4422 (clobber (reg:CC FLAGS_REG))])]
4423 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4426 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4428 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4431 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4433 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4434 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4435 if (out != operands[0])
4436 emit_move_insn (operands[0], out);
4441 ;; Signed conversion to SImode.
4443 (define_expand "fix_truncxfsi2"
4444 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4445 (fix:SI (match_operand:XF 1 "register_operand")))
4446 (clobber (reg:CC FLAGS_REG))])]
4451 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4456 (define_expand "fix_trunc<mode>si2"
4457 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4458 (fix:SI (match_operand:MODEF 1 "register_operand")))
4459 (clobber (reg:CC FLAGS_REG))])]
4460 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4463 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4465 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4468 if (SSE_FLOAT_MODE_P (<MODE>mode))
4470 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4471 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4472 if (out != operands[0])
4473 emit_move_insn (operands[0], out);
4478 ;; Signed conversion to HImode.
4480 (define_expand "fix_trunc<mode>hi2"
4481 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4482 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4483 (clobber (reg:CC FLAGS_REG))])]
4485 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4489 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4494 ;; Unsigned conversion to SImode.
4496 (define_expand "fixuns_trunc<mode>si2"
4498 [(set (match_operand:SI 0 "register_operand")
4500 (match_operand:MODEF 1 "nonimmediate_operand")))
4502 (clobber (match_scratch:<ssevecmode> 3))
4503 (clobber (match_scratch:<ssevecmode> 4))])]
4504 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4506 machine_mode mode = <MODE>mode;
4507 machine_mode vecmode = <ssevecmode>mode;
4508 REAL_VALUE_TYPE TWO31r;
4511 if (optimize_insn_for_size_p ())
4514 real_ldexp (&TWO31r, &dconst1, 31);
4515 two31 = const_double_from_real_value (TWO31r, mode);
4516 two31 = ix86_build_const_vector (vecmode, true, two31);
4517 operands[2] = force_reg (vecmode, two31);
4520 (define_insn_and_split "*fixuns_trunc<mode>_1"
4521 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4523 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4524 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4525 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4526 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4527 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4528 && optimize_function_for_speed_p (cfun)"
4530 "&& reload_completed"
4533 ix86_split_convert_uns_si_sse (operands);
4537 ;; Unsigned conversion to HImode.
4538 ;; Without these patterns, we'll try the unsigned SI conversion which
4539 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4541 (define_expand "fixuns_trunc<mode>hi2"
4543 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4544 (set (match_operand:HI 0 "nonimmediate_operand")
4545 (subreg:HI (match_dup 2) 0))]
4546 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4547 "operands[2] = gen_reg_rtx (SImode);")
4549 ;; When SSE is available, it is always faster to use it!
4550 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4551 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4552 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4553 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4554 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4555 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4556 [(set_attr "type" "sseicvt")
4557 (set_attr "prefix" "maybe_vex")
4558 (set (attr "prefix_rex")
4560 (match_test "<SWI48:MODE>mode == DImode")
4562 (const_string "*")))
4563 (set_attr "mode" "<MODEF:MODE>")
4564 (set_attr "athlon_decode" "double,vector")
4565 (set_attr "amdfam10_decode" "double,double")
4566 (set_attr "bdver1_decode" "double,double")])
4568 ;; Avoid vector decoded forms of the instruction.
4570 [(match_scratch:MODEF 2 "x")
4571 (set (match_operand:SWI48 0 "register_operand")
4572 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4573 "TARGET_AVOID_VECTOR_DECODE
4574 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4575 && optimize_insn_for_speed_p ()"
4576 [(set (match_dup 2) (match_dup 1))
4577 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4579 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4580 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4581 (fix:SWI248x (match_operand 1 "register_operand")))]
4582 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4584 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4585 && (TARGET_64BIT || <MODE>mode != DImode))
4587 && can_create_pseudo_p ()"
4592 if (memory_operand (operands[0], VOIDmode))
4593 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4596 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4597 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4603 [(set_attr "type" "fisttp")
4604 (set_attr "mode" "<MODE>")])
4606 (define_insn "fix_trunc<mode>_i387_fisttp"
4607 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4608 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4609 (clobber (match_scratch:XF 2 "=&1f"))]
4610 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4612 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4613 && (TARGET_64BIT || <MODE>mode != DImode))
4614 && TARGET_SSE_MATH)"
4615 "* return output_fix_trunc (insn, operands, true);"
4616 [(set_attr "type" "fisttp")
4617 (set_attr "mode" "<MODE>")])
4619 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4620 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4621 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4622 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4623 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4624 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4626 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4627 && (TARGET_64BIT || <MODE>mode != DImode))
4628 && TARGET_SSE_MATH)"
4630 [(set_attr "type" "fisttp")
4631 (set_attr "mode" "<MODE>")])
4634 [(set (match_operand:SWI248x 0 "register_operand")
4635 (fix:SWI248x (match_operand 1 "register_operand")))
4636 (clobber (match_operand:SWI248x 2 "memory_operand"))
4637 (clobber (match_scratch 3))]
4639 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4640 (clobber (match_dup 3))])
4641 (set (match_dup 0) (match_dup 2))])
4644 [(set (match_operand:SWI248x 0 "memory_operand")
4645 (fix:SWI248x (match_operand 1 "register_operand")))
4646 (clobber (match_operand:SWI248x 2 "memory_operand"))
4647 (clobber (match_scratch 3))]
4649 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4650 (clobber (match_dup 3))])])
4652 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4653 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4654 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4655 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4656 ;; function in i386.c.
4657 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4658 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4659 (fix:SWI248x (match_operand 1 "register_operand")))
4660 (clobber (reg:CC FLAGS_REG))]
4661 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4663 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4664 && (TARGET_64BIT || <MODE>mode != DImode))
4665 && can_create_pseudo_p ()"
4670 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4672 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4673 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4674 if (memory_operand (operands[0], VOIDmode))
4675 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4676 operands[2], operands[3]));
4679 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4680 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4681 operands[2], operands[3],
4686 [(set_attr "type" "fistp")
4687 (set_attr "i387_cw" "trunc")
4688 (set_attr "mode" "<MODE>")])
4690 (define_insn "fix_truncdi_i387"
4691 [(set (match_operand:DI 0 "memory_operand" "=m")
4692 (fix:DI (match_operand 1 "register_operand" "f")))
4693 (use (match_operand:HI 2 "memory_operand" "m"))
4694 (use (match_operand:HI 3 "memory_operand" "m"))
4695 (clobber (match_scratch:XF 4 "=&1f"))]
4696 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4698 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4699 "* return output_fix_trunc (insn, operands, false);"
4700 [(set_attr "type" "fistp")
4701 (set_attr "i387_cw" "trunc")
4702 (set_attr "mode" "DI")])
4704 (define_insn "fix_truncdi_i387_with_temp"
4705 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4706 (fix:DI (match_operand 1 "register_operand" "f,f")))
4707 (use (match_operand:HI 2 "memory_operand" "m,m"))
4708 (use (match_operand:HI 3 "memory_operand" "m,m"))
4709 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4710 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4711 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4713 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4715 [(set_attr "type" "fistp")
4716 (set_attr "i387_cw" "trunc")
4717 (set_attr "mode" "DI")])
4720 [(set (match_operand:DI 0 "register_operand")
4721 (fix:DI (match_operand 1 "register_operand")))
4722 (use (match_operand:HI 2 "memory_operand"))
4723 (use (match_operand:HI 3 "memory_operand"))
4724 (clobber (match_operand:DI 4 "memory_operand"))
4725 (clobber (match_scratch 5))]
4727 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4730 (clobber (match_dup 5))])
4731 (set (match_dup 0) (match_dup 4))])
4734 [(set (match_operand:DI 0 "memory_operand")
4735 (fix:DI (match_operand 1 "register_operand")))
4736 (use (match_operand:HI 2 "memory_operand"))
4737 (use (match_operand:HI 3 "memory_operand"))
4738 (clobber (match_operand:DI 4 "memory_operand"))
4739 (clobber (match_scratch 5))]
4741 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4744 (clobber (match_dup 5))])])
4746 (define_insn "fix_trunc<mode>_i387"
4747 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4748 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4749 (use (match_operand:HI 2 "memory_operand" "m"))
4750 (use (match_operand:HI 3 "memory_operand" "m"))]
4751 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4753 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4754 "* return output_fix_trunc (insn, operands, false);"
4755 [(set_attr "type" "fistp")
4756 (set_attr "i387_cw" "trunc")
4757 (set_attr "mode" "<MODE>")])
4759 (define_insn "fix_trunc<mode>_i387_with_temp"
4760 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4761 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4762 (use (match_operand:HI 2 "memory_operand" "m,m"))
4763 (use (match_operand:HI 3 "memory_operand" "m,m"))
4764 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4765 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4767 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4769 [(set_attr "type" "fistp")
4770 (set_attr "i387_cw" "trunc")
4771 (set_attr "mode" "<MODE>")])
4774 [(set (match_operand:SWI24 0 "register_operand")
4775 (fix:SWI24 (match_operand 1 "register_operand")))
4776 (use (match_operand:HI 2 "memory_operand"))
4777 (use (match_operand:HI 3 "memory_operand"))
4778 (clobber (match_operand:SWI24 4 "memory_operand"))]
4780 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4782 (use (match_dup 3))])
4783 (set (match_dup 0) (match_dup 4))])
4786 [(set (match_operand:SWI24 0 "memory_operand")
4787 (fix:SWI24 (match_operand 1 "register_operand")))
4788 (use (match_operand:HI 2 "memory_operand"))
4789 (use (match_operand:HI 3 "memory_operand"))
4790 (clobber (match_operand:SWI24 4 "memory_operand"))]
4792 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4794 (use (match_dup 3))])])
4796 (define_insn "x86_fnstcw_1"
4797 [(set (match_operand:HI 0 "memory_operand" "=m")
4798 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4801 [(set (attr "length")
4802 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4803 (set_attr "mode" "HI")
4804 (set_attr "unit" "i387")
4805 (set_attr "bdver1_decode" "vector")])
4807 (define_insn "x86_fldcw_1"
4808 [(set (reg:HI FPCR_REG)
4809 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4812 [(set (attr "length")
4813 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4814 (set_attr "mode" "HI")
4815 (set_attr "unit" "i387")
4816 (set_attr "athlon_decode" "vector")
4817 (set_attr "amdfam10_decode" "vector")
4818 (set_attr "bdver1_decode" "vector")])
4820 ;; Conversion between fixed point and floating point.
4822 ;; Even though we only accept memory inputs, the backend _really_
4823 ;; wants to be able to do this between registers. Thankfully, LRA
4824 ;; will fix this up for us during register allocation.
4826 (define_insn "floathi<mode>2"
4827 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4828 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4830 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4831 || TARGET_MIX_SSE_I387)"
4833 [(set_attr "type" "fmov")
4834 (set_attr "mode" "<MODE>")
4835 (set_attr "fp_int_src" "true")])
4837 (define_insn "float<SWI48x:mode>xf2"
4838 [(set (match_operand:XF 0 "register_operand" "=f")
4839 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4842 [(set_attr "type" "fmov")
4843 (set_attr "mode" "XF")
4844 (set_attr "fp_int_src" "true")])
4846 (define_expand "float<SWI48:mode><MODEF:mode>2"
4847 [(set (match_operand:MODEF 0 "register_operand")
4848 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4849 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
4851 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
4852 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
4854 rtx reg = gen_reg_rtx (XFmode);
4855 rtx (*insn)(rtx, rtx);
4857 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
4859 if (<MODEF:MODE>mode == SFmode)
4860 insn = gen_truncxfsf2;
4861 else if (<MODEF:MODE>mode == DFmode)
4862 insn = gen_truncxfdf2;
4866 emit_insn (insn (operands[0], reg));
4871 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse"
4872 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4874 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4875 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4878 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4879 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4880 [(set_attr "type" "fmov,sseicvt,sseicvt")
4881 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4882 (set_attr "mode" "<MODEF:MODE>")
4883 (set (attr "prefix_rex")
4885 (and (eq_attr "prefix" "maybe_vex")
4886 (match_test "<SWI48:MODE>mode == DImode"))
4888 (const_string "*")))
4889 (set_attr "unit" "i387,*,*")
4890 (set_attr "athlon_decode" "*,double,direct")
4891 (set_attr "amdfam10_decode" "*,vector,double")
4892 (set_attr "bdver1_decode" "*,double,direct")
4893 (set_attr "fp_int_src" "true")
4894 (set (attr "enabled")
4895 (cond [(eq_attr "alternative" "0")
4896 (symbol_ref "TARGET_MIX_SSE_I387
4897 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
4900 (symbol_ref "true")))
4901 (set (attr "preferred_for_speed")
4902 (cond [(eq_attr "alternative" "1")
4903 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
4904 (symbol_ref "true")))])
4906 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
4907 [(set (match_operand:MODEF 0 "register_operand" "=f")
4908 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4909 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
4911 [(set_attr "type" "fmov")
4912 (set_attr "mode" "<MODEF:MODE>")
4913 (set_attr "fp_int_src" "true")])
4915 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
4916 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
4917 ;; alternative in sse2_loadld.
4919 [(set (match_operand:MODEF 0 "register_operand")
4920 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
4921 "TARGET_SSE2 && TARGET_SSE_MATH
4922 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4923 && reload_completed && SSE_REG_P (operands[0])
4924 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)"
4927 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4929 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4931 emit_insn (gen_sse2_loadld (operands[4],
4932 CONST0_RTX (V4SImode), operands[1]));
4934 if (<ssevecmode>mode == V4SFmode)
4935 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4937 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4941 ;; Avoid partial SSE register dependency stalls
4943 [(set (match_operand:MODEF 0 "register_operand")
4944 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4945 "TARGET_SSE2 && TARGET_SSE_MATH
4946 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4947 && optimize_function_for_speed_p (cfun)
4948 && reload_completed && SSE_REG_P (operands[0])"
4951 const machine_mode vmode = <MODEF:ssevecmode>mode;
4952 const machine_mode mode = <MODEF:MODE>mode;
4953 rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
4955 emit_move_insn (op0, CONST0_RTX (vmode));
4957 t = gen_rtx_FLOAT (mode, operands[1]);
4958 t = gen_rtx_VEC_DUPLICATE (vmode, t);
4959 t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
4960 emit_insn (gen_rtx_SET (VOIDmode, op0, t));
4964 ;; Break partial reg stall for cvtsd2ss.
4967 [(set (match_operand:SF 0 "register_operand")
4969 (match_operand:DF 1 "nonimmediate_operand")))]
4970 "TARGET_SSE2 && TARGET_SSE_MATH
4971 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4972 && optimize_function_for_speed_p (cfun)
4973 && SSE_REG_P (operands[0])
4974 && (!SSE_REG_P (operands[1])
4975 || REGNO (operands[0]) != REGNO (operands[1]))"
4979 (float_truncate:V2SF
4984 operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
4986 operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
4988 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4991 ;; Break partial reg stall for cvtss2sd.
4994 [(set (match_operand:DF 0 "register_operand")
4996 (match_operand:SF 1 "nonimmediate_operand")))]
4997 "TARGET_SSE2 && TARGET_SSE_MATH
4998 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4999 && optimize_function_for_speed_p (cfun)
5000 && SSE_REG_P (operands[0])
5001 && (!SSE_REG_P (operands[1])
5002 || REGNO (operands[0]) != REGNO (operands[1]))"
5008 (parallel [(const_int 0) (const_int 1)])))
5012 operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
5014 operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
5016 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5019 ;; Avoid store forwarding (partial memory) stall penalty
5020 ;; by passing DImode value through XMM registers. */
5022 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5023 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5025 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5026 (clobber (match_scratch:V4SI 3 "=X,x"))
5027 (clobber (match_scratch:V4SI 4 "=X,x"))
5028 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5029 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5030 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5031 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5033 [(set_attr "type" "multi")
5034 (set_attr "mode" "<X87MODEF:MODE>")
5035 (set_attr "unit" "i387")
5036 (set_attr "fp_int_src" "true")])
5039 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5040 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5041 (clobber (match_scratch:V4SI 3))
5042 (clobber (match_scratch:V4SI 4))
5043 (clobber (match_operand:DI 2 "memory_operand"))]
5044 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5045 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5046 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5047 && reload_completed"
5048 [(set (match_dup 2) (match_dup 3))
5049 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5051 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5052 Assemble the 64-bit DImode value in an xmm register. */
5053 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5054 gen_lowpart (SImode, operands[1])));
5055 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5056 gen_highpart (SImode, operands[1])));
5057 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5060 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5064 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5065 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5066 (clobber (match_scratch:V4SI 3))
5067 (clobber (match_scratch:V4SI 4))
5068 (clobber (match_operand:DI 2 "memory_operand"))]
5069 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5070 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5071 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5072 && reload_completed"
5073 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5075 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5076 [(set (match_operand:MODEF 0 "register_operand")
5077 (unsigned_float:MODEF
5078 (match_operand:SWI12 1 "nonimmediate_operand")))]
5080 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5082 operands[1] = convert_to_mode (SImode, operands[1], 1);
5083 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5087 ;; Avoid store forwarding (partial memory) stall penalty by extending
5088 ;; SImode value to DImode through XMM register instead of pushing two
5089 ;; SImode values to stack. Also note that fild loads from memory only.
5091 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5092 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5093 (unsigned_float:X87MODEF
5094 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5095 (clobber (match_scratch:DI 3 "=x"))
5096 (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5098 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5099 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5101 "&& reload_completed"
5102 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5103 (set (match_dup 2) (match_dup 3))
5105 (float:X87MODEF (match_dup 2)))]
5107 [(set_attr "type" "multi")
5108 (set_attr "mode" "<MODE>")])
5110 (define_expand "floatunssi<mode>2"
5112 [(set (match_operand:X87MODEF 0 "register_operand")
5113 (unsigned_float:X87MODEF
5114 (match_operand:SI 1 "nonimmediate_operand")))
5115 (clobber (match_scratch:DI 3))
5116 (clobber (match_dup 2))])]
5118 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5119 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5120 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5122 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5124 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5128 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5131 (define_expand "floatunsdisf2"
5132 [(use (match_operand:SF 0 "register_operand"))
5133 (use (match_operand:DI 1 "nonimmediate_operand"))]
5134 "TARGET_64BIT && TARGET_SSE_MATH"
5135 "x86_emit_floatuns (operands); DONE;")
5137 (define_expand "floatunsdidf2"
5138 [(use (match_operand:DF 0 "register_operand"))
5139 (use (match_operand:DI 1 "nonimmediate_operand"))]
5140 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5141 && TARGET_SSE2 && TARGET_SSE_MATH"
5144 x86_emit_floatuns (operands);
5146 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5150 ;; Load effective address instructions
5152 (define_insn_and_split "*lea<mode>"
5153 [(set (match_operand:SWI48 0 "register_operand" "=r")
5154 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5157 if (SImode_address_operand (operands[1], VOIDmode))
5159 gcc_assert (TARGET_64BIT);
5160 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5163 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5165 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5168 machine_mode mode = <MODE>mode;
5171 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5172 change operands[] array behind our back. */
5173 pat = PATTERN (curr_insn);
5175 operands[0] = SET_DEST (pat);
5176 operands[1] = SET_SRC (pat);
5178 /* Emit all operations in SImode for zero-extended addresses. */
5179 if (SImode_address_operand (operands[1], VOIDmode))
5182 ix86_split_lea_for_addr (curr_insn, operands, mode);
5184 /* Zero-extend return register to DImode for zero-extended addresses. */
5185 if (mode != <MODE>mode)
5186 emit_insn (gen_zero_extendsidi2
5187 (operands[0], gen_lowpart (mode, operands[0])));
5191 [(set_attr "type" "lea")
5194 (match_operand 1 "SImode_address_operand")
5196 (const_string "<MODE>")))])
5200 (define_expand "add<mode>3"
5201 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5202 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5203 (match_operand:SDWIM 2 "<general_operand>")))]
5205 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5207 (define_insn_and_split "*add<dwi>3_doubleword"
5208 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5210 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5211 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5212 (clobber (reg:CC FLAGS_REG))]
5213 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5216 [(parallel [(set (reg:CC FLAGS_REG)
5217 (unspec:CC [(match_dup 1) (match_dup 2)]
5220 (plus:DWIH (match_dup 1) (match_dup 2)))])
5221 (parallel [(set (match_dup 3)
5225 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5227 (clobber (reg:CC FLAGS_REG))])]
5228 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5230 (define_insn "*add<mode>3_cc"
5231 [(set (reg:CC FLAGS_REG)
5233 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5234 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5236 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5237 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5238 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5239 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5240 [(set_attr "type" "alu")
5241 (set_attr "mode" "<MODE>")])
5243 (define_insn "addqi3_cc"
5244 [(set (reg:CC FLAGS_REG)
5246 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5247 (match_operand:QI 2 "general_operand" "qn,qm")]
5249 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5250 (plus:QI (match_dup 1) (match_dup 2)))]
5251 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5252 "add{b}\t{%2, %0|%0, %2}"
5253 [(set_attr "type" "alu")
5254 (set_attr "mode" "QI")])
5256 (define_insn "*add<mode>_1"
5257 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5259 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5260 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5261 (clobber (reg:CC FLAGS_REG))]
5262 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5264 switch (get_attr_type (insn))
5270 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5271 if (operands[2] == const1_rtx)
5272 return "inc{<imodesuffix>}\t%0";
5275 gcc_assert (operands[2] == constm1_rtx);
5276 return "dec{<imodesuffix>}\t%0";
5280 /* For most processors, ADD is faster than LEA. This alternative
5281 was added to use ADD as much as possible. */
5282 if (which_alternative == 2)
5283 std::swap (operands[1], operands[2]);
5285 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5286 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5287 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5289 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5293 (cond [(eq_attr "alternative" "3")
5294 (const_string "lea")
5295 (match_operand:SWI48 2 "incdec_operand")
5296 (const_string "incdec")
5298 (const_string "alu")))
5299 (set (attr "length_immediate")
5301 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5303 (const_string "*")))
5304 (set_attr "mode" "<MODE>")])
5306 ;; It may seem that nonimmediate operand is proper one for operand 1.
5307 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5308 ;; we take care in ix86_binary_operator_ok to not allow two memory
5309 ;; operands so proper swapping will be done in reload. This allow
5310 ;; patterns constructed from addsi_1 to match.
5312 (define_insn "addsi_1_zext"
5313 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5315 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5316 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5317 (clobber (reg:CC FLAGS_REG))]
5318 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5320 switch (get_attr_type (insn))
5326 if (operands[2] == const1_rtx)
5327 return "inc{l}\t%k0";
5330 gcc_assert (operands[2] == constm1_rtx);
5331 return "dec{l}\t%k0";
5335 /* For most processors, ADD is faster than LEA. This alternative
5336 was added to use ADD as much as possible. */
5337 if (which_alternative == 1)
5338 std::swap (operands[1], operands[2]);
5340 if (x86_maybe_negate_const_int (&operands[2], SImode))
5341 return "sub{l}\t{%2, %k0|%k0, %2}";
5343 return "add{l}\t{%2, %k0|%k0, %2}";
5347 (cond [(eq_attr "alternative" "2")
5348 (const_string "lea")
5349 (match_operand:SI 2 "incdec_operand")
5350 (const_string "incdec")
5352 (const_string "alu")))
5353 (set (attr "length_immediate")
5355 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5357 (const_string "*")))
5358 (set_attr "mode" "SI")])
5360 (define_insn "*addhi_1"
5361 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5362 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5363 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5364 (clobber (reg:CC FLAGS_REG))]
5365 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5367 switch (get_attr_type (insn))
5373 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5374 if (operands[2] == const1_rtx)
5375 return "inc{w}\t%0";
5378 gcc_assert (operands[2] == constm1_rtx);
5379 return "dec{w}\t%0";
5383 /* For most processors, ADD is faster than LEA. This alternative
5384 was added to use ADD as much as possible. */
5385 if (which_alternative == 2)
5386 std::swap (operands[1], operands[2]);
5388 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5389 if (x86_maybe_negate_const_int (&operands[2], HImode))
5390 return "sub{w}\t{%2, %0|%0, %2}";
5392 return "add{w}\t{%2, %0|%0, %2}";
5396 (cond [(eq_attr "alternative" "3")
5397 (const_string "lea")
5398 (match_operand:HI 2 "incdec_operand")
5399 (const_string "incdec")
5401 (const_string "alu")))
5402 (set (attr "length_immediate")
5404 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5406 (const_string "*")))
5407 (set_attr "mode" "HI,HI,HI,SI")])
5409 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5410 (define_insn "*addqi_1"
5411 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5412 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5413 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5414 (clobber (reg:CC FLAGS_REG))]
5415 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5417 bool widen = (which_alternative == 3 || which_alternative == 4);
5419 switch (get_attr_type (insn))
5425 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5426 if (operands[2] == const1_rtx)
5427 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5430 gcc_assert (operands[2] == constm1_rtx);
5431 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5435 /* For most processors, ADD is faster than LEA. These alternatives
5436 were added to use ADD as much as possible. */
5437 if (which_alternative == 2 || which_alternative == 4)
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], QImode))
5444 return "sub{l}\t{%2, %k0|%k0, %2}";
5446 return "sub{b}\t{%2, %0|%0, %2}";
5449 return "add{l}\t{%k2, %k0|%k0, %k2}";
5451 return "add{b}\t{%2, %0|%0, %2}";
5455 (cond [(eq_attr "alternative" "5")
5456 (const_string "lea")
5457 (match_operand:QI 2 "incdec_operand")
5458 (const_string "incdec")
5460 (const_string "alu")))
5461 (set (attr "length_immediate")
5463 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5465 (const_string "*")))
5466 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5468 (define_insn "*addqi_1_slp"
5469 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5470 (plus:QI (match_dup 0)
5471 (match_operand:QI 1 "general_operand" "qn,qm")))
5472 (clobber (reg:CC FLAGS_REG))]
5473 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5474 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5476 switch (get_attr_type (insn))
5479 if (operands[1] == const1_rtx)
5480 return "inc{b}\t%0";
5483 gcc_assert (operands[1] == constm1_rtx);
5484 return "dec{b}\t%0";
5488 if (x86_maybe_negate_const_int (&operands[1], QImode))
5489 return "sub{b}\t{%1, %0|%0, %1}";
5491 return "add{b}\t{%1, %0|%0, %1}";
5495 (if_then_else (match_operand:QI 1 "incdec_operand")
5496 (const_string "incdec")
5497 (const_string "alu1")))
5498 (set (attr "memory")
5499 (if_then_else (match_operand 1 "memory_operand")
5500 (const_string "load")
5501 (const_string "none")))
5502 (set_attr "mode" "QI")])
5504 ;; Split non destructive adds if we cannot use lea.
5506 [(set (match_operand:SWI48 0 "register_operand")
5507 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5508 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5509 (clobber (reg:CC FLAGS_REG))]
5510 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5511 [(set (match_dup 0) (match_dup 1))
5512 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5513 (clobber (reg:CC FLAGS_REG))])])
5515 ;; Convert add to the lea pattern to avoid flags dependency.
5517 [(set (match_operand:SWI 0 "register_operand")
5518 (plus:SWI (match_operand:SWI 1 "register_operand")
5519 (match_operand:SWI 2 "<nonmemory_operand>")))
5520 (clobber (reg:CC FLAGS_REG))]
5521 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5524 machine_mode mode = <MODE>mode;
5527 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5530 operands[0] = gen_lowpart (mode, operands[0]);
5531 operands[1] = gen_lowpart (mode, operands[1]);
5532 operands[2] = gen_lowpart (mode, operands[2]);
5535 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5537 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5541 ;; Split non destructive adds if we cannot use lea.
5543 [(set (match_operand:DI 0 "register_operand")
5545 (plus:SI (match_operand:SI 1 "register_operand")
5546 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5547 (clobber (reg:CC FLAGS_REG))]
5549 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5550 [(set (match_dup 3) (match_dup 1))
5551 (parallel [(set (match_dup 0)
5552 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5553 (clobber (reg:CC FLAGS_REG))])]
5554 "operands[3] = gen_lowpart (SImode, operands[0]);")
5556 ;; Convert add to the lea pattern to avoid flags dependency.
5558 [(set (match_operand:DI 0 "register_operand")
5560 (plus:SI (match_operand:SI 1 "register_operand")
5561 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5562 (clobber (reg:CC FLAGS_REG))]
5563 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5565 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5567 (define_insn "*add<mode>_2"
5568 [(set (reg FLAGS_REG)
5571 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5572 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5574 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5575 (plus:SWI (match_dup 1) (match_dup 2)))]
5576 "ix86_match_ccmode (insn, CCGOCmode)
5577 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5579 switch (get_attr_type (insn))
5582 if (operands[2] == const1_rtx)
5583 return "inc{<imodesuffix>}\t%0";
5586 gcc_assert (operands[2] == constm1_rtx);
5587 return "dec{<imodesuffix>}\t%0";
5591 if (which_alternative == 2)
5592 std::swap (operands[1], operands[2]);
5594 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5595 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5596 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5598 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5602 (if_then_else (match_operand:SWI 2 "incdec_operand")
5603 (const_string "incdec")
5604 (const_string "alu")))
5605 (set (attr "length_immediate")
5607 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5609 (const_string "*")))
5610 (set_attr "mode" "<MODE>")])
5612 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5613 (define_insn "*addsi_2_zext"
5614 [(set (reg FLAGS_REG)
5616 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5617 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5619 (set (match_operand:DI 0 "register_operand" "=r,r")
5620 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5621 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5622 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5624 switch (get_attr_type (insn))
5627 if (operands[2] == const1_rtx)
5628 return "inc{l}\t%k0";
5631 gcc_assert (operands[2] == constm1_rtx);
5632 return "dec{l}\t%k0";
5636 if (which_alternative == 1)
5637 std::swap (operands[1], operands[2]);
5639 if (x86_maybe_negate_const_int (&operands[2], SImode))
5640 return "sub{l}\t{%2, %k0|%k0, %2}";
5642 return "add{l}\t{%2, %k0|%k0, %2}";
5646 (if_then_else (match_operand:SI 2 "incdec_operand")
5647 (const_string "incdec")
5648 (const_string "alu")))
5649 (set (attr "length_immediate")
5651 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5653 (const_string "*")))
5654 (set_attr "mode" "SI")])
5656 (define_insn "*add<mode>_3"
5657 [(set (reg FLAGS_REG)
5659 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5660 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5661 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5662 "ix86_match_ccmode (insn, CCZmode)
5663 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5665 switch (get_attr_type (insn))
5668 if (operands[2] == const1_rtx)
5669 return "inc{<imodesuffix>}\t%0";
5672 gcc_assert (operands[2] == constm1_rtx);
5673 return "dec{<imodesuffix>}\t%0";
5677 if (which_alternative == 1)
5678 std::swap (operands[1], operands[2]);
5680 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5681 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5682 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5684 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5688 (if_then_else (match_operand:SWI 2 "incdec_operand")
5689 (const_string "incdec")
5690 (const_string "alu")))
5691 (set (attr "length_immediate")
5693 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5695 (const_string "*")))
5696 (set_attr "mode" "<MODE>")])
5698 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5699 (define_insn "*addsi_3_zext"
5700 [(set (reg FLAGS_REG)
5702 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5703 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5704 (set (match_operand:DI 0 "register_operand" "=r,r")
5705 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5706 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5707 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5709 switch (get_attr_type (insn))
5712 if (operands[2] == const1_rtx)
5713 return "inc{l}\t%k0";
5716 gcc_assert (operands[2] == constm1_rtx);
5717 return "dec{l}\t%k0";
5721 if (which_alternative == 1)
5722 std::swap (operands[1], operands[2]);
5724 if (x86_maybe_negate_const_int (&operands[2], SImode))
5725 return "sub{l}\t{%2, %k0|%k0, %2}";
5727 return "add{l}\t{%2, %k0|%k0, %2}";
5731 (if_then_else (match_operand:SI 2 "incdec_operand")
5732 (const_string "incdec")
5733 (const_string "alu")))
5734 (set (attr "length_immediate")
5736 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5738 (const_string "*")))
5739 (set_attr "mode" "SI")])
5741 ; For comparisons against 1, -1 and 128, we may generate better code
5742 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5743 ; is matched then. We can't accept general immediate, because for
5744 ; case of overflows, the result is messed up.
5745 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5746 ; only for comparisons not depending on it.
5748 (define_insn "*adddi_4"
5749 [(set (reg FLAGS_REG)
5751 (match_operand:DI 1 "nonimmediate_operand" "0")
5752 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5753 (clobber (match_scratch:DI 0 "=rm"))]
5755 && ix86_match_ccmode (insn, CCGCmode)"
5757 switch (get_attr_type (insn))
5760 if (operands[2] == constm1_rtx)
5761 return "inc{q}\t%0";
5764 gcc_assert (operands[2] == const1_rtx);
5765 return "dec{q}\t%0";
5769 if (x86_maybe_negate_const_int (&operands[2], DImode))
5770 return "add{q}\t{%2, %0|%0, %2}";
5772 return "sub{q}\t{%2, %0|%0, %2}";
5776 (if_then_else (match_operand:DI 2 "incdec_operand")
5777 (const_string "incdec")
5778 (const_string "alu")))
5779 (set (attr "length_immediate")
5781 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5783 (const_string "*")))
5784 (set_attr "mode" "DI")])
5786 ; For comparisons against 1, -1 and 128, we may generate better code
5787 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5788 ; is matched then. We can't accept general immediate, because for
5789 ; case of overflows, the result is messed up.
5790 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5791 ; only for comparisons not depending on it.
5793 (define_insn "*add<mode>_4"
5794 [(set (reg FLAGS_REG)
5796 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5797 (match_operand:SWI124 2 "const_int_operand" "n")))
5798 (clobber (match_scratch:SWI124 0 "=<r>m"))]
5799 "ix86_match_ccmode (insn, CCGCmode)"
5801 switch (get_attr_type (insn))
5804 if (operands[2] == constm1_rtx)
5805 return "inc{<imodesuffix>}\t%0";
5808 gcc_assert (operands[2] == const1_rtx);
5809 return "dec{<imodesuffix>}\t%0";
5813 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5814 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5816 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5820 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5821 (const_string "incdec")
5822 (const_string "alu")))
5823 (set (attr "length_immediate")
5825 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5827 (const_string "*")))
5828 (set_attr "mode" "<MODE>")])
5830 (define_insn "*add<mode>_5"
5831 [(set (reg FLAGS_REG)
5834 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5835 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5837 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5838 "ix86_match_ccmode (insn, CCGOCmode)
5839 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5841 switch (get_attr_type (insn))
5844 if (operands[2] == const1_rtx)
5845 return "inc{<imodesuffix>}\t%0";
5848 gcc_assert (operands[2] == constm1_rtx);
5849 return "dec{<imodesuffix>}\t%0";
5853 if (which_alternative == 1)
5854 std::swap (operands[1], operands[2]);
5856 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5857 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5858 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5860 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5864 (if_then_else (match_operand:SWI 2 "incdec_operand")
5865 (const_string "incdec")
5866 (const_string "alu")))
5867 (set (attr "length_immediate")
5869 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5871 (const_string "*")))
5872 (set_attr "mode" "<MODE>")])
5874 (define_insn "addqi_ext_1"
5875 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5880 (match_operand 1 "ext_register_operand" "0,0")
5883 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5884 (clobber (reg:CC FLAGS_REG))]
5887 switch (get_attr_type (insn))
5890 if (operands[2] == const1_rtx)
5891 return "inc{b}\t%h0";
5894 gcc_assert (operands[2] == constm1_rtx);
5895 return "dec{b}\t%h0";
5899 return "add{b}\t{%2, %h0|%h0, %2}";
5902 [(set_attr "isa" "*,nox64")
5904 (if_then_else (match_operand:QI 2 "incdec_operand")
5905 (const_string "incdec")
5906 (const_string "alu")))
5907 (set_attr "modrm" "1")
5908 (set_attr "mode" "QI")])
5910 (define_insn "*addqi_ext_2"
5911 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5916 (match_operand 1 "ext_register_operand" "%0")
5920 (match_operand 2 "ext_register_operand" "Q")
5923 (clobber (reg:CC FLAGS_REG))]
5925 "add{b}\t{%h2, %h0|%h0, %h2}"
5926 [(set_attr "type" "alu")
5927 (set_attr "mode" "QI")])
5929 ;; Add with jump on overflow.
5930 (define_expand "addv<mode>4"
5931 [(parallel [(set (reg:CCO FLAGS_REG)
5934 (match_operand:SWI 1 "nonimmediate_operand"))
5937 (plus:SWI (match_dup 1)
5938 (match_operand:SWI 2
5939 "<general_operand>")))))
5940 (set (match_operand:SWI 0 "register_operand")
5941 (plus:SWI (match_dup 1) (match_dup 2)))])
5942 (set (pc) (if_then_else
5943 (eq (reg:CCO FLAGS_REG) (const_int 0))
5944 (label_ref (match_operand 3))
5948 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
5949 if (CONST_INT_P (operands[2]))
5950 operands[4] = operands[2];
5952 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
5955 (define_insn "*addv<mode>4"
5956 [(set (reg:CCO FLAGS_REG)
5959 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
5961 (match_operand:SWI 2 "<general_sext_operand>"
5964 (plus:SWI (match_dup 1) (match_dup 2)))))
5965 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5966 (plus:SWI (match_dup 1) (match_dup 2)))]
5967 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5968 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5969 [(set_attr "type" "alu")
5970 (set_attr "mode" "<MODE>")])
5972 (define_insn "*addv<mode>4_1"
5973 [(set (reg:CCO FLAGS_REG)
5976 (match_operand:SWI 1 "nonimmediate_operand" "0"))
5977 (match_operand:<DWI> 3 "const_int_operand" "i"))
5979 (plus:SWI (match_dup 1)
5980 (match_operand:SWI 2 "x86_64_immediate_operand"
5982 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
5983 (plus:SWI (match_dup 1) (match_dup 2)))]
5984 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
5985 && CONST_INT_P (operands[2])
5986 && INTVAL (operands[2]) == INTVAL (operands[3])"
5987 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5988 [(set_attr "type" "alu")
5989 (set_attr "mode" "<MODE>")
5990 (set (attr "length_immediate")
5991 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
5993 (match_test "<MODE_SIZE> == 8")
5995 (const_string "<MODE_SIZE>")))])
5997 ;; The lea patterns for modes less than 32 bits need to be matched by
5998 ;; several insns converted to real lea by splitters.
6000 (define_insn_and_split "*lea_general_1"
6001 [(set (match_operand 0 "register_operand" "=r")
6002 (plus (plus (match_operand 1 "index_register_operand" "l")
6003 (match_operand 2 "register_operand" "r"))
6004 (match_operand 3 "immediate_operand" "i")))]
6005 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6006 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6007 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6008 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6009 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6010 || GET_MODE (operands[3]) == VOIDmode)"
6012 "&& reload_completed"
6015 machine_mode mode = SImode;
6018 operands[0] = gen_lowpart (mode, operands[0]);
6019 operands[1] = gen_lowpart (mode, operands[1]);
6020 operands[2] = gen_lowpart (mode, operands[2]);
6021 operands[3] = gen_lowpart (mode, operands[3]);
6023 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6026 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6029 [(set_attr "type" "lea")
6030 (set_attr "mode" "SI")])
6032 (define_insn_and_split "*lea_general_2"
6033 [(set (match_operand 0 "register_operand" "=r")
6034 (plus (mult (match_operand 1 "index_register_operand" "l")
6035 (match_operand 2 "const248_operand" "n"))
6036 (match_operand 3 "nonmemory_operand" "ri")))]
6037 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6038 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6039 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6040 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6041 || GET_MODE (operands[3]) == VOIDmode)"
6043 "&& reload_completed"
6046 machine_mode mode = SImode;
6049 operands[0] = gen_lowpart (mode, operands[0]);
6050 operands[1] = gen_lowpart (mode, operands[1]);
6051 operands[3] = gen_lowpart (mode, operands[3]);
6053 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6056 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6059 [(set_attr "type" "lea")
6060 (set_attr "mode" "SI")])
6062 (define_insn_and_split "*lea_general_3"
6063 [(set (match_operand 0 "register_operand" "=r")
6064 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6065 (match_operand 2 "const248_operand" "n"))
6066 (match_operand 3 "register_operand" "r"))
6067 (match_operand 4 "immediate_operand" "i")))]
6068 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6069 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6070 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6071 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6073 "&& reload_completed"
6076 machine_mode mode = SImode;
6079 operands[0] = gen_lowpart (mode, operands[0]);
6080 operands[1] = gen_lowpart (mode, operands[1]);
6081 operands[3] = gen_lowpart (mode, operands[3]);
6082 operands[4] = gen_lowpart (mode, operands[4]);
6084 pat = gen_rtx_PLUS (mode,
6086 gen_rtx_MULT (mode, operands[1],
6091 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6094 [(set_attr "type" "lea")
6095 (set_attr "mode" "SI")])
6097 (define_insn_and_split "*lea_general_4"
6098 [(set (match_operand 0 "register_operand" "=r")
6100 (match_operand 1 "index_register_operand" "l")
6101 (match_operand 2 "const_int_operand" "n"))
6102 (match_operand 3 "const_int_operand" "n")))]
6103 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6104 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6105 || GET_MODE (operands[0]) == SImode
6106 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6107 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6108 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6109 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6110 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6112 "&& reload_completed"
6115 machine_mode mode = GET_MODE (operands[0]);
6118 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6121 operands[0] = gen_lowpart (mode, operands[0]);
6122 operands[1] = gen_lowpart (mode, operands[1]);
6125 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6127 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6128 INTVAL (operands[3]));
6130 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6133 [(set_attr "type" "lea")
6135 (if_then_else (match_operand:DI 0)
6137 (const_string "SI")))])
6139 ;; Subtract instructions
6141 (define_expand "sub<mode>3"
6142 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6143 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6144 (match_operand:SDWIM 2 "<general_operand>")))]
6146 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6148 (define_insn_and_split "*sub<dwi>3_doubleword"
6149 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6151 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6152 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6153 (clobber (reg:CC FLAGS_REG))]
6154 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6157 [(parallel [(set (reg:CC FLAGS_REG)
6158 (compare:CC (match_dup 1) (match_dup 2)))
6160 (minus:DWIH (match_dup 1) (match_dup 2)))])
6161 (parallel [(set (match_dup 3)
6165 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6167 (clobber (reg:CC FLAGS_REG))])]
6168 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6170 (define_insn "*sub<mode>_1"
6171 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6173 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6174 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6175 (clobber (reg:CC FLAGS_REG))]
6176 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6177 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6178 [(set_attr "type" "alu")
6179 (set_attr "mode" "<MODE>")])
6181 (define_insn "*subsi_1_zext"
6182 [(set (match_operand:DI 0 "register_operand" "=r")
6184 (minus:SI (match_operand:SI 1 "register_operand" "0")
6185 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6186 (clobber (reg:CC FLAGS_REG))]
6187 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6188 "sub{l}\t{%2, %k0|%k0, %2}"
6189 [(set_attr "type" "alu")
6190 (set_attr "mode" "SI")])
6192 (define_insn "*subqi_1_slp"
6193 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6194 (minus:QI (match_dup 0)
6195 (match_operand:QI 1 "general_operand" "qn,qm")))
6196 (clobber (reg:CC FLAGS_REG))]
6197 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6198 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6199 "sub{b}\t{%1, %0|%0, %1}"
6200 [(set_attr "type" "alu1")
6201 (set_attr "mode" "QI")])
6203 (define_insn "*sub<mode>_2"
6204 [(set (reg FLAGS_REG)
6207 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6208 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6210 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6211 (minus:SWI (match_dup 1) (match_dup 2)))]
6212 "ix86_match_ccmode (insn, CCGOCmode)
6213 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6214 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6215 [(set_attr "type" "alu")
6216 (set_attr "mode" "<MODE>")])
6218 (define_insn "*subsi_2_zext"
6219 [(set (reg FLAGS_REG)
6221 (minus:SI (match_operand:SI 1 "register_operand" "0")
6222 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6224 (set (match_operand:DI 0 "register_operand" "=r")
6226 (minus:SI (match_dup 1)
6228 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6229 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6230 "sub{l}\t{%2, %k0|%k0, %2}"
6231 [(set_attr "type" "alu")
6232 (set_attr "mode" "SI")])
6234 ;; Subtract with jump on overflow.
6235 (define_expand "subv<mode>4"
6236 [(parallel [(set (reg:CCO FLAGS_REG)
6237 (eq:CCO (minus:<DWI>
6239 (match_operand:SWI 1 "nonimmediate_operand"))
6242 (minus:SWI (match_dup 1)
6243 (match_operand:SWI 2
6244 "<general_operand>")))))
6245 (set (match_operand:SWI 0 "register_operand")
6246 (minus:SWI (match_dup 1) (match_dup 2)))])
6247 (set (pc) (if_then_else
6248 (eq (reg:CCO FLAGS_REG) (const_int 0))
6249 (label_ref (match_operand 3))
6253 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6254 if (CONST_INT_P (operands[2]))
6255 operands[4] = operands[2];
6257 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6260 (define_insn "*subv<mode>4"
6261 [(set (reg:CCO FLAGS_REG)
6262 (eq:CCO (minus:<DWI>
6264 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6266 (match_operand:SWI 2 "<general_sext_operand>"
6269 (minus:SWI (match_dup 1) (match_dup 2)))))
6270 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6271 (minus:SWI (match_dup 1) (match_dup 2)))]
6272 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6273 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6274 [(set_attr "type" "alu")
6275 (set_attr "mode" "<MODE>")])
6277 (define_insn "*subv<mode>4_1"
6278 [(set (reg:CCO FLAGS_REG)
6279 (eq:CCO (minus:<DWI>
6281 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6282 (match_operand:<DWI> 3 "const_int_operand" "i"))
6284 (minus:SWI (match_dup 1)
6285 (match_operand:SWI 2 "x86_64_immediate_operand"
6287 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6288 (minus:SWI (match_dup 1) (match_dup 2)))]
6289 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6290 && CONST_INT_P (operands[2])
6291 && INTVAL (operands[2]) == INTVAL (operands[3])"
6292 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6293 [(set_attr "type" "alu")
6294 (set_attr "mode" "<MODE>")
6295 (set (attr "length_immediate")
6296 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6298 (match_test "<MODE_SIZE> == 8")
6300 (const_string "<MODE_SIZE>")))])
6302 (define_insn "*sub<mode>_3"
6303 [(set (reg FLAGS_REG)
6304 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6305 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6306 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6307 (minus:SWI (match_dup 1) (match_dup 2)))]
6308 "ix86_match_ccmode (insn, CCmode)
6309 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6310 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6311 [(set_attr "type" "alu")
6312 (set_attr "mode" "<MODE>")])
6314 (define_insn "*subsi_3_zext"
6315 [(set (reg FLAGS_REG)
6316 (compare (match_operand:SI 1 "register_operand" "0")
6317 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6318 (set (match_operand:DI 0 "register_operand" "=r")
6320 (minus:SI (match_dup 1)
6322 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6323 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6324 "sub{l}\t{%2, %1|%1, %2}"
6325 [(set_attr "type" "alu")
6326 (set_attr "mode" "SI")])
6328 ;; Add with carry and subtract with borrow
6330 (define_expand "<plusminus_insn><mode>3_carry"
6332 [(set (match_operand:SWI 0 "nonimmediate_operand")
6334 (match_operand:SWI 1 "nonimmediate_operand")
6335 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6336 [(match_operand 3 "flags_reg_operand")
6338 (match_operand:SWI 2 "<general_operand>"))))
6339 (clobber (reg:CC FLAGS_REG))])]
6340 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6342 (define_insn "*<plusminus_insn><mode>3_carry"
6343 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6345 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6347 (match_operator 3 "ix86_carry_flag_operator"
6348 [(reg FLAGS_REG) (const_int 0)])
6349 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6350 (clobber (reg:CC FLAGS_REG))]
6351 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6352 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6353 [(set_attr "type" "alu")
6354 (set_attr "use_carry" "1")
6355 (set_attr "pent_pair" "pu")
6356 (set_attr "mode" "<MODE>")])
6358 (define_insn "*addsi3_carry_zext"
6359 [(set (match_operand:DI 0 "register_operand" "=r")
6361 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6362 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6363 [(reg FLAGS_REG) (const_int 0)])
6364 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6365 (clobber (reg:CC FLAGS_REG))]
6366 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6367 "adc{l}\t{%2, %k0|%k0, %2}"
6368 [(set_attr "type" "alu")
6369 (set_attr "use_carry" "1")
6370 (set_attr "pent_pair" "pu")
6371 (set_attr "mode" "SI")])
6373 (define_insn "*subsi3_carry_zext"
6374 [(set (match_operand:DI 0 "register_operand" "=r")
6376 (minus:SI (match_operand:SI 1 "register_operand" "0")
6377 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6378 [(reg FLAGS_REG) (const_int 0)])
6379 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6380 (clobber (reg:CC FLAGS_REG))]
6381 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6382 "sbb{l}\t{%2, %k0|%k0, %2}"
6383 [(set_attr "type" "alu")
6384 (set_attr "pent_pair" "pu")
6385 (set_attr "mode" "SI")])
6389 (define_insn "adcx<mode>3"
6390 [(set (reg:CCC FLAGS_REG)
6393 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6395 (match_operator 4 "ix86_carry_flag_operator"
6396 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6397 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6399 (set (match_operand:SWI48 0 "register_operand" "=r")
6400 (plus:SWI48 (match_dup 1)
6401 (plus:SWI48 (match_op_dup 4
6402 [(match_dup 3) (const_int 0)])
6404 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6405 "adcx\t{%2, %0|%0, %2}"
6406 [(set_attr "type" "alu")
6407 (set_attr "use_carry" "1")
6408 (set_attr "mode" "<MODE>")])
6410 ;; Overflow setting add instructions
6412 (define_insn "*add<mode>3_cconly_overflow"
6413 [(set (reg:CCC FLAGS_REG)
6416 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6417 (match_operand:SWI 2 "<general_operand>" "<g>"))
6419 (clobber (match_scratch:SWI 0 "=<r>"))]
6420 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6421 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6422 [(set_attr "type" "alu")
6423 (set_attr "mode" "<MODE>")])
6425 (define_insn "*add<mode>3_cc_overflow"
6426 [(set (reg:CCC FLAGS_REG)
6429 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6430 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6432 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6433 (plus:SWI (match_dup 1) (match_dup 2)))]
6434 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6435 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6436 [(set_attr "type" "alu")
6437 (set_attr "mode" "<MODE>")])
6439 (define_insn "*addsi3_zext_cc_overflow"
6440 [(set (reg:CCC FLAGS_REG)
6443 (match_operand:SI 1 "nonimmediate_operand" "%0")
6444 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6446 (set (match_operand:DI 0 "register_operand" "=r")
6447 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6448 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6449 "add{l}\t{%2, %k0|%k0, %2}"
6450 [(set_attr "type" "alu")
6451 (set_attr "mode" "SI")])
6453 ;; The patterns that match these are at the end of this file.
6455 (define_expand "<plusminus_insn>xf3"
6456 [(set (match_operand:XF 0 "register_operand")
6458 (match_operand:XF 1 "register_operand")
6459 (match_operand:XF 2 "register_operand")))]
6462 (define_expand "<plusminus_insn><mode>3"
6463 [(set (match_operand:MODEF 0 "register_operand")
6465 (match_operand:MODEF 1 "register_operand")
6466 (match_operand:MODEF 2 "nonimmediate_operand")))]
6467 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6468 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6470 ;; Multiply instructions
6472 (define_expand "mul<mode>3"
6473 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6475 (match_operand:SWIM248 1 "register_operand")
6476 (match_operand:SWIM248 2 "<general_operand>")))
6477 (clobber (reg:CC FLAGS_REG))])])
6479 (define_expand "mulqi3"
6480 [(parallel [(set (match_operand:QI 0 "register_operand")
6482 (match_operand:QI 1 "register_operand")
6483 (match_operand:QI 2 "nonimmediate_operand")))
6484 (clobber (reg:CC FLAGS_REG))])]
6485 "TARGET_QIMODE_MATH")
6488 ;; IMUL reg32/64, reg32/64, imm8 Direct
6489 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6490 ;; IMUL reg32/64, reg32/64, imm32 Direct
6491 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6492 ;; IMUL reg32/64, reg32/64 Direct
6493 ;; IMUL reg32/64, mem32/64 Direct
6495 ;; On BDVER1, all above IMULs use DirectPath
6497 (define_insn "*mul<mode>3_1"
6498 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6500 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6501 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6502 (clobber (reg:CC FLAGS_REG))]
6503 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6505 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6506 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6507 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6508 [(set_attr "type" "imul")
6509 (set_attr "prefix_0f" "0,0,1")
6510 (set (attr "athlon_decode")
6511 (cond [(eq_attr "cpu" "athlon")
6512 (const_string "vector")
6513 (eq_attr "alternative" "1")
6514 (const_string "vector")
6515 (and (eq_attr "alternative" "2")
6516 (match_operand 1 "memory_operand"))
6517 (const_string "vector")]
6518 (const_string "direct")))
6519 (set (attr "amdfam10_decode")
6520 (cond [(and (eq_attr "alternative" "0,1")
6521 (match_operand 1 "memory_operand"))
6522 (const_string "vector")]
6523 (const_string "direct")))
6524 (set_attr "bdver1_decode" "direct")
6525 (set_attr "mode" "<MODE>")])
6527 (define_insn "*mulsi3_1_zext"
6528 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6530 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6531 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6532 (clobber (reg:CC FLAGS_REG))]
6534 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6536 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6537 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6538 imul{l}\t{%2, %k0|%k0, %2}"
6539 [(set_attr "type" "imul")
6540 (set_attr "prefix_0f" "0,0,1")
6541 (set (attr "athlon_decode")
6542 (cond [(eq_attr "cpu" "athlon")
6543 (const_string "vector")
6544 (eq_attr "alternative" "1")
6545 (const_string "vector")
6546 (and (eq_attr "alternative" "2")
6547 (match_operand 1 "memory_operand"))
6548 (const_string "vector")]
6549 (const_string "direct")))
6550 (set (attr "amdfam10_decode")
6551 (cond [(and (eq_attr "alternative" "0,1")
6552 (match_operand 1 "memory_operand"))
6553 (const_string "vector")]
6554 (const_string "direct")))
6555 (set_attr "bdver1_decode" "direct")
6556 (set_attr "mode" "SI")])
6559 ;; IMUL reg16, reg16, imm8 VectorPath
6560 ;; IMUL reg16, mem16, imm8 VectorPath
6561 ;; IMUL reg16, reg16, imm16 VectorPath
6562 ;; IMUL reg16, mem16, imm16 VectorPath
6563 ;; IMUL reg16, reg16 Direct
6564 ;; IMUL reg16, mem16 Direct
6566 ;; On BDVER1, all HI MULs use DoublePath
6568 (define_insn "*mulhi3_1"
6569 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6570 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6571 (match_operand:HI 2 "general_operand" "K,n,mr")))
6572 (clobber (reg:CC FLAGS_REG))]
6574 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6576 imul{w}\t{%2, %1, %0|%0, %1, %2}
6577 imul{w}\t{%2, %1, %0|%0, %1, %2}
6578 imul{w}\t{%2, %0|%0, %2}"
6579 [(set_attr "type" "imul")
6580 (set_attr "prefix_0f" "0,0,1")
6581 (set (attr "athlon_decode")
6582 (cond [(eq_attr "cpu" "athlon")
6583 (const_string "vector")
6584 (eq_attr "alternative" "1,2")
6585 (const_string "vector")]
6586 (const_string "direct")))
6587 (set (attr "amdfam10_decode")
6588 (cond [(eq_attr "alternative" "0,1")
6589 (const_string "vector")]
6590 (const_string "direct")))
6591 (set_attr "bdver1_decode" "double")
6592 (set_attr "mode" "HI")])
6594 ;;On AMDFAM10 and BDVER1
6598 (define_insn "*mulqi3_1"
6599 [(set (match_operand:QI 0 "register_operand" "=a")
6600 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6601 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6602 (clobber (reg:CC FLAGS_REG))]
6604 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6606 [(set_attr "type" "imul")
6607 (set_attr "length_immediate" "0")
6608 (set (attr "athlon_decode")
6609 (if_then_else (eq_attr "cpu" "athlon")
6610 (const_string "vector")
6611 (const_string "direct")))
6612 (set_attr "amdfam10_decode" "direct")
6613 (set_attr "bdver1_decode" "direct")
6614 (set_attr "mode" "QI")])
6616 ;; Multiply with jump on overflow.
6617 (define_expand "mulv<mode>4"
6618 [(parallel [(set (reg:CCO FLAGS_REG)
6621 (match_operand:SWI48 1 "register_operand"))
6624 (mult:SWI48 (match_dup 1)
6625 (match_operand:SWI48 2
6626 "<general_operand>")))))
6627 (set (match_operand:SWI48 0 "register_operand")
6628 (mult:SWI48 (match_dup 1) (match_dup 2)))])
6629 (set (pc) (if_then_else
6630 (eq (reg:CCO FLAGS_REG) (const_int 0))
6631 (label_ref (match_operand 3))
6635 if (CONST_INT_P (operands[2]))
6636 operands[4] = operands[2];
6638 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6641 (define_insn "*mulv<mode>4"
6642 [(set (reg:CCO FLAGS_REG)
6645 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6647 (match_operand:SWI48 2 "<general_sext_operand>"
6650 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6651 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6652 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6653 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6655 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6656 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6657 [(set_attr "type" "imul")
6658 (set_attr "prefix_0f" "0,1")
6659 (set (attr "athlon_decode")
6660 (cond [(eq_attr "cpu" "athlon")
6661 (const_string "vector")
6662 (eq_attr "alternative" "0")
6663 (const_string "vector")
6664 (and (eq_attr "alternative" "1")
6665 (match_operand 1 "memory_operand"))
6666 (const_string "vector")]
6667 (const_string "direct")))
6668 (set (attr "amdfam10_decode")
6669 (cond [(and (eq_attr "alternative" "1")
6670 (match_operand 1 "memory_operand"))
6671 (const_string "vector")]
6672 (const_string "direct")))
6673 (set_attr "bdver1_decode" "direct")
6674 (set_attr "mode" "<MODE>")])
6676 (define_insn "*mulv<mode>4_1"
6677 [(set (reg:CCO FLAGS_REG)
6680 (match_operand:SWI48 1 "nonimmediate_operand" "rm,rm"))
6681 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
6683 (mult:SWI48 (match_dup 1)
6684 (match_operand:SWI 2 "x86_64_immediate_operand"
6686 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6687 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6688 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
6689 && CONST_INT_P (operands[2])
6690 && INTVAL (operands[2]) == INTVAL (operands[3])"
6692 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6693 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6694 [(set_attr "type" "imul")
6695 (set (attr "athlon_decode")
6696 (cond [(eq_attr "cpu" "athlon")
6697 (const_string "vector")
6698 (eq_attr "alternative" "1")
6699 (const_string "vector")]
6700 (const_string "direct")))
6701 (set (attr "amdfam10_decode")
6702 (cond [(match_operand 1 "memory_operand")
6703 (const_string "vector")]
6704 (const_string "direct")))
6705 (set_attr "bdver1_decode" "direct")
6706 (set_attr "mode" "<MODE>")
6707 (set (attr "length_immediate")
6708 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6710 (match_test "<MODE_SIZE> == 8")
6712 (const_string "<MODE_SIZE>")))])
6714 (define_expand "umulv<mode>4"
6715 [(parallel [(set (reg:CCO FLAGS_REG)
6718 (match_operand:SWI48 1
6719 "nonimmediate_operand"))
6721 (match_operand:SWI48 2
6722 "nonimmediate_operand")))
6724 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6725 (set (match_operand:SWI48 0 "register_operand")
6726 (mult:SWI48 (match_dup 1) (match_dup 2)))
6727 (clobber (match_scratch:SWI48 4))])
6728 (set (pc) (if_then_else
6729 (eq (reg:CCO FLAGS_REG) (const_int 0))
6730 (label_ref (match_operand 3))
6734 if (MEM_P (operands[1]) && MEM_P (operands[2]))
6735 operands[1] = force_reg (<MODE>mode, operands[1]);
6738 (define_insn "*umulv<mode>4"
6739 [(set (reg:CCO FLAGS_REG)
6742 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6744 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6746 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6747 (set (match_operand:SWI48 0 "register_operand" "=a")
6748 (mult:SWI48 (match_dup 1) (match_dup 2)))
6749 (clobber (match_scratch:SWI48 3 "=d"))]
6750 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6751 "mul{<imodesuffix>}\t%2"
6752 [(set_attr "type" "imul")
6753 (set_attr "length_immediate" "0")
6754 (set (attr "athlon_decode")
6755 (if_then_else (eq_attr "cpu" "athlon")
6756 (const_string "vector")
6757 (const_string "double")))
6758 (set_attr "amdfam10_decode" "double")
6759 (set_attr "bdver1_decode" "direct")
6760 (set_attr "mode" "<MODE>")])
6762 (define_expand "<u>mulvqi4"
6763 [(parallel [(set (reg:CCO FLAGS_REG)
6766 (match_operand:QI 1 "nonimmediate_operand"))
6768 (match_operand:QI 2 "nonimmediate_operand")))
6770 (mult:QI (match_dup 1) (match_dup 2)))))
6771 (set (match_operand:QI 0 "register_operand")
6772 (mult:QI (match_dup 1) (match_dup 2)))])
6773 (set (pc) (if_then_else
6774 (eq (reg:CCO FLAGS_REG) (const_int 0))
6775 (label_ref (match_operand 3))
6777 "TARGET_QIMODE_MATH"
6779 if (MEM_P (operands[1]) && MEM_P (operands[2]))
6780 operands[1] = force_reg (QImode, operands[1]);
6783 (define_insn "*<u>mulvqi4"
6784 [(set (reg:CCO FLAGS_REG)
6787 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6789 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6791 (mult:QI (match_dup 1) (match_dup 2)))))
6792 (set (match_operand:QI 0 "register_operand" "=a")
6793 (mult:QI (match_dup 1) (match_dup 2)))]
6795 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6796 "<sgnprefix>mul{b}\t%2"
6797 [(set_attr "type" "imul")
6798 (set_attr "length_immediate" "0")
6799 (set (attr "athlon_decode")
6800 (if_then_else (eq_attr "cpu" "athlon")
6801 (const_string "vector")
6802 (const_string "direct")))
6803 (set_attr "amdfam10_decode" "direct")
6804 (set_attr "bdver1_decode" "direct")
6805 (set_attr "mode" "QI")])
6807 (define_expand "<u>mul<mode><dwi>3"
6808 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6811 (match_operand:DWIH 1 "nonimmediate_operand"))
6813 (match_operand:DWIH 2 "register_operand"))))
6814 (clobber (reg:CC FLAGS_REG))])])
6816 (define_expand "<u>mulqihi3"
6817 [(parallel [(set (match_operand:HI 0 "register_operand")
6820 (match_operand:QI 1 "nonimmediate_operand"))
6822 (match_operand:QI 2 "register_operand"))))
6823 (clobber (reg:CC FLAGS_REG))])]
6824 "TARGET_QIMODE_MATH")
6826 (define_insn "*bmi2_umulditi3_1"
6827 [(set (match_operand:DI 0 "register_operand" "=r")
6829 (match_operand:DI 2 "nonimmediate_operand" "%d")
6830 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6831 (set (match_operand:DI 1 "register_operand" "=r")
6834 (mult:TI (zero_extend:TI (match_dup 2))
6835 (zero_extend:TI (match_dup 3)))
6837 "TARGET_64BIT && TARGET_BMI2
6838 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6839 "mulx\t{%3, %0, %1|%1, %0, %3}"
6840 [(set_attr "type" "imulx")
6841 (set_attr "prefix" "vex")
6842 (set_attr "mode" "DI")])
6844 (define_insn "*bmi2_umulsidi3_1"
6845 [(set (match_operand:SI 0 "register_operand" "=r")
6847 (match_operand:SI 2 "nonimmediate_operand" "%d")
6848 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6849 (set (match_operand:SI 1 "register_operand" "=r")
6852 (mult:DI (zero_extend:DI (match_dup 2))
6853 (zero_extend:DI (match_dup 3)))
6855 "!TARGET_64BIT && TARGET_BMI2
6856 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6857 "mulx\t{%3, %0, %1|%1, %0, %3}"
6858 [(set_attr "type" "imulx")
6859 (set_attr "prefix" "vex")
6860 (set_attr "mode" "SI")])
6862 (define_insn "*umul<mode><dwi>3_1"
6863 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6866 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6868 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6869 (clobber (reg:CC FLAGS_REG))]
6870 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6873 mul{<imodesuffix>}\t%2"
6874 [(set_attr "isa" "bmi2,*")
6875 (set_attr "type" "imulx,imul")
6876 (set_attr "length_immediate" "*,0")
6877 (set (attr "athlon_decode")
6878 (cond [(eq_attr "alternative" "1")
6879 (if_then_else (eq_attr "cpu" "athlon")
6880 (const_string "vector")
6881 (const_string "double"))]
6882 (const_string "*")))
6883 (set_attr "amdfam10_decode" "*,double")
6884 (set_attr "bdver1_decode" "*,direct")
6885 (set_attr "prefix" "vex,orig")
6886 (set_attr "mode" "<MODE>")])
6888 ;; Convert mul to the mulx pattern to avoid flags dependency.
6890 [(set (match_operand:<DWI> 0 "register_operand")
6893 (match_operand:DWIH 1 "register_operand"))
6895 (match_operand:DWIH 2 "nonimmediate_operand"))))
6896 (clobber (reg:CC FLAGS_REG))]
6897 "TARGET_BMI2 && reload_completed
6898 && true_regnum (operands[1]) == DX_REG"
6899 [(parallel [(set (match_dup 3)
6900 (mult:DWIH (match_dup 1) (match_dup 2)))
6904 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6905 (zero_extend:<DWI> (match_dup 2)))
6908 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6910 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6913 (define_insn "*mul<mode><dwi>3_1"
6914 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6917 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6919 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6920 (clobber (reg:CC FLAGS_REG))]
6921 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6922 "imul{<imodesuffix>}\t%2"
6923 [(set_attr "type" "imul")
6924 (set_attr "length_immediate" "0")
6925 (set (attr "athlon_decode")
6926 (if_then_else (eq_attr "cpu" "athlon")
6927 (const_string "vector")
6928 (const_string "double")))
6929 (set_attr "amdfam10_decode" "double")
6930 (set_attr "bdver1_decode" "direct")
6931 (set_attr "mode" "<MODE>")])
6933 (define_insn "*<u>mulqihi3_1"
6934 [(set (match_operand:HI 0 "register_operand" "=a")
6937 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6939 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6940 (clobber (reg:CC FLAGS_REG))]
6942 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6943 "<sgnprefix>mul{b}\t%2"
6944 [(set_attr "type" "imul")
6945 (set_attr "length_immediate" "0")
6946 (set (attr "athlon_decode")
6947 (if_then_else (eq_attr "cpu" "athlon")
6948 (const_string "vector")
6949 (const_string "direct")))
6950 (set_attr "amdfam10_decode" "direct")
6951 (set_attr "bdver1_decode" "direct")
6952 (set_attr "mode" "QI")])
6954 (define_expand "<s>mul<mode>3_highpart"
6955 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6960 (match_operand:SWI48 1 "nonimmediate_operand"))
6962 (match_operand:SWI48 2 "register_operand")))
6964 (clobber (match_scratch:SWI48 3))
6965 (clobber (reg:CC FLAGS_REG))])]
6967 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6969 (define_insn "*<s>muldi3_highpart_1"
6970 [(set (match_operand:DI 0 "register_operand" "=d")
6975 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6977 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6979 (clobber (match_scratch:DI 3 "=1"))
6980 (clobber (reg:CC FLAGS_REG))]
6982 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6983 "<sgnprefix>mul{q}\t%2"
6984 [(set_attr "type" "imul")
6985 (set_attr "length_immediate" "0")
6986 (set (attr "athlon_decode")
6987 (if_then_else (eq_attr "cpu" "athlon")
6988 (const_string "vector")
6989 (const_string "double")))
6990 (set_attr "amdfam10_decode" "double")
6991 (set_attr "bdver1_decode" "direct")
6992 (set_attr "mode" "DI")])
6994 (define_insn "*<s>mulsi3_highpart_1"
6995 [(set (match_operand:SI 0 "register_operand" "=d")
7000 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7002 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7004 (clobber (match_scratch:SI 3 "=1"))
7005 (clobber (reg:CC FLAGS_REG))]
7006 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7007 "<sgnprefix>mul{l}\t%2"
7008 [(set_attr "type" "imul")
7009 (set_attr "length_immediate" "0")
7010 (set (attr "athlon_decode")
7011 (if_then_else (eq_attr "cpu" "athlon")
7012 (const_string "vector")
7013 (const_string "double")))
7014 (set_attr "amdfam10_decode" "double")
7015 (set_attr "bdver1_decode" "direct")
7016 (set_attr "mode" "SI")])
7018 (define_insn "*<s>mulsi3_highpart_zext"
7019 [(set (match_operand:DI 0 "register_operand" "=d")
7020 (zero_extend:DI (truncate:SI
7022 (mult:DI (any_extend:DI
7023 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7025 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7027 (clobber (match_scratch:SI 3 "=1"))
7028 (clobber (reg:CC FLAGS_REG))]
7030 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7031 "<sgnprefix>mul{l}\t%2"
7032 [(set_attr "type" "imul")
7033 (set_attr "length_immediate" "0")
7034 (set (attr "athlon_decode")
7035 (if_then_else (eq_attr "cpu" "athlon")
7036 (const_string "vector")
7037 (const_string "double")))
7038 (set_attr "amdfam10_decode" "double")
7039 (set_attr "bdver1_decode" "direct")
7040 (set_attr "mode" "SI")])
7042 ;; The patterns that match these are at the end of this file.
7044 (define_expand "mulxf3"
7045 [(set (match_operand:XF 0 "register_operand")
7046 (mult:XF (match_operand:XF 1 "register_operand")
7047 (match_operand:XF 2 "register_operand")))]
7050 (define_expand "mul<mode>3"
7051 [(set (match_operand:MODEF 0 "register_operand")
7052 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7053 (match_operand:MODEF 2 "nonimmediate_operand")))]
7054 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7055 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7057 ;; Divide instructions
7059 ;; The patterns that match these are at the end of this file.
7061 (define_expand "divxf3"
7062 [(set (match_operand:XF 0 "register_operand")
7063 (div:XF (match_operand:XF 1 "register_operand")
7064 (match_operand:XF 2 "register_operand")))]
7067 (define_expand "divdf3"
7068 [(set (match_operand:DF 0 "register_operand")
7069 (div:DF (match_operand:DF 1 "register_operand")
7070 (match_operand:DF 2 "nonimmediate_operand")))]
7071 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7072 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7074 (define_expand "divsf3"
7075 [(set (match_operand:SF 0 "register_operand")
7076 (div:SF (match_operand:SF 1 "register_operand")
7077 (match_operand:SF 2 "nonimmediate_operand")))]
7078 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7083 && optimize_insn_for_speed_p ()
7084 && flag_finite_math_only && !flag_trapping_math
7085 && flag_unsafe_math_optimizations)
7087 ix86_emit_swdivsf (operands[0], operands[1],
7088 operands[2], SFmode);
7093 ;; Divmod instructions.
7095 (define_expand "divmod<mode>4"
7096 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7098 (match_operand:SWIM248 1 "register_operand")
7099 (match_operand:SWIM248 2 "nonimmediate_operand")))
7100 (set (match_operand:SWIM248 3 "register_operand")
7101 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7102 (clobber (reg:CC FLAGS_REG))])])
7104 ;; Split with 8bit unsigned divide:
7105 ;; if (dividend an divisor are in [0-255])
7106 ;; use 8bit unsigned integer divide
7108 ;; use original integer divide
7110 [(set (match_operand:SWI48 0 "register_operand")
7111 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7112 (match_operand:SWI48 3 "nonimmediate_operand")))
7113 (set (match_operand:SWI48 1 "register_operand")
7114 (mod:SWI48 (match_dup 2) (match_dup 3)))
7115 (clobber (reg:CC FLAGS_REG))]
7116 "TARGET_USE_8BIT_IDIV
7117 && TARGET_QIMODE_MATH
7118 && can_create_pseudo_p ()
7119 && !optimize_insn_for_size_p ()"
7121 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7123 (define_insn_and_split "divmod<mode>4_1"
7124 [(set (match_operand:SWI48 0 "register_operand" "=a")
7125 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7126 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7127 (set (match_operand:SWI48 1 "register_operand" "=&d")
7128 (mod:SWI48 (match_dup 2) (match_dup 3)))
7129 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7130 (clobber (reg:CC FLAGS_REG))]
7134 [(parallel [(set (match_dup 1)
7135 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7136 (clobber (reg:CC FLAGS_REG))])
7137 (parallel [(set (match_dup 0)
7138 (div:SWI48 (match_dup 2) (match_dup 3)))
7140 (mod:SWI48 (match_dup 2) (match_dup 3)))
7142 (clobber (reg:CC FLAGS_REG))])]
7144 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7146 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7147 operands[4] = operands[2];
7150 /* Avoid use of cltd in favor of a mov+shift. */
7151 emit_move_insn (operands[1], operands[2]);
7152 operands[4] = operands[1];
7155 [(set_attr "type" "multi")
7156 (set_attr "mode" "<MODE>")])
7158 (define_insn_and_split "*divmod<mode>4"
7159 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7160 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7161 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7162 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7163 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7164 (clobber (reg:CC FLAGS_REG))]
7168 [(parallel [(set (match_dup 1)
7169 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7170 (clobber (reg:CC FLAGS_REG))])
7171 (parallel [(set (match_dup 0)
7172 (div:SWIM248 (match_dup 2) (match_dup 3)))
7174 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7176 (clobber (reg:CC FLAGS_REG))])]
7178 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7180 if (<MODE>mode != HImode
7181 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7182 operands[4] = operands[2];
7185 /* Avoid use of cltd in favor of a mov+shift. */
7186 emit_move_insn (operands[1], operands[2]);
7187 operands[4] = operands[1];
7190 [(set_attr "type" "multi")
7191 (set_attr "mode" "<MODE>")])
7193 (define_insn "*divmod<mode>4_noext"
7194 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7195 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7196 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7197 (set (match_operand:SWIM248 1 "register_operand" "=d")
7198 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7199 (use (match_operand:SWIM248 4 "register_operand" "1"))
7200 (clobber (reg:CC FLAGS_REG))]
7202 "idiv{<imodesuffix>}\t%3"
7203 [(set_attr "type" "idiv")
7204 (set_attr "mode" "<MODE>")])
7206 (define_expand "divmodqi4"
7207 [(parallel [(set (match_operand:QI 0 "register_operand")
7209 (match_operand:QI 1 "register_operand")
7210 (match_operand:QI 2 "nonimmediate_operand")))
7211 (set (match_operand:QI 3 "register_operand")
7212 (mod:QI (match_dup 1) (match_dup 2)))
7213 (clobber (reg:CC FLAGS_REG))])]
7214 "TARGET_QIMODE_MATH"
7219 tmp0 = gen_reg_rtx (HImode);
7220 tmp1 = gen_reg_rtx (HImode);
7222 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7224 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7225 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7227 /* Extract remainder from AH. */
7228 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7229 insn = emit_move_insn (operands[3], tmp1);
7231 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7232 set_unique_reg_note (insn, REG_EQUAL, mod);
7234 /* Extract quotient from AL. */
7235 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7237 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7238 set_unique_reg_note (insn, REG_EQUAL, div);
7243 ;; Divide AX by r/m8, with result stored in
7246 ;; Change div/mod to HImode and extend the second argument to HImode
7247 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7248 ;; combine may fail.
7249 (define_insn "divmodhiqi3"
7250 [(set (match_operand:HI 0 "register_operand" "=a")
7255 (mod:HI (match_operand:HI 1 "register_operand" "0")
7257 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7261 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7262 (clobber (reg:CC FLAGS_REG))]
7263 "TARGET_QIMODE_MATH"
7265 [(set_attr "type" "idiv")
7266 (set_attr "mode" "QI")])
7268 (define_expand "udivmod<mode>4"
7269 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7271 (match_operand:SWIM248 1 "register_operand")
7272 (match_operand:SWIM248 2 "nonimmediate_operand")))
7273 (set (match_operand:SWIM248 3 "register_operand")
7274 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7275 (clobber (reg:CC FLAGS_REG))])])
7277 ;; Split with 8bit unsigned divide:
7278 ;; if (dividend an divisor are in [0-255])
7279 ;; use 8bit unsigned integer divide
7281 ;; use original integer divide
7283 [(set (match_operand:SWI48 0 "register_operand")
7284 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7285 (match_operand:SWI48 3 "nonimmediate_operand")))
7286 (set (match_operand:SWI48 1 "register_operand")
7287 (umod:SWI48 (match_dup 2) (match_dup 3)))
7288 (clobber (reg:CC FLAGS_REG))]
7289 "TARGET_USE_8BIT_IDIV
7290 && TARGET_QIMODE_MATH
7291 && can_create_pseudo_p ()
7292 && !optimize_insn_for_size_p ()"
7294 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7296 (define_insn_and_split "udivmod<mode>4_1"
7297 [(set (match_operand:SWI48 0 "register_operand" "=a")
7298 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7299 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7300 (set (match_operand:SWI48 1 "register_operand" "=&d")
7301 (umod:SWI48 (match_dup 2) (match_dup 3)))
7302 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7303 (clobber (reg:CC FLAGS_REG))]
7307 [(set (match_dup 1) (const_int 0))
7308 (parallel [(set (match_dup 0)
7309 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7311 (umod:SWI48 (match_dup 2) (match_dup 3)))
7313 (clobber (reg:CC FLAGS_REG))])]
7315 [(set_attr "type" "multi")
7316 (set_attr "mode" "<MODE>")])
7318 (define_insn_and_split "*udivmod<mode>4"
7319 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7320 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7321 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7322 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7323 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7324 (clobber (reg:CC FLAGS_REG))]
7328 [(set (match_dup 1) (const_int 0))
7329 (parallel [(set (match_dup 0)
7330 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7332 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7334 (clobber (reg:CC FLAGS_REG))])]
7336 [(set_attr "type" "multi")
7337 (set_attr "mode" "<MODE>")])
7339 ;; Optimize division or modulo by constant power of 2, if the constant
7340 ;; materializes only after expansion.
7341 (define_insn_and_split "*udivmod<mode>4_pow2"
7342 [(set (match_operand:SWI48 0 "register_operand" "=r")
7343 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7344 (match_operand:SWI48 3 "const_int_operand" "n")))
7345 (set (match_operand:SWI48 1 "register_operand" "=r")
7346 (umod:SWI48 (match_dup 2) (match_dup 3)))
7347 (clobber (reg:CC FLAGS_REG))]
7348 "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
7349 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
7352 [(set (match_dup 1) (match_dup 2))
7353 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7354 (clobber (reg:CC FLAGS_REG))])
7355 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7356 (clobber (reg:CC FLAGS_REG))])]
7358 int v = exact_log2 (UINTVAL (operands[3]));
7359 operands[4] = GEN_INT (v);
7360 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7362 [(set_attr "type" "multi")
7363 (set_attr "mode" "<MODE>")])
7365 (define_insn "*udivmod<mode>4_noext"
7366 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7367 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7368 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7369 (set (match_operand:SWIM248 1 "register_operand" "=d")
7370 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7371 (use (match_operand:SWIM248 4 "register_operand" "1"))
7372 (clobber (reg:CC FLAGS_REG))]
7374 "div{<imodesuffix>}\t%3"
7375 [(set_attr "type" "idiv")
7376 (set_attr "mode" "<MODE>")])
7378 (define_expand "udivmodqi4"
7379 [(parallel [(set (match_operand:QI 0 "register_operand")
7381 (match_operand:QI 1 "register_operand")
7382 (match_operand:QI 2 "nonimmediate_operand")))
7383 (set (match_operand:QI 3 "register_operand")
7384 (umod:QI (match_dup 1) (match_dup 2)))
7385 (clobber (reg:CC FLAGS_REG))])]
7386 "TARGET_QIMODE_MATH"
7391 tmp0 = gen_reg_rtx (HImode);
7392 tmp1 = gen_reg_rtx (HImode);
7394 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7396 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7397 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7399 /* Extract remainder from AH. */
7400 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7401 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7402 insn = emit_move_insn (operands[3], tmp1);
7404 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7405 set_unique_reg_note (insn, REG_EQUAL, mod);
7407 /* Extract quotient from AL. */
7408 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7410 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7411 set_unique_reg_note (insn, REG_EQUAL, div);
7416 (define_insn "udivmodhiqi3"
7417 [(set (match_operand:HI 0 "register_operand" "=a")
7422 (mod:HI (match_operand:HI 1 "register_operand" "0")
7424 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7428 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7429 (clobber (reg:CC FLAGS_REG))]
7430 "TARGET_QIMODE_MATH"
7432 [(set_attr "type" "idiv")
7433 (set_attr "mode" "QI")])
7435 ;; We cannot use div/idiv for double division, because it causes
7436 ;; "division by zero" on the overflow and that's not what we expect
7437 ;; from truncate. Because true (non truncating) double division is
7438 ;; never generated, we can't create this insn anyway.
7441 ; [(set (match_operand:SI 0 "register_operand" "=a")
7443 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7445 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7446 ; (set (match_operand:SI 3 "register_operand" "=d")
7448 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7449 ; (clobber (reg:CC FLAGS_REG))]
7451 ; "div{l}\t{%2, %0|%0, %2}"
7452 ; [(set_attr "type" "idiv")])
7454 ;;- Logical AND instructions
7456 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7457 ;; Note that this excludes ah.
7459 (define_expand "testsi_ccno_1"
7460 [(set (reg:CCNO FLAGS_REG)
7462 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7463 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7466 (define_expand "testqi_ccz_1"
7467 [(set (reg:CCZ FLAGS_REG)
7468 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7469 (match_operand:QI 1 "nonmemory_operand"))
7472 (define_expand "testdi_ccno_1"
7473 [(set (reg:CCNO FLAGS_REG)
7475 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7476 (match_operand:DI 1 "x86_64_szext_general_operand"))
7478 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7480 (define_insn "*testdi_1"
7481 [(set (reg FLAGS_REG)
7484 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7485 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7487 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7488 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7490 test{l}\t{%k1, %k0|%k0, %k1}
7491 test{l}\t{%k1, %k0|%k0, %k1}
7492 test{q}\t{%1, %0|%0, %1}
7493 test{q}\t{%1, %0|%0, %1}
7494 test{q}\t{%1, %0|%0, %1}"
7495 [(set_attr "type" "test")
7496 (set_attr "modrm" "0,1,0,1,1")
7497 (set_attr "mode" "SI,SI,DI,DI,DI")])
7499 (define_insn "*testqi_1_maybe_si"
7500 [(set (reg FLAGS_REG)
7503 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7504 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7506 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7507 && ix86_match_ccmode (insn,
7508 CONST_INT_P (operands[1])
7509 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7511 if (which_alternative == 3)
7513 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7514 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7515 return "test{l}\t{%1, %k0|%k0, %1}";
7517 return "test{b}\t{%1, %0|%0, %1}";
7519 [(set_attr "type" "test")
7520 (set_attr "modrm" "0,1,1,1")
7521 (set_attr "mode" "QI,QI,QI,SI")
7522 (set_attr "pent_pair" "uv,np,uv,np")])
7524 (define_insn "*test<mode>_1"
7525 [(set (reg FLAGS_REG)
7528 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7529 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7531 "ix86_match_ccmode (insn, CCNOmode)
7532 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7533 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7534 [(set_attr "type" "test")
7535 (set_attr "modrm" "0,1,1")
7536 (set_attr "mode" "<MODE>")
7537 (set_attr "pent_pair" "uv,np,uv")])
7539 (define_expand "testqi_ext_ccno_0"
7540 [(set (reg:CCNO FLAGS_REG)
7544 (match_operand 0 "ext_register_operand")
7547 (match_operand 1 "const_int_operand"))
7550 (define_insn "*testqi_ext_0"
7551 [(set (reg FLAGS_REG)
7555 (match_operand 0 "ext_register_operand" "Q")
7558 (match_operand 1 "const_int_operand" "n"))
7560 "ix86_match_ccmode (insn, CCNOmode)"
7561 "test{b}\t{%1, %h0|%h0, %1}"
7562 [(set_attr "type" "test")
7563 (set_attr "mode" "QI")
7564 (set_attr "length_immediate" "1")
7565 (set_attr "modrm" "1")
7566 (set_attr "pent_pair" "np")])
7568 (define_insn "*testqi_ext_1"
7569 [(set (reg FLAGS_REG)
7573 (match_operand 0 "ext_register_operand" "Q,Q")
7577 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7579 "ix86_match_ccmode (insn, CCNOmode)"
7580 "test{b}\t{%1, %h0|%h0, %1}"
7581 [(set_attr "isa" "*,nox64")
7582 (set_attr "type" "test")
7583 (set_attr "mode" "QI")])
7585 (define_insn "*testqi_ext_2"
7586 [(set (reg FLAGS_REG)
7590 (match_operand 0 "ext_register_operand" "Q")
7594 (match_operand 1 "ext_register_operand" "Q")
7598 "ix86_match_ccmode (insn, CCNOmode)"
7599 "test{b}\t{%h1, %h0|%h0, %h1}"
7600 [(set_attr "type" "test")
7601 (set_attr "mode" "QI")])
7603 ;; Combine likes to form bit extractions for some tests. Humor it.
7604 (define_insn "*testqi_ext_3"
7605 [(set (reg FLAGS_REG)
7606 (compare (zero_extract:SWI48
7607 (match_operand 0 "nonimmediate_operand" "rm")
7608 (match_operand:SWI48 1 "const_int_operand")
7609 (match_operand:SWI48 2 "const_int_operand"))
7611 "ix86_match_ccmode (insn, CCNOmode)
7612 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7613 || GET_MODE (operands[0]) == SImode
7614 || GET_MODE (operands[0]) == HImode
7615 || GET_MODE (operands[0]) == QImode)
7616 /* Ensure that resulting mask is zero or sign extended operand. */
7617 && INTVAL (operands[2]) >= 0
7618 && ((INTVAL (operands[1]) > 0
7619 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7620 || (<MODE>mode == DImode
7621 && INTVAL (operands[1]) > 32
7622 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7626 [(set (match_operand 0 "flags_reg_operand")
7627 (match_operator 1 "compare_operator"
7629 (match_operand 2 "nonimmediate_operand")
7630 (match_operand 3 "const_int_operand")
7631 (match_operand 4 "const_int_operand"))
7633 "ix86_match_ccmode (insn, CCNOmode)"
7634 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7636 rtx val = operands[2];
7637 HOST_WIDE_INT len = INTVAL (operands[3]);
7638 HOST_WIDE_INT pos = INTVAL (operands[4]);
7640 machine_mode mode, submode;
7642 mode = GET_MODE (val);
7645 /* ??? Combine likes to put non-volatile mem extractions in QImode
7646 no matter the size of the test. So find a mode that works. */
7647 if (! MEM_VOLATILE_P (val))
7649 mode = smallest_mode_for_size (pos + len, MODE_INT);
7650 val = adjust_address (val, mode, 0);
7653 else if (GET_CODE (val) == SUBREG
7654 && (submode = GET_MODE (SUBREG_REG (val)),
7655 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7656 && pos + len <= GET_MODE_BITSIZE (submode)
7657 && GET_MODE_CLASS (submode) == MODE_INT)
7659 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7661 val = SUBREG_REG (val);
7663 else if (mode == HImode && pos + len <= 8)
7665 /* Small HImode tests can be converted to QImode. */
7667 val = gen_lowpart (QImode, val);
7670 if (len == HOST_BITS_PER_WIDE_INT)
7673 mask = ((HOST_WIDE_INT)1 << len) - 1;
7676 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7679 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7680 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7681 ;; this is relatively important trick.
7682 ;; Do the conversion only post-reload to avoid limiting of the register class
7685 [(set (match_operand 0 "flags_reg_operand")
7686 (match_operator 1 "compare_operator"
7687 [(and (match_operand 2 "register_operand")
7688 (match_operand 3 "const_int_operand"))
7691 && QI_REG_P (operands[2])
7692 && GET_MODE (operands[2]) != QImode
7693 && ((ix86_match_ccmode (insn, CCZmode)
7694 && !(INTVAL (operands[3]) & ~(255 << 8)))
7695 || (ix86_match_ccmode (insn, CCNOmode)
7696 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7699 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7703 operands[2] = gen_lowpart (SImode, operands[2]);
7704 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7708 [(set (match_operand 0 "flags_reg_operand")
7709 (match_operator 1 "compare_operator"
7710 [(and (match_operand 2 "nonimmediate_operand")
7711 (match_operand 3 "const_int_operand"))
7714 && GET_MODE (operands[2]) != QImode
7715 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7716 && ((ix86_match_ccmode (insn, CCZmode)
7717 && !(INTVAL (operands[3]) & ~255))
7718 || (ix86_match_ccmode (insn, CCNOmode)
7719 && !(INTVAL (operands[3]) & ~127)))"
7721 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7724 operands[2] = gen_lowpart (QImode, operands[2]);
7725 operands[3] = gen_lowpart (QImode, operands[3]);
7729 [(set (match_operand:SWI1248x 0 "mask_reg_operand")
7730 (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
7731 (match_operand:SWI1248x 2 "mask_reg_operand")))
7732 (clobber (reg:CC FLAGS_REG))]
7733 "TARGET_AVX512F && reload_completed"
7735 (any_logic:SWI1248x (match_dup 1)
7738 (define_insn "*k<logic><mode>"
7739 [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
7740 (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
7741 (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
7744 if (!TARGET_AVX512DQ && <MODE>mode == QImode)
7745 return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7747 return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
7749 [(set_attr "mode" "<MODE>")
7750 (set_attr "type" "msklog")
7751 (set_attr "prefix" "vex")])
7753 ;; %%% This used to optimize known byte-wide and operations to memory,
7754 ;; and sometimes to QImode registers. If this is considered useful,
7755 ;; it should be done with splitters.
7757 (define_expand "and<mode>3"
7758 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7759 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7760 (match_operand:SWIM 2 "<general_szext_operand>")))]
7763 machine_mode mode = <MODE>mode;
7764 rtx (*insn) (rtx, rtx);
7766 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7768 HOST_WIDE_INT ival = INTVAL (operands[2]);
7770 if (ival == (HOST_WIDE_INT) 0xffffffff)
7772 else if (ival == 0xffff)
7774 else if (ival == 0xff)
7778 if (mode == <MODE>mode)
7780 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7784 if (<MODE>mode == DImode)
7785 insn = (mode == SImode)
7786 ? gen_zero_extendsidi2
7788 ? gen_zero_extendhidi2
7789 : gen_zero_extendqidi2;
7790 else if (<MODE>mode == SImode)
7791 insn = (mode == HImode)
7792 ? gen_zero_extendhisi2
7793 : gen_zero_extendqisi2;
7794 else if (<MODE>mode == HImode)
7795 insn = gen_zero_extendqihi2;
7799 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7803 (define_insn "*anddi_1"
7804 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
7806 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
7807 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
7808 (clobber (reg:CC FLAGS_REG))]
7809 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7811 switch (get_attr_type (insn))
7817 return "kandq\t{%2, %1, %0|%0, %1, %2}";
7820 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7821 if (get_attr_mode (insn) == MODE_SI)
7822 return "and{l}\t{%k2, %k0|%k0, %k2}";
7824 return "and{q}\t{%2, %0|%0, %2}";
7827 [(set_attr "type" "alu,alu,alu,imovx,msklog")
7828 (set_attr "length_immediate" "*,*,*,0,0")
7829 (set (attr "prefix_rex")
7831 (and (eq_attr "type" "imovx")
7832 (and (match_test "INTVAL (operands[2]) == 0xff")
7833 (match_operand 1 "ext_QIreg_operand")))
7835 (const_string "*")))
7836 (set_attr "mode" "SI,DI,DI,SI,DI")])
7838 (define_insn "*andsi_1"
7839 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7840 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
7841 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
7842 (clobber (reg:CC FLAGS_REG))]
7843 "ix86_binary_operator_ok (AND, SImode, operands)"
7845 switch (get_attr_type (insn))
7851 return "kandd\t{%2, %1, %0|%0, %1, %2}";
7854 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7855 return "and{l}\t{%2, %0|%0, %2}";
7858 [(set_attr "type" "alu,alu,imovx,msklog")
7859 (set (attr "prefix_rex")
7861 (and (eq_attr "type" "imovx")
7862 (and (match_test "INTVAL (operands[2]) == 0xff")
7863 (match_operand 1 "ext_QIreg_operand")))
7865 (const_string "*")))
7866 (set_attr "length_immediate" "*,*,0,0")
7867 (set_attr "mode" "SI")])
7869 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7870 (define_insn "*andsi_1_zext"
7871 [(set (match_operand:DI 0 "register_operand" "=r")
7873 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7874 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7875 (clobber (reg:CC FLAGS_REG))]
7876 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7877 "and{l}\t{%2, %k0|%k0, %2}"
7878 [(set_attr "type" "alu")
7879 (set_attr "mode" "SI")])
7881 (define_insn "*andhi_1"
7882 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7883 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
7884 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
7885 (clobber (reg:CC FLAGS_REG))]
7886 "ix86_binary_operator_ok (AND, HImode, operands)"
7888 switch (get_attr_type (insn))
7894 return "kandw\t{%2, %1, %0|%0, %1, %2}";
7897 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7898 return "and{w}\t{%2, %0|%0, %2}";
7901 [(set_attr "type" "alu,alu,imovx,msklog")
7902 (set_attr "length_immediate" "*,*,0,*")
7903 (set (attr "prefix_rex")
7905 (and (eq_attr "type" "imovx")
7906 (match_operand 1 "ext_QIreg_operand"))
7908 (const_string "*")))
7909 (set_attr "mode" "HI,HI,SI,HI")])
7911 ;; %%% Potential partial reg stall on alternative 2. What to do?
7912 (define_insn "*andqi_1"
7913 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
7914 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
7915 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
7916 (clobber (reg:CC FLAGS_REG))]
7917 "ix86_binary_operator_ok (AND, QImode, operands)"
7919 switch (which_alternative)
7923 return "and{b}\t{%2, %0|%0, %2}";
7925 return "and{l}\t{%k2, %k0|%k0, %k2}";
7927 return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
7928 : "kandw\t{%2, %1, %0|%0, %1, %2}";
7933 [(set_attr "type" "alu,alu,alu,msklog")
7934 (set_attr "mode" "QI,QI,SI,HI")])
7936 (define_insn "*andqi_1_slp"
7937 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7938 (and:QI (match_dup 0)
7939 (match_operand:QI 1 "general_operand" "qn,qmn")))
7940 (clobber (reg:CC FLAGS_REG))]
7941 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7942 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7943 "and{b}\t{%1, %0|%0, %1}"
7944 [(set_attr "type" "alu1")
7945 (set_attr "mode" "QI")])
7947 (define_insn "kandn<mode>"
7948 [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
7951 (match_operand:SWI12 1 "register_operand" "r,0,k"))
7952 (match_operand:SWI12 2 "register_operand" "r,r,k")))
7953 (clobber (reg:CC FLAGS_REG))]
7956 switch (which_alternative)
7959 return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
7963 if (TARGET_AVX512DQ && <MODE>mode == QImode)
7964 return "kandnb\t{%2, %1, %0|%0, %1, %2}";
7966 return "kandnw\t{%2, %1, %0|%0, %1, %2}";
7971 [(set_attr "isa" "bmi,*,avx512f")
7972 (set_attr "type" "bitmanip,*,msklog")
7973 (set_attr "prefix" "*,*,vex")
7974 (set_attr "btver2_decode" "direct,*,*")
7975 (set_attr "mode" "<MODE>")])
7978 [(set (match_operand:SWI12 0 "general_reg_operand")
7982 (match_operand:SWI12 1 "general_reg_operand")))
7983 (clobber (reg:CC FLAGS_REG))]
7984 "TARGET_AVX512F && !TARGET_BMI && reload_completed"
7986 (not:HI (match_dup 0)))
7987 (parallel [(set (match_dup 0)
7988 (and:HI (match_dup 0)
7990 (clobber (reg:CC FLAGS_REG))])])
7992 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7994 [(set (match_operand:DI 0 "register_operand")
7995 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7996 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7997 (clobber (reg:CC FLAGS_REG))]
7999 [(parallel [(set (match_dup 0)
8000 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8001 (clobber (reg:CC FLAGS_REG))])]
8002 "operands[2] = gen_lowpart (SImode, operands[2]);")
8005 [(set (match_operand:SWI248 0 "register_operand")
8006 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8007 (match_operand:SWI248 2 "const_int_operand")))
8008 (clobber (reg:CC FLAGS_REG))]
8010 && true_regnum (operands[0]) != true_regnum (operands[1])"
8013 HOST_WIDE_INT ival = INTVAL (operands[2]);
8015 rtx (*insn) (rtx, rtx);
8017 if (ival == (HOST_WIDE_INT) 0xffffffff)
8019 else if (ival == 0xffff)
8023 gcc_assert (ival == 0xff);
8027 if (<MODE>mode == DImode)
8028 insn = (mode == SImode)
8029 ? gen_zero_extendsidi2
8031 ? gen_zero_extendhidi2
8032 : gen_zero_extendqidi2;
8035 if (<MODE>mode != SImode)
8036 /* Zero extend to SImode to avoid partial register stalls. */
8037 operands[0] = gen_lowpart (SImode, operands[0]);
8039 insn = (mode == HImode)
8040 ? gen_zero_extendhisi2
8041 : gen_zero_extendqisi2;
8043 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8048 [(set (match_operand 0 "register_operand")
8050 (const_int -65536)))
8051 (clobber (reg:CC FLAGS_REG))]
8052 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8053 || optimize_function_for_size_p (cfun)"
8054 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8055 "operands[1] = gen_lowpart (HImode, operands[0]);")
8058 [(set (match_operand 0 "ext_register_operand")
8061 (clobber (reg:CC FLAGS_REG))]
8062 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8063 && reload_completed"
8064 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8065 "operands[1] = gen_lowpart (QImode, operands[0]);")
8068 [(set (match_operand 0 "ext_register_operand")
8070 (const_int -65281)))
8071 (clobber (reg:CC FLAGS_REG))]
8072 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8073 && reload_completed"
8074 [(parallel [(set (zero_extract:SI (match_dup 0)
8078 (zero_extract:SI (match_dup 0)
8081 (zero_extract:SI (match_dup 0)
8084 (clobber (reg:CC FLAGS_REG))])]
8085 "operands[0] = gen_lowpart (SImode, operands[0]);")
8087 (define_insn "*anddi_2"
8088 [(set (reg FLAGS_REG)
8091 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8092 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8094 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8095 (and:DI (match_dup 1) (match_dup 2)))]
8097 && ix86_match_ccmode
8099 /* If we are going to emit andl instead of andq, and the operands[2]
8100 constant might have the SImode sign bit set, make sure the sign
8101 flag isn't tested, because the instruction will set the sign flag
8102 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8103 conservatively assume it might have bit 31 set. */
8104 (satisfies_constraint_Z (operands[2])
8105 && (!CONST_INT_P (operands[2])
8106 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8107 ? CCZmode : CCNOmode)
8108 && ix86_binary_operator_ok (AND, DImode, operands)"
8110 and{l}\t{%k2, %k0|%k0, %k2}
8111 and{q}\t{%2, %0|%0, %2}
8112 and{q}\t{%2, %0|%0, %2}"
8113 [(set_attr "type" "alu")
8114 (set_attr "mode" "SI,DI,DI")])
8116 (define_insn "*andqi_2_maybe_si"
8117 [(set (reg FLAGS_REG)
8119 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8120 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8122 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8123 (and:QI (match_dup 1) (match_dup 2)))]
8124 "ix86_binary_operator_ok (AND, QImode, operands)
8125 && ix86_match_ccmode (insn,
8126 CONST_INT_P (operands[2])
8127 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8129 if (which_alternative == 2)
8131 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8132 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8133 return "and{l}\t{%2, %k0|%k0, %2}";
8135 return "and{b}\t{%2, %0|%0, %2}";
8137 [(set_attr "type" "alu")
8138 (set_attr "mode" "QI,QI,SI")])
8140 (define_insn "*and<mode>_2"
8141 [(set (reg FLAGS_REG)
8142 (compare (and:SWI124
8143 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8144 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8146 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8147 (and:SWI124 (match_dup 1) (match_dup 2)))]
8148 "ix86_match_ccmode (insn, CCNOmode)
8149 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8150 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8151 [(set_attr "type" "alu")
8152 (set_attr "mode" "<MODE>")])
8154 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8155 (define_insn "*andsi_2_zext"
8156 [(set (reg FLAGS_REG)
8158 (match_operand:SI 1 "nonimmediate_operand" "%0")
8159 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8161 (set (match_operand:DI 0 "register_operand" "=r")
8162 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8163 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8164 && ix86_binary_operator_ok (AND, SImode, operands)"
8165 "and{l}\t{%2, %k0|%k0, %2}"
8166 [(set_attr "type" "alu")
8167 (set_attr "mode" "SI")])
8169 (define_insn "*andqi_2_slp"
8170 [(set (reg FLAGS_REG)
8172 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8173 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8175 (set (strict_low_part (match_dup 0))
8176 (and:QI (match_dup 0) (match_dup 1)))]
8177 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8178 && ix86_match_ccmode (insn, CCNOmode)
8179 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8180 "and{b}\t{%1, %0|%0, %1}"
8181 [(set_attr "type" "alu1")
8182 (set_attr "mode" "QI")])
8184 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8185 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8186 ;; for a QImode operand, which of course failed.
8187 (define_insn "andqi_ext_0"
8188 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8193 (match_operand 1 "ext_register_operand" "0")
8196 (match_operand 2 "const_int_operand" "n")))
8197 (clobber (reg:CC FLAGS_REG))]
8199 "and{b}\t{%2, %h0|%h0, %2}"
8200 [(set_attr "type" "alu")
8201 (set_attr "length_immediate" "1")
8202 (set_attr "modrm" "1")
8203 (set_attr "mode" "QI")])
8205 ;; Generated by peephole translating test to and. This shows up
8206 ;; often in fp comparisons.
8207 (define_insn "*andqi_ext_0_cc"
8208 [(set (reg FLAGS_REG)
8212 (match_operand 1 "ext_register_operand" "0")
8215 (match_operand 2 "const_int_operand" "n"))
8217 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8226 "ix86_match_ccmode (insn, CCNOmode)"
8227 "and{b}\t{%2, %h0|%h0, %2}"
8228 [(set_attr "type" "alu")
8229 (set_attr "length_immediate" "1")
8230 (set_attr "modrm" "1")
8231 (set_attr "mode" "QI")])
8233 (define_insn "*andqi_ext_1"
8234 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8239 (match_operand 1 "ext_register_operand" "0,0")
8243 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8244 (clobber (reg:CC FLAGS_REG))]
8246 "and{b}\t{%2, %h0|%h0, %2}"
8247 [(set_attr "isa" "*,nox64")
8248 (set_attr "type" "alu")
8249 (set_attr "length_immediate" "0")
8250 (set_attr "mode" "QI")])
8252 (define_insn "*andqi_ext_2"
8253 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8258 (match_operand 1 "ext_register_operand" "%0")
8262 (match_operand 2 "ext_register_operand" "Q")
8265 (clobber (reg:CC FLAGS_REG))]
8267 "and{b}\t{%h2, %h0|%h0, %h2}"
8268 [(set_attr "type" "alu")
8269 (set_attr "length_immediate" "0")
8270 (set_attr "mode" "QI")])
8272 ;; Convert wide AND instructions with immediate operand to shorter QImode
8273 ;; equivalents when possible.
8274 ;; Don't do the splitting with memory operands, since it introduces risk
8275 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8276 ;; for size, but that can (should?) be handled by generic code instead.
8278 [(set (match_operand 0 "register_operand")
8279 (and (match_operand 1 "register_operand")
8280 (match_operand 2 "const_int_operand")))
8281 (clobber (reg:CC FLAGS_REG))]
8283 && QI_REG_P (operands[0])
8284 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8285 && !(~INTVAL (operands[2]) & ~(255 << 8))
8286 && GET_MODE (operands[0]) != QImode"
8287 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8288 (and:SI (zero_extract:SI (match_dup 1)
8289 (const_int 8) (const_int 8))
8291 (clobber (reg:CC FLAGS_REG))])]
8293 operands[0] = gen_lowpart (SImode, operands[0]);
8294 operands[1] = gen_lowpart (SImode, operands[1]);
8295 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8298 ;; Since AND can be encoded with sign extended immediate, this is only
8299 ;; profitable when 7th bit is not set.
8301 [(set (match_operand 0 "register_operand")
8302 (and (match_operand 1 "general_operand")
8303 (match_operand 2 "const_int_operand")))
8304 (clobber (reg:CC FLAGS_REG))]
8306 && ANY_QI_REG_P (operands[0])
8307 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8308 && !(~INTVAL (operands[2]) & ~255)
8309 && !(INTVAL (operands[2]) & 128)
8310 && GET_MODE (operands[0]) != QImode"
8311 [(parallel [(set (strict_low_part (match_dup 0))
8312 (and:QI (match_dup 1)
8314 (clobber (reg:CC FLAGS_REG))])]
8316 operands[0] = gen_lowpart (QImode, operands[0]);
8317 operands[1] = gen_lowpart (QImode, operands[1]);
8318 operands[2] = gen_lowpart (QImode, operands[2]);
8321 ;; Logical inclusive and exclusive OR instructions
8323 ;; %%% This used to optimize known byte-wide and operations to memory.
8324 ;; If this is considered useful, it should be done with splitters.
8326 (define_expand "<code><mode>3"
8327 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8328 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8329 (match_operand:SWIM 2 "<general_operand>")))]
8331 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8333 (define_insn "*<code><mode>_1"
8334 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8336 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8337 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8338 (clobber (reg:CC FLAGS_REG))]
8339 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8341 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8342 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8343 k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8344 [(set_attr "type" "alu,alu,msklog")
8345 (set_attr "mode" "<MODE>")])
8347 (define_insn "*<code>hi_1"
8348 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8350 (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8351 (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8352 (clobber (reg:CC FLAGS_REG))]
8353 "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8355 <logic>{w}\t{%2, %0|%0, %2}
8356 <logic>{w}\t{%2, %0|%0, %2}
8357 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8358 [(set_attr "type" "alu,alu,msklog")
8359 (set_attr "mode" "HI")])
8361 ;; %%% Potential partial reg stall on alternative 2. What to do?
8362 (define_insn "*<code>qi_1"
8363 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8364 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8365 (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8366 (clobber (reg:CC FLAGS_REG))]
8367 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8369 <logic>{b}\t{%2, %0|%0, %2}
8370 <logic>{b}\t{%2, %0|%0, %2}
8371 <logic>{l}\t{%k2, %k0|%k0, %k2}
8372 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8373 [(set_attr "type" "alu,alu,alu,msklog")
8374 (set_attr "mode" "QI,QI,SI,HI")])
8376 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8377 (define_insn "*<code>si_1_zext"
8378 [(set (match_operand:DI 0 "register_operand" "=r")
8380 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8381 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8382 (clobber (reg:CC FLAGS_REG))]
8383 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8384 "<logic>{l}\t{%2, %k0|%k0, %2}"
8385 [(set_attr "type" "alu")
8386 (set_attr "mode" "SI")])
8388 (define_insn "*<code>si_1_zext_imm"
8389 [(set (match_operand:DI 0 "register_operand" "=r")
8391 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8392 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8393 (clobber (reg:CC FLAGS_REG))]
8394 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8395 "<logic>{l}\t{%2, %k0|%k0, %2}"
8396 [(set_attr "type" "alu")
8397 (set_attr "mode" "SI")])
8399 (define_insn "*<code>qi_1_slp"
8400 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8401 (any_or:QI (match_dup 0)
8402 (match_operand:QI 1 "general_operand" "qmn,qn")))
8403 (clobber (reg:CC FLAGS_REG))]
8404 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8405 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8406 "<logic>{b}\t{%1, %0|%0, %1}"
8407 [(set_attr "type" "alu1")
8408 (set_attr "mode" "QI")])
8410 (define_insn "*<code><mode>_2"
8411 [(set (reg FLAGS_REG)
8412 (compare (any_or:SWI
8413 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8414 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8416 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8417 (any_or:SWI (match_dup 1) (match_dup 2)))]
8418 "ix86_match_ccmode (insn, CCNOmode)
8419 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8420 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8421 [(set_attr "type" "alu")
8422 (set_attr "mode" "<MODE>")])
8424 (define_insn "kxnor<mode>"
8425 [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8428 (match_operand:SWI12 1 "register_operand" "0,k")
8429 (match_operand:SWI12 2 "register_operand" "r,k"))))
8430 (clobber (reg:CC FLAGS_REG))]
8433 if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8434 return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8435 return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8437 [(set_attr "type" "*,msklog")
8438 (set_attr "prefix" "*,vex")
8439 (set_attr "mode" "<MODE>")])
8441 (define_insn "kxnor<mode>"
8442 [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8445 (match_operand:SWI48x 1 "register_operand" "0,k")
8446 (match_operand:SWI48x 2 "register_operand" "r,k"))))
8447 (clobber (reg:CC FLAGS_REG))]
8451 kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8452 [(set_attr "type" "*,msklog")
8453 (set_attr "prefix" "*,vex")
8454 (set_attr "mode" "<MODE>")])
8457 [(set (match_operand:SWI1248x 0 "general_reg_operand")
8461 (match_operand:SWI1248x 1 "general_reg_operand"))))
8462 (clobber (reg:CC FLAGS_REG))]
8463 "TARGET_AVX512F && reload_completed"
8464 [(parallel [(set (match_dup 0)
8465 (xor:HI (match_dup 0)
8467 (clobber (reg:CC FLAGS_REG))])
8469 (not:HI (match_dup 0)))])
8471 ;;There are kortrest[bdq] but no intrinsics for them.
8472 ;;We probably don't need to implement them.
8473 (define_insn "kortestzhi"
8474 [(set (reg:CCZ FLAGS_REG)
8477 (match_operand:HI 0 "register_operand" "k")
8478 (match_operand:HI 1 "register_operand" "k"))
8480 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8481 "kortestw\t{%1, %0|%0, %1}"
8482 [(set_attr "mode" "HI")
8483 (set_attr "type" "msklog")
8484 (set_attr "prefix" "vex")])
8486 (define_insn "kortestchi"
8487 [(set (reg:CCC FLAGS_REG)
8490 (match_operand:HI 0 "register_operand" "k")
8491 (match_operand:HI 1 "register_operand" "k"))
8493 "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8494 "kortestw\t{%1, %0|%0, %1}"
8495 [(set_attr "mode" "HI")
8496 (set_attr "type" "msklog")
8497 (set_attr "prefix" "vex")])
8499 (define_insn "kunpckhi"
8500 [(set (match_operand:HI 0 "register_operand" "=k")
8503 (match_operand:HI 1 "register_operand" "k")
8505 (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8507 "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8508 [(set_attr "mode" "HI")
8509 (set_attr "type" "msklog")
8510 (set_attr "prefix" "vex")])
8512 (define_insn "kunpcksi"
8513 [(set (match_operand:SI 0 "register_operand" "=k")
8516 (match_operand:SI 1 "register_operand" "k")
8518 (zero_extend:SI (subreg:HI (match_operand:SI 2 "register_operand" "k") 0))))]
8520 "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8521 [(set_attr "mode" "SI")])
8523 (define_insn "kunpckdi"
8524 [(set (match_operand:DI 0 "register_operand" "=k")
8527 (match_operand:DI 1 "register_operand" "k")
8529 (zero_extend:DI (subreg:SI (match_operand:DI 2 "register_operand" "k") 0))))]
8531 "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8532 [(set_attr "mode" "DI")])
8534 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8535 ;; ??? Special case for immediate operand is missing - it is tricky.
8536 (define_insn "*<code>si_2_zext"
8537 [(set (reg FLAGS_REG)
8538 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8539 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8541 (set (match_operand:DI 0 "register_operand" "=r")
8542 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8543 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8544 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8545 "<logic>{l}\t{%2, %k0|%k0, %2}"
8546 [(set_attr "type" "alu")
8547 (set_attr "mode" "SI")])
8549 (define_insn "*<code>si_2_zext_imm"
8550 [(set (reg FLAGS_REG)
8552 (match_operand:SI 1 "nonimmediate_operand" "%0")
8553 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8555 (set (match_operand:DI 0 "register_operand" "=r")
8556 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8557 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8558 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8559 "<logic>{l}\t{%2, %k0|%k0, %2}"
8560 [(set_attr "type" "alu")
8561 (set_attr "mode" "SI")])
8563 (define_insn "*<code>qi_2_slp"
8564 [(set (reg FLAGS_REG)
8565 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8566 (match_operand:QI 1 "general_operand" "qmn,qn"))
8568 (set (strict_low_part (match_dup 0))
8569 (any_or:QI (match_dup 0) (match_dup 1)))]
8570 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8571 && ix86_match_ccmode (insn, CCNOmode)
8572 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8573 "<logic>{b}\t{%1, %0|%0, %1}"
8574 [(set_attr "type" "alu1")
8575 (set_attr "mode" "QI")])
8577 (define_insn "*<code><mode>_3"
8578 [(set (reg FLAGS_REG)
8579 (compare (any_or:SWI
8580 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8581 (match_operand:SWI 2 "<general_operand>" "<g>"))
8583 (clobber (match_scratch:SWI 0 "=<r>"))]
8584 "ix86_match_ccmode (insn, CCNOmode)
8585 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8586 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8587 [(set_attr "type" "alu")
8588 (set_attr "mode" "<MODE>")])
8590 (define_insn "*<code>qi_ext_0"
8591 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8596 (match_operand 1 "ext_register_operand" "0")
8599 (match_operand 2 "const_int_operand" "n")))
8600 (clobber (reg:CC FLAGS_REG))]
8601 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8602 "<logic>{b}\t{%2, %h0|%h0, %2}"
8603 [(set_attr "type" "alu")
8604 (set_attr "length_immediate" "1")
8605 (set_attr "modrm" "1")
8606 (set_attr "mode" "QI")])
8608 (define_insn "*<code>qi_ext_1"
8609 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8614 (match_operand 1 "ext_register_operand" "0,0")
8618 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8619 (clobber (reg:CC FLAGS_REG))]
8620 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8621 "<logic>{b}\t{%2, %h0|%h0, %2}"
8622 [(set_attr "isa" "*,nox64")
8623 (set_attr "type" "alu")
8624 (set_attr "length_immediate" "0")
8625 (set_attr "mode" "QI")])
8627 (define_insn "*<code>qi_ext_2"
8628 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8632 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8635 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8638 (clobber (reg:CC FLAGS_REG))]
8639 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8640 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8641 [(set_attr "type" "alu")
8642 (set_attr "length_immediate" "0")
8643 (set_attr "mode" "QI")])
8646 [(set (match_operand 0 "register_operand")
8647 (any_or (match_operand 1 "register_operand")
8648 (match_operand 2 "const_int_operand")))
8649 (clobber (reg:CC FLAGS_REG))]
8651 && QI_REG_P (operands[0])
8652 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8653 && !(INTVAL (operands[2]) & ~(255 << 8))
8654 && GET_MODE (operands[0]) != QImode"
8655 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8656 (any_or:SI (zero_extract:SI (match_dup 1)
8657 (const_int 8) (const_int 8))
8659 (clobber (reg:CC FLAGS_REG))])]
8661 operands[0] = gen_lowpart (SImode, operands[0]);
8662 operands[1] = gen_lowpart (SImode, operands[1]);
8663 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8666 ;; Since OR can be encoded with sign extended immediate, this is only
8667 ;; profitable when 7th bit is set.
8669 [(set (match_operand 0 "register_operand")
8670 (any_or (match_operand 1 "general_operand")
8671 (match_operand 2 "const_int_operand")))
8672 (clobber (reg:CC FLAGS_REG))]
8674 && ANY_QI_REG_P (operands[0])
8675 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8676 && !(INTVAL (operands[2]) & ~255)
8677 && (INTVAL (operands[2]) & 128)
8678 && GET_MODE (operands[0]) != QImode"
8679 [(parallel [(set (strict_low_part (match_dup 0))
8680 (any_or:QI (match_dup 1)
8682 (clobber (reg:CC FLAGS_REG))])]
8684 operands[0] = gen_lowpart (QImode, operands[0]);
8685 operands[1] = gen_lowpart (QImode, operands[1]);
8686 operands[2] = gen_lowpart (QImode, operands[2]);
8689 (define_expand "xorqi_cc_ext_1"
8691 (set (reg:CCNO FLAGS_REG)
8695 (match_operand 1 "ext_register_operand")
8698 (match_operand:QI 2 "const_int_operand"))
8700 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8710 (define_insn "*xorqi_cc_ext_1"
8711 [(set (reg FLAGS_REG)
8715 (match_operand 1 "ext_register_operand" "0,0")
8718 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8720 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8729 "ix86_match_ccmode (insn, CCNOmode)"
8730 "xor{b}\t{%2, %h0|%h0, %2}"
8731 [(set_attr "isa" "*,nox64")
8732 (set_attr "type" "alu")
8733 (set_attr "modrm" "1")
8734 (set_attr "mode" "QI")])
8736 ;; Negation instructions
8738 (define_expand "neg<mode>2"
8739 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8740 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8742 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8744 (define_insn_and_split "*neg<dwi>2_doubleword"
8745 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8746 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8747 (clobber (reg:CC FLAGS_REG))]
8748 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8752 [(set (reg:CCZ FLAGS_REG)
8753 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8754 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8757 (plus:DWIH (match_dup 3)
8758 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8760 (clobber (reg:CC FLAGS_REG))])
8763 (neg:DWIH (match_dup 2)))
8764 (clobber (reg:CC FLAGS_REG))])]
8765 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8767 (define_insn "*neg<mode>2_1"
8768 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8769 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8770 (clobber (reg:CC FLAGS_REG))]
8771 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8772 "neg{<imodesuffix>}\t%0"
8773 [(set_attr "type" "negnot")
8774 (set_attr "mode" "<MODE>")])
8776 ;; Combine is quite creative about this pattern.
8777 (define_insn "*negsi2_1_zext"
8778 [(set (match_operand:DI 0 "register_operand" "=r")
8780 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8783 (clobber (reg:CC FLAGS_REG))]
8784 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8786 [(set_attr "type" "negnot")
8787 (set_attr "mode" "SI")])
8789 ;; The problem with neg is that it does not perform (compare x 0),
8790 ;; it really performs (compare 0 x), which leaves us with the zero
8791 ;; flag being the only useful item.
8793 (define_insn "*neg<mode>2_cmpz"
8794 [(set (reg:CCZ FLAGS_REG)
8796 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8798 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8799 (neg:SWI (match_dup 1)))]
8800 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8801 "neg{<imodesuffix>}\t%0"
8802 [(set_attr "type" "negnot")
8803 (set_attr "mode" "<MODE>")])
8805 (define_insn "*negsi2_cmpz_zext"
8806 [(set (reg:CCZ FLAGS_REG)
8810 (match_operand:DI 1 "register_operand" "0")
8814 (set (match_operand:DI 0 "register_operand" "=r")
8815 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8818 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8820 [(set_attr "type" "negnot")
8821 (set_attr "mode" "SI")])
8823 ;; Negate with jump on overflow.
8824 (define_expand "negv<mode>3"
8825 [(parallel [(set (reg:CCO FLAGS_REG)
8826 (ne:CCO (match_operand:SWI 1 "register_operand")
8828 (set (match_operand:SWI 0 "register_operand")
8829 (neg:SWI (match_dup 1)))])
8830 (set (pc) (if_then_else
8831 (eq (reg:CCO FLAGS_REG) (const_int 0))
8832 (label_ref (match_operand 2))
8837 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8841 (define_insn "*negv<mode>3"
8842 [(set (reg:CCO FLAGS_REG)
8843 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8844 (match_operand:SWI 2 "const_int_operand")))
8845 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8846 (neg:SWI (match_dup 1)))]
8847 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8848 && mode_signbit_p (<MODE>mode, operands[2])"
8849 "neg{<imodesuffix>}\t%0"
8850 [(set_attr "type" "negnot")
8851 (set_attr "mode" "<MODE>")])
8853 ;; Changing of sign for FP values is doable using integer unit too.
8855 (define_expand "<code><mode>2"
8856 [(set (match_operand:X87MODEF 0 "register_operand")
8857 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8858 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8859 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8861 (define_insn "*absneg<mode>2_mixed"
8862 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8863 (match_operator:MODEF 3 "absneg_operator"
8864 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8865 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8866 (clobber (reg:CC FLAGS_REG))]
8867 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8870 (define_insn "*absneg<mode>2_sse"
8871 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8872 (match_operator:MODEF 3 "absneg_operator"
8873 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8874 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8875 (clobber (reg:CC FLAGS_REG))]
8876 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8879 (define_insn "*absneg<mode>2_i387"
8880 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8881 (match_operator:X87MODEF 3 "absneg_operator"
8882 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8883 (use (match_operand 2))
8884 (clobber (reg:CC FLAGS_REG))]
8885 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8888 (define_expand "<code>tf2"
8889 [(set (match_operand:TF 0 "register_operand")
8890 (absneg:TF (match_operand:TF 1 "register_operand")))]
8892 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8894 (define_insn "*absnegtf2_sse"
8895 [(set (match_operand:TF 0 "register_operand" "=x,x")
8896 (match_operator:TF 3 "absneg_operator"
8897 [(match_operand:TF 1 "register_operand" "0,x")]))
8898 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8899 (clobber (reg:CC FLAGS_REG))]
8903 ;; Splitters for fp abs and neg.
8906 [(set (match_operand 0 "fp_register_operand")
8907 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8908 (use (match_operand 2))
8909 (clobber (reg:CC FLAGS_REG))]
8911 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8914 [(set (match_operand 0 "register_operand")
8915 (match_operator 3 "absneg_operator"
8916 [(match_operand 1 "register_operand")]))
8917 (use (match_operand 2 "nonimmediate_operand"))
8918 (clobber (reg:CC FLAGS_REG))]
8919 "reload_completed && SSE_REG_P (operands[0])"
8920 [(set (match_dup 0) (match_dup 3))]
8922 machine_mode mode = GET_MODE (operands[0]);
8923 machine_mode vmode = GET_MODE (operands[2]);
8926 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8927 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8928 if (operands_match_p (operands[0], operands[2]))
8929 std::swap (operands[1], operands[2]);
8930 if (GET_CODE (operands[3]) == ABS)
8931 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8933 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8938 [(set (match_operand:SF 0 "register_operand")
8939 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8940 (use (match_operand:V4SF 2))
8941 (clobber (reg:CC FLAGS_REG))]
8943 [(parallel [(set (match_dup 0) (match_dup 1))
8944 (clobber (reg:CC FLAGS_REG))])]
8947 operands[0] = gen_lowpart (SImode, operands[0]);
8948 if (GET_CODE (operands[1]) == ABS)
8950 tmp = gen_int_mode (0x7fffffff, SImode);
8951 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8955 tmp = gen_int_mode (0x80000000, SImode);
8956 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8962 [(set (match_operand:DF 0 "register_operand")
8963 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8964 (use (match_operand 2))
8965 (clobber (reg:CC FLAGS_REG))]
8967 [(parallel [(set (match_dup 0) (match_dup 1))
8968 (clobber (reg:CC FLAGS_REG))])]
8973 tmp = gen_lowpart (DImode, operands[0]);
8974 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8977 if (GET_CODE (operands[1]) == ABS)
8980 tmp = gen_rtx_NOT (DImode, tmp);
8984 operands[0] = gen_highpart (SImode, operands[0]);
8985 if (GET_CODE (operands[1]) == ABS)
8987 tmp = gen_int_mode (0x7fffffff, SImode);
8988 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8992 tmp = gen_int_mode (0x80000000, SImode);
8993 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9000 [(set (match_operand:XF 0 "register_operand")
9001 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9002 (use (match_operand 2))
9003 (clobber (reg:CC FLAGS_REG))]
9005 [(parallel [(set (match_dup 0) (match_dup 1))
9006 (clobber (reg:CC FLAGS_REG))])]
9009 operands[0] = gen_rtx_REG (SImode,
9010 true_regnum (operands[0])
9011 + (TARGET_64BIT ? 1 : 2));
9012 if (GET_CODE (operands[1]) == ABS)
9014 tmp = GEN_INT (0x7fff);
9015 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9019 tmp = GEN_INT (0x8000);
9020 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9025 ;; Conditionalize these after reload. If they match before reload, we
9026 ;; lose the clobber and ability to use integer instructions.
9028 (define_insn "*<code><mode>2_1"
9029 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9030 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9032 && (reload_completed
9033 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9034 "f<absneg_mnemonic>"
9035 [(set_attr "type" "fsgn")
9036 (set_attr "mode" "<MODE>")])
9038 (define_insn "*<code>extendsfdf2"
9039 [(set (match_operand:DF 0 "register_operand" "=f")
9040 (absneg:DF (float_extend:DF
9041 (match_operand:SF 1 "register_operand" "0"))))]
9042 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9043 "f<absneg_mnemonic>"
9044 [(set_attr "type" "fsgn")
9045 (set_attr "mode" "DF")])
9047 (define_insn "*<code>extendsfxf2"
9048 [(set (match_operand:XF 0 "register_operand" "=f")
9049 (absneg:XF (float_extend:XF
9050 (match_operand:SF 1 "register_operand" "0"))))]
9052 "f<absneg_mnemonic>"
9053 [(set_attr "type" "fsgn")
9054 (set_attr "mode" "XF")])
9056 (define_insn "*<code>extenddfxf2"
9057 [(set (match_operand:XF 0 "register_operand" "=f")
9058 (absneg:XF (float_extend:XF
9059 (match_operand:DF 1 "register_operand" "0"))))]
9061 "f<absneg_mnemonic>"
9062 [(set_attr "type" "fsgn")
9063 (set_attr "mode" "XF")])
9065 ;; Copysign instructions
9067 (define_mode_iterator CSGNMODE [SF DF TF])
9068 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9070 (define_expand "copysign<mode>3"
9071 [(match_operand:CSGNMODE 0 "register_operand")
9072 (match_operand:CSGNMODE 1 "nonmemory_operand")
9073 (match_operand:CSGNMODE 2 "register_operand")]
9074 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9075 || (TARGET_SSE && (<MODE>mode == TFmode))"
9076 "ix86_expand_copysign (operands); DONE;")
9078 (define_insn_and_split "copysign<mode>3_const"
9079 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9081 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9082 (match_operand:CSGNMODE 2 "register_operand" "0")
9083 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9085 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9086 || (TARGET_SSE && (<MODE>mode == TFmode))"
9088 "&& reload_completed"
9090 "ix86_split_copysign_const (operands); DONE;")
9092 (define_insn "copysign<mode>3_var"
9093 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9095 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9096 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9097 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9098 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9100 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9101 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9102 || (TARGET_SSE && (<MODE>mode == TFmode))"
9106 [(set (match_operand:CSGNMODE 0 "register_operand")
9108 [(match_operand:CSGNMODE 2 "register_operand")
9109 (match_operand:CSGNMODE 3 "register_operand")
9110 (match_operand:<CSGNVMODE> 4)
9111 (match_operand:<CSGNVMODE> 5)]
9113 (clobber (match_scratch:<CSGNVMODE> 1))]
9114 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9115 || (TARGET_SSE && (<MODE>mode == TFmode)))
9116 && reload_completed"
9118 "ix86_split_copysign_var (operands); DONE;")
9120 ;; One complement instructions
9122 (define_expand "one_cmpl<mode>2"
9123 [(set (match_operand:SWIM 0 "nonimmediate_operand")
9124 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9126 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9128 (define_insn "*one_cmpl<mode>2_1"
9129 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
9130 (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
9131 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9133 not{<imodesuffix>}\t%0
9134 knot<mskmodesuffix>\t{%1, %0|%0, %1}"
9135 [(set_attr "isa" "*,avx512bw")
9136 (set_attr "type" "negnot,msklog")
9137 (set_attr "prefix" "*,vex")
9138 (set_attr "mode" "<MODE>")])
9140 (define_insn "*one_cmplhi2_1"
9141 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
9142 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
9143 "ix86_unary_operator_ok (NOT, HImode, operands)"
9146 knotw\t{%1, %0|%0, %1}"
9147 [(set_attr "isa" "*,avx512f")
9148 (set_attr "type" "negnot,msklog")
9149 (set_attr "prefix" "*,vex")
9150 (set_attr "mode" "HI")])
9152 ;; %%% Potential partial reg stall on alternative 1. What to do?
9153 (define_insn "*one_cmplqi2_1"
9154 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
9155 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
9156 "ix86_unary_operator_ok (NOT, QImode, operands)"
9158 switch (which_alternative)
9161 return "not{b}\t%0";
9163 return "not{l}\t%k0";
9165 if (TARGET_AVX512DQ)
9166 return "knotb\t{%1, %0|%0, %1}";
9167 return "knotw\t{%1, %0|%0, %1}";
9172 [(set_attr "isa" "*,*,avx512f")
9173 (set_attr "type" "negnot,negnot,msklog")
9174 (set_attr "prefix" "*,*,vex")
9175 (set_attr "mode" "QI,SI,QI")])
9177 ;; ??? Currently never generated - xor is used instead.
9178 (define_insn "*one_cmplsi2_1_zext"
9179 [(set (match_operand:DI 0 "register_operand" "=r")
9181 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9182 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9184 [(set_attr "type" "negnot")
9185 (set_attr "mode" "SI")])
9187 (define_insn "*one_cmpl<mode>2_2"
9188 [(set (reg FLAGS_REG)
9189 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9191 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9192 (not:SWI (match_dup 1)))]
9193 "ix86_match_ccmode (insn, CCNOmode)
9194 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9196 [(set_attr "type" "alu1")
9197 (set_attr "mode" "<MODE>")])
9200 [(set (match_operand 0 "flags_reg_operand")
9201 (match_operator 2 "compare_operator"
9202 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9204 (set (match_operand:SWI 1 "nonimmediate_operand")
9205 (not:SWI (match_dup 3)))]
9206 "ix86_match_ccmode (insn, CCNOmode)"
9207 [(parallel [(set (match_dup 0)
9208 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9211 (xor:SWI (match_dup 3) (const_int -1)))])])
9213 ;; ??? Currently never generated - xor is used instead.
9214 (define_insn "*one_cmplsi2_2_zext"
9215 [(set (reg FLAGS_REG)
9216 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9218 (set (match_operand:DI 0 "register_operand" "=r")
9219 (zero_extend:DI (not:SI (match_dup 1))))]
9220 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9221 && ix86_unary_operator_ok (NOT, SImode, operands)"
9223 [(set_attr "type" "alu1")
9224 (set_attr "mode" "SI")])
9227 [(set (match_operand 0 "flags_reg_operand")
9228 (match_operator 2 "compare_operator"
9229 [(not:SI (match_operand:SI 3 "register_operand"))
9231 (set (match_operand:DI 1 "register_operand")
9232 (zero_extend:DI (not:SI (match_dup 3))))]
9233 "ix86_match_ccmode (insn, CCNOmode)"
9234 [(parallel [(set (match_dup 0)
9235 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9238 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9240 ;; Shift instructions
9242 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9243 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9244 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9245 ;; from the assembler input.
9247 ;; This instruction shifts the target reg/mem as usual, but instead of
9248 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9249 ;; is a left shift double, bits are taken from the high order bits of
9250 ;; reg, else if the insn is a shift right double, bits are taken from the
9251 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9252 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9254 ;; Since sh[lr]d does not change the `reg' operand, that is done
9255 ;; separately, making all shifts emit pairs of shift double and normal
9256 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9257 ;; support a 63 bit shift, each shift where the count is in a reg expands
9258 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9260 ;; If the shift count is a constant, we need never emit more than one
9261 ;; shift pair, instead using moves and sign extension for counts greater
9264 (define_expand "ashl<mode>3"
9265 [(set (match_operand:SDWIM 0 "<shift_operand>")
9266 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9267 (match_operand:QI 2 "nonmemory_operand")))]
9269 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9271 (define_insn "*ashl<mode>3_doubleword"
9272 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9273 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9274 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9275 (clobber (reg:CC FLAGS_REG))]
9278 [(set_attr "type" "multi")])
9281 [(set (match_operand:DWI 0 "register_operand")
9282 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9283 (match_operand:QI 2 "nonmemory_operand")))
9284 (clobber (reg:CC FLAGS_REG))]
9285 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9287 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9289 ;; By default we don't ask for a scratch register, because when DWImode
9290 ;; values are manipulated, registers are already at a premium. But if
9291 ;; we have one handy, we won't turn it away.
9294 [(match_scratch:DWIH 3 "r")
9295 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9297 (match_operand:<DWI> 1 "nonmemory_operand")
9298 (match_operand:QI 2 "nonmemory_operand")))
9299 (clobber (reg:CC FLAGS_REG))])
9303 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9305 (define_insn "x86_64_shld"
9306 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9307 (ior:DI (ashift:DI (match_dup 0)
9308 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9309 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9310 (minus:QI (const_int 64) (match_dup 2)))))
9311 (clobber (reg:CC FLAGS_REG))]
9313 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9314 [(set_attr "type" "ishift")
9315 (set_attr "prefix_0f" "1")
9316 (set_attr "mode" "DI")
9317 (set_attr "athlon_decode" "vector")
9318 (set_attr "amdfam10_decode" "vector")
9319 (set_attr "bdver1_decode" "vector")])
9321 (define_insn "x86_shld"
9322 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9323 (ior:SI (ashift:SI (match_dup 0)
9324 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9325 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9326 (minus:QI (const_int 32) (match_dup 2)))))
9327 (clobber (reg:CC FLAGS_REG))]
9329 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9330 [(set_attr "type" "ishift")
9331 (set_attr "prefix_0f" "1")
9332 (set_attr "mode" "SI")
9333 (set_attr "pent_pair" "np")
9334 (set_attr "athlon_decode" "vector")
9335 (set_attr "amdfam10_decode" "vector")
9336 (set_attr "bdver1_decode" "vector")])
9338 (define_expand "x86_shift<mode>_adj_1"
9339 [(set (reg:CCZ FLAGS_REG)
9340 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9343 (set (match_operand:SWI48 0 "register_operand")
9344 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9345 (match_operand:SWI48 1 "register_operand")
9348 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9349 (match_operand:SWI48 3 "register_operand")
9352 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9354 (define_expand "x86_shift<mode>_adj_2"
9355 [(use (match_operand:SWI48 0 "register_operand"))
9356 (use (match_operand:SWI48 1 "register_operand"))
9357 (use (match_operand:QI 2 "register_operand"))]
9360 rtx_code_label *label = gen_label_rtx ();
9363 emit_insn (gen_testqi_ccz_1 (operands[2],
9364 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9366 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9367 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9368 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9369 gen_rtx_LABEL_REF (VOIDmode, label),
9371 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9372 JUMP_LABEL (tmp) = label;
9374 emit_move_insn (operands[0], operands[1]);
9375 ix86_expand_clear (operands[1]);
9378 LABEL_NUSES (label) = 1;
9383 ;; Avoid useless masking of count operand.
9384 (define_insn "*ashl<mode>3_mask"
9385 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9387 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9390 (match_operand:SI 2 "register_operand" "c")
9391 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9392 (clobber (reg:CC FLAGS_REG))]
9393 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9394 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9395 == GET_MODE_BITSIZE (<MODE>mode)-1"
9397 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9399 [(set_attr "type" "ishift")
9400 (set_attr "mode" "<MODE>")])
9402 (define_insn "*bmi2_ashl<mode>3_1"
9403 [(set (match_operand:SWI48 0 "register_operand" "=r")
9404 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9405 (match_operand:SWI48 2 "register_operand" "r")))]
9407 "shlx\t{%2, %1, %0|%0, %1, %2}"
9408 [(set_attr "type" "ishiftx")
9409 (set_attr "mode" "<MODE>")])
9411 (define_insn "*ashl<mode>3_1"
9412 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9413 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9414 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9415 (clobber (reg:CC FLAGS_REG))]
9416 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9418 switch (get_attr_type (insn))
9425 gcc_assert (operands[2] == const1_rtx);
9426 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9427 return "add{<imodesuffix>}\t%0, %0";
9430 if (operands[2] == const1_rtx
9431 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9432 return "sal{<imodesuffix>}\t%0";
9434 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9437 [(set_attr "isa" "*,*,bmi2")
9439 (cond [(eq_attr "alternative" "1")
9440 (const_string "lea")
9441 (eq_attr "alternative" "2")
9442 (const_string "ishiftx")
9443 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9444 (match_operand 0 "register_operand"))
9445 (match_operand 2 "const1_operand"))
9446 (const_string "alu")
9448 (const_string "ishift")))
9449 (set (attr "length_immediate")
9451 (ior (eq_attr "type" "alu")
9452 (and (eq_attr "type" "ishift")
9453 (and (match_operand 2 "const1_operand")
9454 (ior (match_test "TARGET_SHIFT1")
9455 (match_test "optimize_function_for_size_p (cfun)")))))
9457 (const_string "*")))
9458 (set_attr "mode" "<MODE>")])
9460 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9462 [(set (match_operand:SWI48 0 "register_operand")
9463 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9464 (match_operand:QI 2 "register_operand")))
9465 (clobber (reg:CC FLAGS_REG))]
9466 "TARGET_BMI2 && reload_completed"
9468 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9469 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9471 (define_insn "*bmi2_ashlsi3_1_zext"
9472 [(set (match_operand:DI 0 "register_operand" "=r")
9474 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9475 (match_operand:SI 2 "register_operand" "r"))))]
9476 "TARGET_64BIT && TARGET_BMI2"
9477 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9478 [(set_attr "type" "ishiftx")
9479 (set_attr "mode" "SI")])
9481 (define_insn "*ashlsi3_1_zext"
9482 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9484 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9485 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9486 (clobber (reg:CC FLAGS_REG))]
9487 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9489 switch (get_attr_type (insn))
9496 gcc_assert (operands[2] == const1_rtx);
9497 return "add{l}\t%k0, %k0";
9500 if (operands[2] == const1_rtx
9501 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9502 return "sal{l}\t%k0";
9504 return "sal{l}\t{%2, %k0|%k0, %2}";
9507 [(set_attr "isa" "*,*,bmi2")
9509 (cond [(eq_attr "alternative" "1")
9510 (const_string "lea")
9511 (eq_attr "alternative" "2")
9512 (const_string "ishiftx")
9513 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9514 (match_operand 2 "const1_operand"))
9515 (const_string "alu")
9517 (const_string "ishift")))
9518 (set (attr "length_immediate")
9520 (ior (eq_attr "type" "alu")
9521 (and (eq_attr "type" "ishift")
9522 (and (match_operand 2 "const1_operand")
9523 (ior (match_test "TARGET_SHIFT1")
9524 (match_test "optimize_function_for_size_p (cfun)")))))
9526 (const_string "*")))
9527 (set_attr "mode" "SI")])
9529 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9531 [(set (match_operand:DI 0 "register_operand")
9533 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9534 (match_operand:QI 2 "register_operand"))))
9535 (clobber (reg:CC FLAGS_REG))]
9536 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9538 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9539 "operands[2] = gen_lowpart (SImode, operands[2]);")
9541 (define_insn "*ashlhi3_1"
9542 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9543 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9544 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9545 (clobber (reg:CC FLAGS_REG))]
9546 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9548 switch (get_attr_type (insn))
9554 gcc_assert (operands[2] == const1_rtx);
9555 return "add{w}\t%0, %0";
9558 if (operands[2] == const1_rtx
9559 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9560 return "sal{w}\t%0";
9562 return "sal{w}\t{%2, %0|%0, %2}";
9566 (cond [(eq_attr "alternative" "1")
9567 (const_string "lea")
9568 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9569 (match_operand 0 "register_operand"))
9570 (match_operand 2 "const1_operand"))
9571 (const_string "alu")
9573 (const_string "ishift")))
9574 (set (attr "length_immediate")
9576 (ior (eq_attr "type" "alu")
9577 (and (eq_attr "type" "ishift")
9578 (and (match_operand 2 "const1_operand")
9579 (ior (match_test "TARGET_SHIFT1")
9580 (match_test "optimize_function_for_size_p (cfun)")))))
9582 (const_string "*")))
9583 (set_attr "mode" "HI,SI")])
9585 ;; %%% Potential partial reg stall on alternative 1. What to do?
9586 (define_insn "*ashlqi3_1"
9587 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9588 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9589 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9590 (clobber (reg:CC FLAGS_REG))]
9591 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9593 switch (get_attr_type (insn))
9599 gcc_assert (operands[2] == const1_rtx);
9600 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9601 return "add{l}\t%k0, %k0";
9603 return "add{b}\t%0, %0";
9606 if (operands[2] == const1_rtx
9607 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9609 if (get_attr_mode (insn) == MODE_SI)
9610 return "sal{l}\t%k0";
9612 return "sal{b}\t%0";
9616 if (get_attr_mode (insn) == MODE_SI)
9617 return "sal{l}\t{%2, %k0|%k0, %2}";
9619 return "sal{b}\t{%2, %0|%0, %2}";
9624 (cond [(eq_attr "alternative" "2")
9625 (const_string "lea")
9626 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9627 (match_operand 0 "register_operand"))
9628 (match_operand 2 "const1_operand"))
9629 (const_string "alu")
9631 (const_string "ishift")))
9632 (set (attr "length_immediate")
9634 (ior (eq_attr "type" "alu")
9635 (and (eq_attr "type" "ishift")
9636 (and (match_operand 2 "const1_operand")
9637 (ior (match_test "TARGET_SHIFT1")
9638 (match_test "optimize_function_for_size_p (cfun)")))))
9640 (const_string "*")))
9641 (set_attr "mode" "QI,SI,SI")])
9643 (define_insn "*ashlqi3_1_slp"
9644 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9645 (ashift:QI (match_dup 0)
9646 (match_operand:QI 1 "nonmemory_operand" "cI")))
9647 (clobber (reg:CC FLAGS_REG))]
9648 "(optimize_function_for_size_p (cfun)
9649 || !TARGET_PARTIAL_FLAG_REG_STALL
9650 || (operands[1] == const1_rtx
9652 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9654 switch (get_attr_type (insn))
9657 gcc_assert (operands[1] == const1_rtx);
9658 return "add{b}\t%0, %0";
9661 if (operands[1] == const1_rtx
9662 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9663 return "sal{b}\t%0";
9665 return "sal{b}\t{%1, %0|%0, %1}";
9669 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9670 (match_operand 0 "register_operand"))
9671 (match_operand 1 "const1_operand"))
9672 (const_string "alu")
9674 (const_string "ishift1")))
9675 (set (attr "length_immediate")
9677 (ior (eq_attr "type" "alu")
9678 (and (eq_attr "type" "ishift1")
9679 (and (match_operand 1 "const1_operand")
9680 (ior (match_test "TARGET_SHIFT1")
9681 (match_test "optimize_function_for_size_p (cfun)")))))
9683 (const_string "*")))
9684 (set_attr "mode" "QI")])
9686 ;; Convert ashift to the lea pattern to avoid flags dependency.
9688 [(set (match_operand 0 "register_operand")
9689 (ashift (match_operand 1 "index_register_operand")
9690 (match_operand:QI 2 "const_int_operand")))
9691 (clobber (reg:CC FLAGS_REG))]
9692 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9694 && true_regnum (operands[0]) != true_regnum (operands[1])"
9697 machine_mode mode = GET_MODE (operands[0]);
9700 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9703 operands[0] = gen_lowpart (mode, operands[0]);
9704 operands[1] = gen_lowpart (mode, operands[1]);
9707 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9709 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9711 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9715 ;; Convert ashift to the lea pattern to avoid flags dependency.
9717 [(set (match_operand:DI 0 "register_operand")
9719 (ashift:SI (match_operand:SI 1 "index_register_operand")
9720 (match_operand:QI 2 "const_int_operand"))))
9721 (clobber (reg:CC FLAGS_REG))]
9722 "TARGET_64BIT && reload_completed
9723 && true_regnum (operands[0]) != true_regnum (operands[1])"
9725 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9727 operands[1] = gen_lowpart (SImode, operands[1]);
9728 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9731 ;; This pattern can't accept a variable shift count, since shifts by
9732 ;; zero don't affect the flags. We assume that shifts by constant
9733 ;; zero are optimized away.
9734 (define_insn "*ashl<mode>3_cmp"
9735 [(set (reg FLAGS_REG)
9737 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9738 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9740 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9741 (ashift:SWI (match_dup 1) (match_dup 2)))]
9742 "(optimize_function_for_size_p (cfun)
9743 || !TARGET_PARTIAL_FLAG_REG_STALL
9744 || (operands[2] == const1_rtx
9746 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9747 && ix86_match_ccmode (insn, CCGOCmode)
9748 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9750 switch (get_attr_type (insn))
9753 gcc_assert (operands[2] == const1_rtx);
9754 return "add{<imodesuffix>}\t%0, %0";
9757 if (operands[2] == const1_rtx
9758 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9759 return "sal{<imodesuffix>}\t%0";
9761 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9765 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9766 (match_operand 0 "register_operand"))
9767 (match_operand 2 "const1_operand"))
9768 (const_string "alu")
9770 (const_string "ishift")))
9771 (set (attr "length_immediate")
9773 (ior (eq_attr "type" "alu")
9774 (and (eq_attr "type" "ishift")
9775 (and (match_operand 2 "const1_operand")
9776 (ior (match_test "TARGET_SHIFT1")
9777 (match_test "optimize_function_for_size_p (cfun)")))))
9779 (const_string "*")))
9780 (set_attr "mode" "<MODE>")])
9782 (define_insn "*ashlsi3_cmp_zext"
9783 [(set (reg FLAGS_REG)
9785 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9786 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9788 (set (match_operand:DI 0 "register_operand" "=r")
9789 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9791 && (optimize_function_for_size_p (cfun)
9792 || !TARGET_PARTIAL_FLAG_REG_STALL
9793 || (operands[2] == const1_rtx
9795 || TARGET_DOUBLE_WITH_ADD)))
9796 && ix86_match_ccmode (insn, CCGOCmode)
9797 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9799 switch (get_attr_type (insn))
9802 gcc_assert (operands[2] == const1_rtx);
9803 return "add{l}\t%k0, %k0";
9806 if (operands[2] == const1_rtx
9807 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9808 return "sal{l}\t%k0";
9810 return "sal{l}\t{%2, %k0|%k0, %2}";
9814 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9815 (match_operand 2 "const1_operand"))
9816 (const_string "alu")
9818 (const_string "ishift")))
9819 (set (attr "length_immediate")
9821 (ior (eq_attr "type" "alu")
9822 (and (eq_attr "type" "ishift")
9823 (and (match_operand 2 "const1_operand")
9824 (ior (match_test "TARGET_SHIFT1")
9825 (match_test "optimize_function_for_size_p (cfun)")))))
9827 (const_string "*")))
9828 (set_attr "mode" "SI")])
9830 (define_insn "*ashl<mode>3_cconly"
9831 [(set (reg FLAGS_REG)
9833 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9834 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9836 (clobber (match_scratch:SWI 0 "=<r>"))]
9837 "(optimize_function_for_size_p (cfun)
9838 || !TARGET_PARTIAL_FLAG_REG_STALL
9839 || (operands[2] == const1_rtx
9841 || TARGET_DOUBLE_WITH_ADD)))
9842 && ix86_match_ccmode (insn, CCGOCmode)"
9844 switch (get_attr_type (insn))
9847 gcc_assert (operands[2] == const1_rtx);
9848 return "add{<imodesuffix>}\t%0, %0";
9851 if (operands[2] == const1_rtx
9852 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9853 return "sal{<imodesuffix>}\t%0";
9855 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9859 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9860 (match_operand 0 "register_operand"))
9861 (match_operand 2 "const1_operand"))
9862 (const_string "alu")
9864 (const_string "ishift")))
9865 (set (attr "length_immediate")
9867 (ior (eq_attr "type" "alu")
9868 (and (eq_attr "type" "ishift")
9869 (and (match_operand 2 "const1_operand")
9870 (ior (match_test "TARGET_SHIFT1")
9871 (match_test "optimize_function_for_size_p (cfun)")))))
9873 (const_string "*")))
9874 (set_attr "mode" "<MODE>")])
9876 ;; See comment above `ashl<mode>3' about how this works.
9878 (define_expand "<shift_insn><mode>3"
9879 [(set (match_operand:SDWIM 0 "<shift_operand>")
9880 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9881 (match_operand:QI 2 "nonmemory_operand")))]
9883 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9885 ;; Avoid useless masking of count operand.
9886 (define_insn "*<shift_insn><mode>3_mask"
9887 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9889 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9892 (match_operand:SI 2 "register_operand" "c")
9893 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9894 (clobber (reg:CC FLAGS_REG))]
9895 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9896 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9897 == GET_MODE_BITSIZE (<MODE>mode)-1"
9899 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9901 [(set_attr "type" "ishift")
9902 (set_attr "mode" "<MODE>")])
9904 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9905 [(set (match_operand:DWI 0 "register_operand" "=r")
9906 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9907 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9908 (clobber (reg:CC FLAGS_REG))]
9911 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9913 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9914 [(set_attr "type" "multi")])
9916 ;; By default we don't ask for a scratch register, because when DWImode
9917 ;; values are manipulated, registers are already at a premium. But if
9918 ;; we have one handy, we won't turn it away.
9921 [(match_scratch:DWIH 3 "r")
9922 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9924 (match_operand:<DWI> 1 "register_operand")
9925 (match_operand:QI 2 "nonmemory_operand")))
9926 (clobber (reg:CC FLAGS_REG))])
9930 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9932 (define_insn "x86_64_shrd"
9933 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9934 (ior:DI (lshiftrt:DI (match_dup 0)
9935 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9936 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9937 (minus:QI (const_int 64) (match_dup 2)))))
9938 (clobber (reg:CC FLAGS_REG))]
9940 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9941 [(set_attr "type" "ishift")
9942 (set_attr "prefix_0f" "1")
9943 (set_attr "mode" "DI")
9944 (set_attr "athlon_decode" "vector")
9945 (set_attr "amdfam10_decode" "vector")
9946 (set_attr "bdver1_decode" "vector")])
9948 (define_insn "x86_shrd"
9949 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9950 (ior:SI (lshiftrt:SI (match_dup 0)
9951 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9952 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9953 (minus:QI (const_int 32) (match_dup 2)))))
9954 (clobber (reg:CC FLAGS_REG))]
9956 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9957 [(set_attr "type" "ishift")
9958 (set_attr "prefix_0f" "1")
9959 (set_attr "mode" "SI")
9960 (set_attr "pent_pair" "np")
9961 (set_attr "athlon_decode" "vector")
9962 (set_attr "amdfam10_decode" "vector")
9963 (set_attr "bdver1_decode" "vector")])
9965 (define_insn "ashrdi3_cvt"
9966 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9967 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9968 (match_operand:QI 2 "const_int_operand")))
9969 (clobber (reg:CC FLAGS_REG))]
9970 "TARGET_64BIT && INTVAL (operands[2]) == 63
9971 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9972 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9975 sar{q}\t{%2, %0|%0, %2}"
9976 [(set_attr "type" "imovx,ishift")
9977 (set_attr "prefix_0f" "0,*")
9978 (set_attr "length_immediate" "0,*")
9979 (set_attr "modrm" "0,1")
9980 (set_attr "mode" "DI")])
9982 (define_insn "ashrsi3_cvt"
9983 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9984 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9985 (match_operand:QI 2 "const_int_operand")))
9986 (clobber (reg:CC FLAGS_REG))]
9987 "INTVAL (operands[2]) == 31
9988 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9989 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9992 sar{l}\t{%2, %0|%0, %2}"
9993 [(set_attr "type" "imovx,ishift")
9994 (set_attr "prefix_0f" "0,*")
9995 (set_attr "length_immediate" "0,*")
9996 (set_attr "modrm" "0,1")
9997 (set_attr "mode" "SI")])
9999 (define_insn "*ashrsi3_cvt_zext"
10000 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10002 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10003 (match_operand:QI 2 "const_int_operand"))))
10004 (clobber (reg:CC FLAGS_REG))]
10005 "TARGET_64BIT && INTVAL (operands[2]) == 31
10006 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10007 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10010 sar{l}\t{%2, %k0|%k0, %2}"
10011 [(set_attr "type" "imovx,ishift")
10012 (set_attr "prefix_0f" "0,*")
10013 (set_attr "length_immediate" "0,*")
10014 (set_attr "modrm" "0,1")
10015 (set_attr "mode" "SI")])
10017 (define_expand "x86_shift<mode>_adj_3"
10018 [(use (match_operand:SWI48 0 "register_operand"))
10019 (use (match_operand:SWI48 1 "register_operand"))
10020 (use (match_operand:QI 2 "register_operand"))]
10023 rtx_code_label *label = gen_label_rtx ();
10026 emit_insn (gen_testqi_ccz_1 (operands[2],
10027 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10029 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10030 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10031 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10032 gen_rtx_LABEL_REF (VOIDmode, label),
10034 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10035 JUMP_LABEL (tmp) = label;
10037 emit_move_insn (operands[0], operands[1]);
10038 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10039 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10040 emit_label (label);
10041 LABEL_NUSES (label) = 1;
10046 (define_insn "*bmi2_<shift_insn><mode>3_1"
10047 [(set (match_operand:SWI48 0 "register_operand" "=r")
10048 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10049 (match_operand:SWI48 2 "register_operand" "r")))]
10051 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10052 [(set_attr "type" "ishiftx")
10053 (set_attr "mode" "<MODE>")])
10055 (define_insn "*<shift_insn><mode>3_1"
10056 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10058 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10059 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10060 (clobber (reg:CC FLAGS_REG))]
10061 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10063 switch (get_attr_type (insn))
10069 if (operands[2] == const1_rtx
10070 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10071 return "<shift>{<imodesuffix>}\t%0";
10073 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10076 [(set_attr "isa" "*,bmi2")
10077 (set_attr "type" "ishift,ishiftx")
10078 (set (attr "length_immediate")
10080 (and (match_operand 2 "const1_operand")
10081 (ior (match_test "TARGET_SHIFT1")
10082 (match_test "optimize_function_for_size_p (cfun)")))
10084 (const_string "*")))
10085 (set_attr "mode" "<MODE>")])
10087 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10089 [(set (match_operand:SWI48 0 "register_operand")
10090 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10091 (match_operand:QI 2 "register_operand")))
10092 (clobber (reg:CC FLAGS_REG))]
10093 "TARGET_BMI2 && reload_completed"
10094 [(set (match_dup 0)
10095 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10096 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10098 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10099 [(set (match_operand:DI 0 "register_operand" "=r")
10101 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10102 (match_operand:SI 2 "register_operand" "r"))))]
10103 "TARGET_64BIT && TARGET_BMI2"
10104 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10105 [(set_attr "type" "ishiftx")
10106 (set_attr "mode" "SI")])
10108 (define_insn "*<shift_insn>si3_1_zext"
10109 [(set (match_operand:DI 0 "register_operand" "=r,r")
10111 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10112 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10113 (clobber (reg:CC FLAGS_REG))]
10114 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10116 switch (get_attr_type (insn))
10122 if (operands[2] == const1_rtx
10123 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10124 return "<shift>{l}\t%k0";
10126 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10129 [(set_attr "isa" "*,bmi2")
10130 (set_attr "type" "ishift,ishiftx")
10131 (set (attr "length_immediate")
10133 (and (match_operand 2 "const1_operand")
10134 (ior (match_test "TARGET_SHIFT1")
10135 (match_test "optimize_function_for_size_p (cfun)")))
10137 (const_string "*")))
10138 (set_attr "mode" "SI")])
10140 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10142 [(set (match_operand:DI 0 "register_operand")
10144 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10145 (match_operand:QI 2 "register_operand"))))
10146 (clobber (reg:CC FLAGS_REG))]
10147 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10148 [(set (match_dup 0)
10149 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10150 "operands[2] = gen_lowpart (SImode, operands[2]);")
10152 (define_insn "*<shift_insn><mode>3_1"
10153 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10155 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10156 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10157 (clobber (reg:CC FLAGS_REG))]
10158 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10160 if (operands[2] == const1_rtx
10161 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10162 return "<shift>{<imodesuffix>}\t%0";
10164 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10166 [(set_attr "type" "ishift")
10167 (set (attr "length_immediate")
10169 (and (match_operand 2 "const1_operand")
10170 (ior (match_test "TARGET_SHIFT1")
10171 (match_test "optimize_function_for_size_p (cfun)")))
10173 (const_string "*")))
10174 (set_attr "mode" "<MODE>")])
10176 (define_insn "*<shift_insn>qi3_1_slp"
10177 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10178 (any_shiftrt:QI (match_dup 0)
10179 (match_operand:QI 1 "nonmemory_operand" "cI")))
10180 (clobber (reg:CC FLAGS_REG))]
10181 "(optimize_function_for_size_p (cfun)
10182 || !TARGET_PARTIAL_REG_STALL
10183 || (operands[1] == const1_rtx
10184 && TARGET_SHIFT1))"
10186 if (operands[1] == const1_rtx
10187 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10188 return "<shift>{b}\t%0";
10190 return "<shift>{b}\t{%1, %0|%0, %1}";
10192 [(set_attr "type" "ishift1")
10193 (set (attr "length_immediate")
10195 (and (match_operand 1 "const1_operand")
10196 (ior (match_test "TARGET_SHIFT1")
10197 (match_test "optimize_function_for_size_p (cfun)")))
10199 (const_string "*")))
10200 (set_attr "mode" "QI")])
10202 ;; This pattern can't accept a variable shift count, since shifts by
10203 ;; zero don't affect the flags. We assume that shifts by constant
10204 ;; zero are optimized away.
10205 (define_insn "*<shift_insn><mode>3_cmp"
10206 [(set (reg FLAGS_REG)
10209 (match_operand:SWI 1 "nonimmediate_operand" "0")
10210 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10212 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10213 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10214 "(optimize_function_for_size_p (cfun)
10215 || !TARGET_PARTIAL_FLAG_REG_STALL
10216 || (operands[2] == const1_rtx
10218 && ix86_match_ccmode (insn, CCGOCmode)
10219 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10221 if (operands[2] == const1_rtx
10222 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10223 return "<shift>{<imodesuffix>}\t%0";
10225 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10227 [(set_attr "type" "ishift")
10228 (set (attr "length_immediate")
10230 (and (match_operand 2 "const1_operand")
10231 (ior (match_test "TARGET_SHIFT1")
10232 (match_test "optimize_function_for_size_p (cfun)")))
10234 (const_string "*")))
10235 (set_attr "mode" "<MODE>")])
10237 (define_insn "*<shift_insn>si3_cmp_zext"
10238 [(set (reg FLAGS_REG)
10240 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10241 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10243 (set (match_operand:DI 0 "register_operand" "=r")
10244 (zero_extend:DI (any_shiftrt:SI (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>, SImode, operands)"
10253 if (operands[2] == const1_rtx
10254 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10255 return "<shift>{l}\t%k0";
10257 return "<shift>{l}\t{%2, %k0|%k0, %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" "SI")])
10269 (define_insn "*<shift_insn><mode>3_cconly"
10270 [(set (reg FLAGS_REG)
10273 (match_operand:SWI 1 "register_operand" "0")
10274 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10276 (clobber (match_scratch:SWI 0 "=<r>"))]
10277 "(optimize_function_for_size_p (cfun)
10278 || !TARGET_PARTIAL_FLAG_REG_STALL
10279 || (operands[2] == const1_rtx
10281 && ix86_match_ccmode (insn, CCGOCmode)"
10283 if (operands[2] == const1_rtx
10284 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10285 return "<shift>{<imodesuffix>}\t%0";
10287 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10289 [(set_attr "type" "ishift")
10290 (set (attr "length_immediate")
10292 (and (match_operand 2 "const1_operand")
10293 (ior (match_test "TARGET_SHIFT1")
10294 (match_test "optimize_function_for_size_p (cfun)")))
10296 (const_string "*")))
10297 (set_attr "mode" "<MODE>")])
10299 ;; Rotate instructions
10301 (define_expand "<rotate_insn>ti3"
10302 [(set (match_operand:TI 0 "register_operand")
10303 (any_rotate:TI (match_operand:TI 1 "register_operand")
10304 (match_operand:QI 2 "nonmemory_operand")))]
10307 if (const_1_to_63_operand (operands[2], VOIDmode))
10308 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10309 (operands[0], operands[1], operands[2]));
10316 (define_expand "<rotate_insn>di3"
10317 [(set (match_operand:DI 0 "shiftdi_operand")
10318 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10319 (match_operand:QI 2 "nonmemory_operand")))]
10323 ix86_expand_binary_operator (<CODE>, DImode, operands);
10324 else if (const_1_to_31_operand (operands[2], VOIDmode))
10325 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10326 (operands[0], operands[1], operands[2]));
10333 (define_expand "<rotate_insn><mode>3"
10334 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10335 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10336 (match_operand:QI 2 "nonmemory_operand")))]
10338 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10340 ;; Avoid useless masking of count operand.
10341 (define_insn "*<rotate_insn><mode>3_mask"
10342 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10344 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10347 (match_operand:SI 2 "register_operand" "c")
10348 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10349 (clobber (reg:CC FLAGS_REG))]
10350 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10351 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10352 == GET_MODE_BITSIZE (<MODE>mode)-1"
10354 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10356 [(set_attr "type" "rotate")
10357 (set_attr "mode" "<MODE>")])
10359 ;; Implement rotation using two double-precision
10360 ;; shift instructions and a scratch register.
10362 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10363 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10364 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10365 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10366 (clobber (reg:CC FLAGS_REG))
10367 (clobber (match_scratch:DWIH 3 "=&r"))]
10371 [(set (match_dup 3) (match_dup 4))
10373 [(set (match_dup 4)
10374 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10375 (lshiftrt:DWIH (match_dup 5)
10376 (minus:QI (match_dup 6) (match_dup 2)))))
10377 (clobber (reg:CC FLAGS_REG))])
10379 [(set (match_dup 5)
10380 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10381 (lshiftrt:DWIH (match_dup 3)
10382 (minus:QI (match_dup 6) (match_dup 2)))))
10383 (clobber (reg:CC FLAGS_REG))])]
10385 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10387 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10390 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10391 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10392 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10393 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10394 (clobber (reg:CC FLAGS_REG))
10395 (clobber (match_scratch:DWIH 3 "=&r"))]
10399 [(set (match_dup 3) (match_dup 4))
10401 [(set (match_dup 4)
10402 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10403 (ashift:DWIH (match_dup 5)
10404 (minus:QI (match_dup 6) (match_dup 2)))))
10405 (clobber (reg:CC FLAGS_REG))])
10407 [(set (match_dup 5)
10408 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10409 (ashift:DWIH (match_dup 3)
10410 (minus:QI (match_dup 6) (match_dup 2)))))
10411 (clobber (reg:CC FLAGS_REG))])]
10413 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10415 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10418 (define_insn "*bmi2_rorx<mode>3_1"
10419 [(set (match_operand:SWI48 0 "register_operand" "=r")
10420 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10421 (match_operand:QI 2 "immediate_operand" "<S>")))]
10423 "rorx\t{%2, %1, %0|%0, %1, %2}"
10424 [(set_attr "type" "rotatex")
10425 (set_attr "mode" "<MODE>")])
10427 (define_insn "*<rotate_insn><mode>3_1"
10428 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10430 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10431 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10432 (clobber (reg:CC FLAGS_REG))]
10433 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10435 switch (get_attr_type (insn))
10441 if (operands[2] == const1_rtx
10442 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10443 return "<rotate>{<imodesuffix>}\t%0";
10445 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10448 [(set_attr "isa" "*,bmi2")
10449 (set_attr "type" "rotate,rotatex")
10450 (set (attr "length_immediate")
10452 (and (eq_attr "type" "rotate")
10453 (and (match_operand 2 "const1_operand")
10454 (ior (match_test "TARGET_SHIFT1")
10455 (match_test "optimize_function_for_size_p (cfun)"))))
10457 (const_string "*")))
10458 (set_attr "mode" "<MODE>")])
10460 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10462 [(set (match_operand:SWI48 0 "register_operand")
10463 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10464 (match_operand:QI 2 "immediate_operand")))
10465 (clobber (reg:CC FLAGS_REG))]
10466 "TARGET_BMI2 && reload_completed"
10467 [(set (match_dup 0)
10468 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10471 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10475 [(set (match_operand:SWI48 0 "register_operand")
10476 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10477 (match_operand:QI 2 "immediate_operand")))
10478 (clobber (reg:CC FLAGS_REG))]
10479 "TARGET_BMI2 && reload_completed"
10480 [(set (match_dup 0)
10481 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10483 (define_insn "*bmi2_rorxsi3_1_zext"
10484 [(set (match_operand:DI 0 "register_operand" "=r")
10486 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10487 (match_operand:QI 2 "immediate_operand" "I"))))]
10488 "TARGET_64BIT && TARGET_BMI2"
10489 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10490 [(set_attr "type" "rotatex")
10491 (set_attr "mode" "SI")])
10493 (define_insn "*<rotate_insn>si3_1_zext"
10494 [(set (match_operand:DI 0 "register_operand" "=r,r")
10496 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10497 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10498 (clobber (reg:CC FLAGS_REG))]
10499 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10501 switch (get_attr_type (insn))
10507 if (operands[2] == const1_rtx
10508 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10509 return "<rotate>{l}\t%k0";
10511 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10514 [(set_attr "isa" "*,bmi2")
10515 (set_attr "type" "rotate,rotatex")
10516 (set (attr "length_immediate")
10518 (and (eq_attr "type" "rotate")
10519 (and (match_operand 2 "const1_operand")
10520 (ior (match_test "TARGET_SHIFT1")
10521 (match_test "optimize_function_for_size_p (cfun)"))))
10523 (const_string "*")))
10524 (set_attr "mode" "SI")])
10526 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10528 [(set (match_operand:DI 0 "register_operand")
10530 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10531 (match_operand:QI 2 "immediate_operand"))))
10532 (clobber (reg:CC FLAGS_REG))]
10533 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10534 [(set (match_dup 0)
10535 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10538 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10542 [(set (match_operand:DI 0 "register_operand")
10544 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10545 (match_operand:QI 2 "immediate_operand"))))
10546 (clobber (reg:CC FLAGS_REG))]
10547 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10548 [(set (match_dup 0)
10549 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10551 (define_insn "*<rotate_insn><mode>3_1"
10552 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10553 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10554 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10555 (clobber (reg:CC FLAGS_REG))]
10556 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10558 if (operands[2] == const1_rtx
10559 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10560 return "<rotate>{<imodesuffix>}\t%0";
10562 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10564 [(set_attr "type" "rotate")
10565 (set (attr "length_immediate")
10567 (and (match_operand 2 "const1_operand")
10568 (ior (match_test "TARGET_SHIFT1")
10569 (match_test "optimize_function_for_size_p (cfun)")))
10571 (const_string "*")))
10572 (set_attr "mode" "<MODE>")])
10574 (define_insn "*<rotate_insn>qi3_1_slp"
10575 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10576 (any_rotate:QI (match_dup 0)
10577 (match_operand:QI 1 "nonmemory_operand" "cI")))
10578 (clobber (reg:CC FLAGS_REG))]
10579 "(optimize_function_for_size_p (cfun)
10580 || !TARGET_PARTIAL_REG_STALL
10581 || (operands[1] == const1_rtx
10582 && TARGET_SHIFT1))"
10584 if (operands[1] == const1_rtx
10585 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10586 return "<rotate>{b}\t%0";
10588 return "<rotate>{b}\t{%1, %0|%0, %1}";
10590 [(set_attr "type" "rotate1")
10591 (set (attr "length_immediate")
10593 (and (match_operand 1 "const1_operand")
10594 (ior (match_test "TARGET_SHIFT1")
10595 (match_test "optimize_function_for_size_p (cfun)")))
10597 (const_string "*")))
10598 (set_attr "mode" "QI")])
10601 [(set (match_operand:HI 0 "register_operand")
10602 (any_rotate:HI (match_dup 0) (const_int 8)))
10603 (clobber (reg:CC FLAGS_REG))]
10605 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10606 [(parallel [(set (strict_low_part (match_dup 0))
10607 (bswap:HI (match_dup 0)))
10608 (clobber (reg:CC FLAGS_REG))])])
10610 ;; Bit set / bit test instructions
10612 (define_expand "extv"
10613 [(set (match_operand:SI 0 "register_operand")
10614 (sign_extract:SI (match_operand:SI 1 "register_operand")
10615 (match_operand:SI 2 "const8_operand")
10616 (match_operand:SI 3 "const8_operand")))]
10619 /* Handle extractions from %ah et al. */
10620 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10623 /* From mips.md: extract_bit_field doesn't verify that our source
10624 matches the predicate, so check it again here. */
10625 if (! ext_register_operand (operands[1], VOIDmode))
10629 (define_expand "extzv"
10630 [(set (match_operand:SI 0 "register_operand")
10631 (zero_extract:SI (match_operand 1 "ext_register_operand")
10632 (match_operand:SI 2 "const8_operand")
10633 (match_operand:SI 3 "const8_operand")))]
10636 /* Handle extractions from %ah et al. */
10637 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10640 /* From mips.md: extract_bit_field doesn't verify that our source
10641 matches the predicate, so check it again here. */
10642 if (! ext_register_operand (operands[1], VOIDmode))
10646 (define_expand "insv"
10647 [(set (zero_extract (match_operand 0 "register_operand")
10648 (match_operand 1 "const_int_operand")
10649 (match_operand 2 "const_int_operand"))
10650 (match_operand 3 "register_operand"))]
10653 rtx (*gen_mov_insv_1) (rtx, rtx);
10655 if (ix86_expand_pinsr (operands))
10658 /* Handle insertions to %ah et al. */
10659 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10662 /* From mips.md: insert_bit_field doesn't verify that our source
10663 matches the predicate, so check it again here. */
10664 if (! ext_register_operand (operands[0], VOIDmode))
10667 gen_mov_insv_1 = (TARGET_64BIT
10668 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10670 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10674 ;; %%% bts, btr, btc, bt.
10675 ;; In general these instructions are *slow* when applied to memory,
10676 ;; since they enforce atomic operation. When applied to registers,
10677 ;; it depends on the cpu implementation. They're never faster than
10678 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10679 ;; no point. But in 64-bit, we can't hold the relevant immediates
10680 ;; within the instruction itself, so operating on bits in the high
10681 ;; 32-bits of a register becomes easier.
10683 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10684 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10685 ;; negdf respectively, so they can never be disabled entirely.
10687 (define_insn "*btsq"
10688 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10690 (match_operand:DI 1 "const_0_to_63_operand"))
10692 (clobber (reg:CC FLAGS_REG))]
10693 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10694 "bts{q}\t{%1, %0|%0, %1}"
10695 [(set_attr "type" "alu1")
10696 (set_attr "prefix_0f" "1")
10697 (set_attr "mode" "DI")])
10699 (define_insn "*btrq"
10700 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10702 (match_operand:DI 1 "const_0_to_63_operand"))
10704 (clobber (reg:CC FLAGS_REG))]
10705 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10706 "btr{q}\t{%1, %0|%0, %1}"
10707 [(set_attr "type" "alu1")
10708 (set_attr "prefix_0f" "1")
10709 (set_attr "mode" "DI")])
10711 (define_insn "*btcq"
10712 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10714 (match_operand:DI 1 "const_0_to_63_operand"))
10715 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10716 (clobber (reg:CC FLAGS_REG))]
10717 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10718 "btc{q}\t{%1, %0|%0, %1}"
10719 [(set_attr "type" "alu1")
10720 (set_attr "prefix_0f" "1")
10721 (set_attr "mode" "DI")])
10723 ;; Allow Nocona to avoid these instructions if a register is available.
10726 [(match_scratch:DI 2 "r")
10727 (parallel [(set (zero_extract:DI
10728 (match_operand:DI 0 "register_operand")
10730 (match_operand:DI 1 "const_0_to_63_operand"))
10732 (clobber (reg:CC FLAGS_REG))])]
10733 "TARGET_64BIT && !TARGET_USE_BT"
10736 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10739 if (HOST_BITS_PER_WIDE_INT >= 64)
10740 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10741 else if (i < HOST_BITS_PER_WIDE_INT)
10742 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10744 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10746 op1 = immed_double_const (lo, hi, DImode);
10749 emit_move_insn (operands[2], op1);
10753 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10758 [(match_scratch:DI 2 "r")
10759 (parallel [(set (zero_extract:DI
10760 (match_operand:DI 0 "register_operand")
10762 (match_operand:DI 1 "const_0_to_63_operand"))
10764 (clobber (reg:CC FLAGS_REG))])]
10765 "TARGET_64BIT && !TARGET_USE_BT"
10768 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10771 if (HOST_BITS_PER_WIDE_INT >= 64)
10772 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10773 else if (i < HOST_BITS_PER_WIDE_INT)
10774 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10776 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10778 op1 = immed_double_const (~lo, ~hi, DImode);
10781 emit_move_insn (operands[2], op1);
10785 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10790 [(match_scratch:DI 2 "r")
10791 (parallel [(set (zero_extract:DI
10792 (match_operand:DI 0 "register_operand")
10794 (match_operand:DI 1 "const_0_to_63_operand"))
10795 (not:DI (zero_extract:DI
10796 (match_dup 0) (const_int 1) (match_dup 1))))
10797 (clobber (reg:CC FLAGS_REG))])]
10798 "TARGET_64BIT && !TARGET_USE_BT"
10801 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10804 if (HOST_BITS_PER_WIDE_INT >= 64)
10805 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10806 else if (i < HOST_BITS_PER_WIDE_INT)
10807 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10809 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10811 op1 = immed_double_const (lo, hi, DImode);
10814 emit_move_insn (operands[2], op1);
10818 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10822 (define_insn "*bt<mode>"
10823 [(set (reg:CCC FLAGS_REG)
10825 (zero_extract:SWI48
10826 (match_operand:SWI48 0 "register_operand" "r")
10828 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10830 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10831 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10832 [(set_attr "type" "alu1")
10833 (set_attr "prefix_0f" "1")
10834 (set_attr "mode" "<MODE>")])
10836 ;; Store-flag instructions.
10838 ;; For all sCOND expanders, also expand the compare or test insn that
10839 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10841 (define_insn_and_split "*setcc_di_1"
10842 [(set (match_operand:DI 0 "register_operand" "=q")
10843 (match_operator:DI 1 "ix86_comparison_operator"
10844 [(reg FLAGS_REG) (const_int 0)]))]
10845 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10847 "&& reload_completed"
10848 [(set (match_dup 2) (match_dup 1))
10849 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10851 operands[1] = shallow_copy_rtx (operands[1]);
10852 PUT_MODE (operands[1], QImode);
10853 operands[2] = gen_lowpart (QImode, operands[0]);
10856 (define_insn_and_split "*setcc_si_1_and"
10857 [(set (match_operand:SI 0 "register_operand" "=q")
10858 (match_operator:SI 1 "ix86_comparison_operator"
10859 [(reg FLAGS_REG) (const_int 0)]))
10860 (clobber (reg:CC FLAGS_REG))]
10861 "!TARGET_PARTIAL_REG_STALL
10862 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10864 "&& reload_completed"
10865 [(set (match_dup 2) (match_dup 1))
10866 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10867 (clobber (reg:CC FLAGS_REG))])]
10869 operands[1] = shallow_copy_rtx (operands[1]);
10870 PUT_MODE (operands[1], QImode);
10871 operands[2] = gen_lowpart (QImode, operands[0]);
10874 (define_insn_and_split "*setcc_si_1_movzbl"
10875 [(set (match_operand:SI 0 "register_operand" "=q")
10876 (match_operator:SI 1 "ix86_comparison_operator"
10877 [(reg FLAGS_REG) (const_int 0)]))]
10878 "!TARGET_PARTIAL_REG_STALL
10879 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10881 "&& reload_completed"
10882 [(set (match_dup 2) (match_dup 1))
10883 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10885 operands[1] = shallow_copy_rtx (operands[1]);
10886 PUT_MODE (operands[1], QImode);
10887 operands[2] = gen_lowpart (QImode, operands[0]);
10890 (define_insn "*setcc_qi"
10891 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10892 (match_operator:QI 1 "ix86_comparison_operator"
10893 [(reg FLAGS_REG) (const_int 0)]))]
10896 [(set_attr "type" "setcc")
10897 (set_attr "mode" "QI")])
10899 (define_insn "*setcc_qi_slp"
10900 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10901 (match_operator:QI 1 "ix86_comparison_operator"
10902 [(reg FLAGS_REG) (const_int 0)]))]
10905 [(set_attr "type" "setcc")
10906 (set_attr "mode" "QI")])
10908 ;; In general it is not safe to assume too much about CCmode registers,
10909 ;; so simplify-rtx stops when it sees a second one. Under certain
10910 ;; conditions this is safe on x86, so help combine not create
10917 [(set (match_operand:QI 0 "nonimmediate_operand")
10918 (ne:QI (match_operator 1 "ix86_comparison_operator"
10919 [(reg FLAGS_REG) (const_int 0)])
10922 [(set (match_dup 0) (match_dup 1))]
10924 operands[1] = shallow_copy_rtx (operands[1]);
10925 PUT_MODE (operands[1], QImode);
10929 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10930 (ne:QI (match_operator 1 "ix86_comparison_operator"
10931 [(reg FLAGS_REG) (const_int 0)])
10934 [(set (match_dup 0) (match_dup 1))]
10936 operands[1] = shallow_copy_rtx (operands[1]);
10937 PUT_MODE (operands[1], QImode);
10941 [(set (match_operand:QI 0 "nonimmediate_operand")
10942 (eq:QI (match_operator 1 "ix86_comparison_operator"
10943 [(reg FLAGS_REG) (const_int 0)])
10946 [(set (match_dup 0) (match_dup 1))]
10948 operands[1] = shallow_copy_rtx (operands[1]);
10949 PUT_MODE (operands[1], QImode);
10950 PUT_CODE (operands[1],
10951 ix86_reverse_condition (GET_CODE (operands[1]),
10952 GET_MODE (XEXP (operands[1], 0))));
10954 /* Make sure that (a) the CCmode we have for the flags is strong
10955 enough for the reversed compare or (b) we have a valid FP compare. */
10956 if (! ix86_comparison_operator (operands[1], VOIDmode))
10961 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10962 (eq:QI (match_operator 1 "ix86_comparison_operator"
10963 [(reg FLAGS_REG) (const_int 0)])
10966 [(set (match_dup 0) (match_dup 1))]
10968 operands[1] = shallow_copy_rtx (operands[1]);
10969 PUT_MODE (operands[1], QImode);
10970 PUT_CODE (operands[1],
10971 ix86_reverse_condition (GET_CODE (operands[1]),
10972 GET_MODE (XEXP (operands[1], 0))));
10974 /* Make sure that (a) the CCmode we have for the flags is strong
10975 enough for the reversed compare or (b) we have a valid FP compare. */
10976 if (! ix86_comparison_operator (operands[1], VOIDmode))
10980 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10981 ;; subsequent logical operations are used to imitate conditional moves.
10982 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10985 (define_insn "setcc_<mode>_sse"
10986 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10987 (match_operator:MODEF 3 "sse_comparison_operator"
10988 [(match_operand:MODEF 1 "register_operand" "0,x")
10989 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10990 "SSE_FLOAT_MODE_P (<MODE>mode)"
10992 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10993 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10994 [(set_attr "isa" "noavx,avx")
10995 (set_attr "type" "ssecmp")
10996 (set_attr "length_immediate" "1")
10997 (set_attr "prefix" "orig,vex")
10998 (set_attr "mode" "<MODE>")])
11000 ;; Basic conditional jump instructions.
11001 ;; We ignore the overflow flag for signed branch instructions.
11003 (define_insn "*jcc_1_bnd"
11005 (if_then_else (match_operator 1 "ix86_comparison_operator"
11006 [(reg FLAGS_REG) (const_int 0)])
11007 (label_ref (match_operand 0))
11009 "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
11011 [(set_attr "type" "ibr")
11012 (set_attr "modrm" "0")
11013 (set (attr "length")
11014 (if_then_else (and (ge (minus (match_dup 0) (pc))
11016 (lt (minus (match_dup 0) (pc))
11021 (define_insn "*jcc_1"
11023 (if_then_else (match_operator 1 "ix86_comparison_operator"
11024 [(reg FLAGS_REG) (const_int 0)])
11025 (label_ref (match_operand 0))
11029 [(set_attr "type" "ibr")
11030 (set_attr "modrm" "0")
11031 (set (attr "length")
11032 (if_then_else (and (ge (minus (match_dup 0) (pc))
11034 (lt (minus (match_dup 0) (pc))
11039 (define_insn "*jcc_2_bnd"
11041 (if_then_else (match_operator 1 "ix86_comparison_operator"
11042 [(reg FLAGS_REG) (const_int 0)])
11044 (label_ref (match_operand 0))))]
11045 "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
11047 [(set_attr "type" "ibr")
11048 (set_attr "modrm" "0")
11049 (set (attr "length")
11050 (if_then_else (and (ge (minus (match_dup 0) (pc))
11052 (lt (minus (match_dup 0) (pc))
11057 (define_insn "*jcc_2"
11059 (if_then_else (match_operator 1 "ix86_comparison_operator"
11060 [(reg FLAGS_REG) (const_int 0)])
11062 (label_ref (match_operand 0))))]
11065 [(set_attr "type" "ibr")
11066 (set_attr "modrm" "0")
11067 (set (attr "length")
11068 (if_then_else (and (ge (minus (match_dup 0) (pc))
11070 (lt (minus (match_dup 0) (pc))
11075 ;; In general it is not safe to assume too much about CCmode registers,
11076 ;; so simplify-rtx stops when it sees a second one. Under certain
11077 ;; conditions this is safe on x86, so help combine not create
11085 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11086 [(reg FLAGS_REG) (const_int 0)])
11088 (label_ref (match_operand 1))
11092 (if_then_else (match_dup 0)
11093 (label_ref (match_dup 1))
11096 operands[0] = shallow_copy_rtx (operands[0]);
11097 PUT_MODE (operands[0], VOIDmode);
11102 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11103 [(reg FLAGS_REG) (const_int 0)])
11105 (label_ref (match_operand 1))
11109 (if_then_else (match_dup 0)
11110 (label_ref (match_dup 1))
11113 operands[0] = shallow_copy_rtx (operands[0]);
11114 PUT_MODE (operands[0], VOIDmode);
11115 PUT_CODE (operands[0],
11116 ix86_reverse_condition (GET_CODE (operands[0]),
11117 GET_MODE (XEXP (operands[0], 0))));
11119 /* Make sure that (a) the CCmode we have for the flags is strong
11120 enough for the reversed compare or (b) we have a valid FP compare. */
11121 if (! ix86_comparison_operator (operands[0], VOIDmode))
11125 ;; zero_extend in SImode is correct also for DImode, since this is what combine
11126 ;; pass generates from shift insn with QImode operand. Actually, the mode
11127 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
11128 ;; appropriate modulo of the bit offset value.
11130 (define_insn_and_split "*jcc_bt<mode>"
11132 (if_then_else (match_operator 0 "bt_comparison_operator"
11133 [(zero_extract:SWI48
11134 (match_operand:SWI48 1 "register_operand" "r")
11137 (match_operand:QI 2 "register_operand" "r")))
11139 (label_ref (match_operand 3))
11141 (clobber (reg:CC FLAGS_REG))]
11142 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11145 [(set (reg:CCC FLAGS_REG)
11147 (zero_extract:SWI48
11153 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11154 (label_ref (match_dup 3))
11157 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
11158 operands[0] = shallow_copy_rtx (operands[0]);
11159 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11162 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
11163 ;; zero extended to SImode.
11164 (define_insn_and_split "*jcc_bt<mode>_1"
11166 (if_then_else (match_operator 0 "bt_comparison_operator"
11167 [(zero_extract:SWI48
11168 (match_operand:SWI48 1 "register_operand" "r")
11170 (match_operand:SI 2 "register_operand" "r"))
11172 (label_ref (match_operand 3))
11174 (clobber (reg:CC FLAGS_REG))]
11175 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11178 [(set (reg:CCC FLAGS_REG)
11180 (zero_extract:SWI48
11186 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11187 (label_ref (match_dup 3))
11190 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11191 operands[0] = shallow_copy_rtx (operands[0]);
11192 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11195 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
11196 ;; also for DImode, this is what combine produces.
11197 (define_insn_and_split "*jcc_bt<mode>_mask"
11199 (if_then_else (match_operator 0 "bt_comparison_operator"
11200 [(zero_extract:SWI48
11201 (match_operand:SWI48 1 "register_operand" "r")
11204 (match_operand:SI 2 "register_operand" "r")
11205 (match_operand:SI 3 "const_int_operand" "n")))])
11206 (label_ref (match_operand 4))
11208 (clobber (reg:CC FLAGS_REG))]
11209 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11210 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11211 == GET_MODE_BITSIZE (<MODE>mode)-1"
11214 [(set (reg:CCC FLAGS_REG)
11216 (zero_extract:SWI48
11222 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11223 (label_ref (match_dup 4))
11226 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11227 operands[0] = shallow_copy_rtx (operands[0]);
11228 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11231 (define_insn_and_split "*jcc_btsi_1"
11233 (if_then_else (match_operator 0 "bt_comparison_operator"
11236 (match_operand:SI 1 "register_operand" "r")
11237 (match_operand:QI 2 "register_operand" "r"))
11240 (label_ref (match_operand 3))
11242 (clobber (reg:CC FLAGS_REG))]
11243 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11246 [(set (reg:CCC FLAGS_REG)
11254 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11255 (label_ref (match_dup 3))
11258 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11259 operands[0] = shallow_copy_rtx (operands[0]);
11260 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11263 ;; avoid useless masking of bit offset operand
11264 (define_insn_and_split "*jcc_btsi_mask_1"
11267 (match_operator 0 "bt_comparison_operator"
11270 (match_operand:SI 1 "register_operand" "r")
11273 (match_operand:SI 2 "register_operand" "r")
11274 (match_operand:SI 3 "const_int_operand" "n")) 0))
11277 (label_ref (match_operand 4))
11279 (clobber (reg:CC FLAGS_REG))]
11280 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11281 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11284 [(set (reg:CCC FLAGS_REG)
11292 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11293 (label_ref (match_dup 4))
11296 operands[0] = shallow_copy_rtx (operands[0]);
11297 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11300 ;; Define combination compare-and-branch fp compare instructions to help
11303 (define_insn "*jcc<mode>_0_i387"
11305 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11306 [(match_operand:X87MODEF 1 "register_operand" "f")
11307 (match_operand:X87MODEF 2 "const0_operand")])
11308 (label_ref (match_operand 3))
11310 (clobber (reg:CCFP FPSR_REG))
11311 (clobber (reg:CCFP FLAGS_REG))
11312 (clobber (match_scratch:HI 4 "=a"))]
11313 "TARGET_80387 && !TARGET_CMOVE"
11316 (define_insn "*jcc<mode>_0_r_i387"
11318 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11319 [(match_operand:X87MODEF 1 "register_operand" "f")
11320 (match_operand:X87MODEF 2 "const0_operand")])
11322 (label_ref (match_operand 3))))
11323 (clobber (reg:CCFP FPSR_REG))
11324 (clobber (reg:CCFP FLAGS_REG))
11325 (clobber (match_scratch:HI 4 "=a"))]
11326 "TARGET_80387 && !TARGET_CMOVE"
11329 (define_insn "*jccxf_i387"
11331 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11332 [(match_operand:XF 1 "register_operand" "f")
11333 (match_operand:XF 2 "register_operand" "f")])
11334 (label_ref (match_operand 3))
11336 (clobber (reg:CCFP FPSR_REG))
11337 (clobber (reg:CCFP FLAGS_REG))
11338 (clobber (match_scratch:HI 4 "=a"))]
11339 "TARGET_80387 && !TARGET_CMOVE"
11342 (define_insn "*jccxf_r_i387"
11344 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11345 [(match_operand:XF 1 "register_operand" "f")
11346 (match_operand:XF 2 "register_operand" "f")])
11348 (label_ref (match_operand 3))))
11349 (clobber (reg:CCFP FPSR_REG))
11350 (clobber (reg:CCFP FLAGS_REG))
11351 (clobber (match_scratch:HI 4 "=a"))]
11352 "TARGET_80387 && !TARGET_CMOVE"
11355 (define_insn "*jcc<mode>_i387"
11357 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11358 [(match_operand:MODEF 1 "register_operand" "f")
11359 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11360 (label_ref (match_operand 3))
11362 (clobber (reg:CCFP FPSR_REG))
11363 (clobber (reg:CCFP FLAGS_REG))
11364 (clobber (match_scratch:HI 4 "=a"))]
11365 "TARGET_80387 && !TARGET_CMOVE"
11368 (define_insn "*jcc<mode>_r_i387"
11370 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11371 [(match_operand:MODEF 1 "register_operand" "f")
11372 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11374 (label_ref (match_operand 3))))
11375 (clobber (reg:CCFP FPSR_REG))
11376 (clobber (reg:CCFP FLAGS_REG))
11377 (clobber (match_scratch:HI 4 "=a"))]
11378 "TARGET_80387 && !TARGET_CMOVE"
11381 (define_insn "*jccu<mode>_i387"
11383 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11384 [(match_operand:X87MODEF 1 "register_operand" "f")
11385 (match_operand:X87MODEF 2 "register_operand" "f")])
11386 (label_ref (match_operand 3))
11388 (clobber (reg:CCFP FPSR_REG))
11389 (clobber (reg:CCFP FLAGS_REG))
11390 (clobber (match_scratch:HI 4 "=a"))]
11391 "TARGET_80387 && !TARGET_CMOVE"
11394 (define_insn "*jccu<mode>_r_i387"
11396 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11397 [(match_operand:X87MODEF 1 "register_operand" "f")
11398 (match_operand:X87MODEF 2 "register_operand" "f")])
11400 (label_ref (match_operand 3))))
11401 (clobber (reg:CCFP FPSR_REG))
11402 (clobber (reg:CCFP FLAGS_REG))
11403 (clobber (match_scratch:HI 4 "=a"))]
11404 "TARGET_80387 && !TARGET_CMOVE"
11409 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11410 [(match_operand:X87MODEF 1 "register_operand")
11411 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11413 (match_operand 4)))
11414 (clobber (reg:CCFP FPSR_REG))
11415 (clobber (reg:CCFP FLAGS_REG))]
11416 "TARGET_80387 && !TARGET_CMOVE
11417 && reload_completed"
11420 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11421 operands[3], operands[4], NULL_RTX);
11427 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11428 [(match_operand:X87MODEF 1 "register_operand")
11429 (match_operand:X87MODEF 2 "general_operand")])
11431 (match_operand 4)))
11432 (clobber (reg:CCFP FPSR_REG))
11433 (clobber (reg:CCFP FLAGS_REG))
11434 (clobber (match_scratch:HI 5))]
11435 "TARGET_80387 && !TARGET_CMOVE
11436 && reload_completed"
11439 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11440 operands[3], operands[4], operands[5]);
11444 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11445 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11446 ;; with a precedence over other operators and is always put in the first
11447 ;; place. Swap condition and operands to match ficom instruction.
11449 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11452 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11453 [(match_operator:X87MODEF 1 "float_operator"
11454 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11455 (match_operand:X87MODEF 3 "register_operand" "f")])
11456 (label_ref (match_operand 4))
11458 (clobber (reg:CCFP FPSR_REG))
11459 (clobber (reg:CCFP FLAGS_REG))
11460 (clobber (match_scratch:HI 5 "=a"))]
11461 "TARGET_80387 && !TARGET_CMOVE
11462 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11463 || optimize_function_for_size_p (cfun))"
11466 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11469 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11470 [(match_operator:X87MODEF 1 "float_operator"
11471 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11472 (match_operand:X87MODEF 3 "register_operand" "f")])
11474 (label_ref (match_operand 4))))
11475 (clobber (reg:CCFP FPSR_REG))
11476 (clobber (reg:CCFP FLAGS_REG))
11477 (clobber (match_scratch:HI 5 "=a"))]
11478 "TARGET_80387 && !TARGET_CMOVE
11479 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11480 || optimize_function_for_size_p (cfun))"
11486 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11487 [(match_operator:X87MODEF 1 "float_operator"
11488 [(match_operand:SWI24 2 "memory_operand")])
11489 (match_operand:X87MODEF 3 "register_operand")])
11491 (match_operand 5)))
11492 (clobber (reg:CCFP FPSR_REG))
11493 (clobber (reg:CCFP FLAGS_REG))
11494 (clobber (match_scratch:HI 6))]
11495 "TARGET_80387 && !TARGET_CMOVE
11496 && reload_completed"
11499 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11500 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11501 operands[4], operands[5], operands[6]);
11505 ;; Unconditional and other jump instructions
11507 (define_insn "jump_bnd"
11509 (label_ref (match_operand 0)))]
11510 "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
11512 [(set_attr "type" "ibr")
11513 (set (attr "length")
11514 (if_then_else (and (ge (minus (match_dup 0) (pc))
11516 (lt (minus (match_dup 0) (pc))
11520 (set_attr "modrm" "0")])
11522 (define_insn "jump"
11524 (label_ref (match_operand 0)))]
11527 [(set_attr "type" "ibr")
11528 (set (attr "length")
11529 (if_then_else (and (ge (minus (match_dup 0) (pc))
11531 (lt (minus (match_dup 0) (pc))
11535 (set_attr "modrm" "0")])
11537 (define_expand "indirect_jump"
11538 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11542 operands[0] = convert_memory_address (word_mode, operands[0]);
11545 (define_insn "*indirect_jump"
11546 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11549 [(set_attr "type" "ibr")
11550 (set_attr "length_immediate" "0")])
11552 (define_expand "tablejump"
11553 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11554 (use (label_ref (match_operand 1)))])]
11557 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11558 relative. Convert the relative address to an absolute address. */
11562 enum rtx_code code;
11564 /* We can't use @GOTOFF for text labels on VxWorks;
11565 see gotoff_operand. */
11566 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11570 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11572 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11576 op1 = pic_offset_table_rtx;
11581 op0 = pic_offset_table_rtx;
11585 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11590 operands[0] = convert_memory_address (word_mode, operands[0]);
11593 (define_insn "*tablejump_1"
11594 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11595 (use (label_ref (match_operand 1)))]
11598 [(set_attr "type" "ibr")
11599 (set_attr "length_immediate" "0")])
11601 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11604 [(set (reg FLAGS_REG) (match_operand 0))
11605 (set (match_operand:QI 1 "register_operand")
11606 (match_operator:QI 2 "ix86_comparison_operator"
11607 [(reg FLAGS_REG) (const_int 0)]))
11608 (set (match_operand 3 "q_regs_operand")
11609 (zero_extend (match_dup 1)))]
11610 "(peep2_reg_dead_p (3, operands[1])
11611 || operands_match_p (operands[1], operands[3]))
11612 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11613 [(set (match_dup 4) (match_dup 0))
11614 (set (strict_low_part (match_dup 5))
11617 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11618 operands[5] = gen_lowpart (QImode, operands[3]);
11619 ix86_expand_clear (operands[3]);
11623 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11624 (match_operand 4)])
11625 (set (match_operand:QI 1 "register_operand")
11626 (match_operator:QI 2 "ix86_comparison_operator"
11627 [(reg FLAGS_REG) (const_int 0)]))
11628 (set (match_operand 3 "q_regs_operand")
11629 (zero_extend (match_dup 1)))]
11630 "(peep2_reg_dead_p (3, operands[1])
11631 || operands_match_p (operands[1], operands[3]))
11632 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11633 [(parallel [(set (match_dup 5) (match_dup 0))
11635 (set (strict_low_part (match_dup 6))
11638 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11639 operands[6] = gen_lowpart (QImode, operands[3]);
11640 ix86_expand_clear (operands[3]);
11643 ;; Similar, but match zero extend with andsi3.
11646 [(set (reg FLAGS_REG) (match_operand 0))
11647 (set (match_operand:QI 1 "register_operand")
11648 (match_operator:QI 2 "ix86_comparison_operator"
11649 [(reg FLAGS_REG) (const_int 0)]))
11650 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11651 (and:SI (match_dup 3) (const_int 255)))
11652 (clobber (reg:CC FLAGS_REG))])]
11653 "REGNO (operands[1]) == REGNO (operands[3])
11654 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11655 [(set (match_dup 4) (match_dup 0))
11656 (set (strict_low_part (match_dup 5))
11659 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11660 operands[5] = gen_lowpart (QImode, operands[3]);
11661 ix86_expand_clear (operands[3]);
11665 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11666 (match_operand 4)])
11667 (set (match_operand:QI 1 "register_operand")
11668 (match_operator:QI 2 "ix86_comparison_operator"
11669 [(reg FLAGS_REG) (const_int 0)]))
11670 (parallel [(set (match_operand 3 "q_regs_operand")
11671 (zero_extend (match_dup 1)))
11672 (clobber (reg:CC FLAGS_REG))])]
11673 "(peep2_reg_dead_p (3, operands[1])
11674 || operands_match_p (operands[1], operands[3]))
11675 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11676 [(parallel [(set (match_dup 5) (match_dup 0))
11678 (set (strict_low_part (match_dup 6))
11681 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11682 operands[6] = gen_lowpart (QImode, operands[3]);
11683 ix86_expand_clear (operands[3]);
11686 ;; Call instructions.
11688 ;; The predicates normally associated with named expanders are not properly
11689 ;; checked for calls. This is a bug in the generic code, but it isn't that
11690 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11692 ;; P6 processors will jump to the address after the decrement when %esp
11693 ;; is used as a call operand, so they will execute return address as a code.
11694 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11696 ;; Register constraint for call instruction.
11697 (define_mode_attr c [(SI "l") (DI "r")])
11699 ;; Call subroutine returning no value.
11701 (define_expand "call"
11702 [(call (match_operand:QI 0)
11704 (use (match_operand 2))]
11707 ix86_expand_call (NULL, operands[0], operands[1],
11708 operands[2], NULL, false);
11712 (define_expand "sibcall"
11713 [(call (match_operand:QI 0)
11715 (use (match_operand 2))]
11718 ix86_expand_call (NULL, operands[0], operands[1],
11719 operands[2], NULL, true);
11723 (define_insn "*call"
11724 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11725 (match_operand 1))]
11726 "!SIBLING_CALL_P (insn)"
11727 "* return ix86_output_call_insn (insn, operands[0]);"
11728 [(set_attr "type" "call")])
11730 (define_insn "*sibcall"
11731 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11732 (match_operand 1))]
11733 "SIBLING_CALL_P (insn)"
11734 "* return ix86_output_call_insn (insn, operands[0]);"
11735 [(set_attr "type" "call")])
11737 (define_insn "*sibcall_memory"
11738 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11740 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11742 "* return ix86_output_call_insn (insn, operands[0]);"
11743 [(set_attr "type" "call")])
11746 [(set (match_operand:W 0 "register_operand")
11747 (match_operand:W 1 "memory_operand"))
11748 (call (mem:QI (match_dup 0))
11749 (match_operand 3))]
11750 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11751 && peep2_reg_dead_p (2, operands[0])"
11752 [(parallel [(call (mem:QI (match_dup 1))
11754 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11757 [(set (match_operand:W 0 "register_operand")
11758 (match_operand:W 1 "memory_operand"))
11759 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11760 (call (mem:QI (match_dup 0))
11761 (match_operand 3))]
11762 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11763 && peep2_reg_dead_p (3, operands[0])"
11764 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11765 (parallel [(call (mem:QI (match_dup 1))
11767 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11769 (define_expand "call_pop"
11770 [(parallel [(call (match_operand:QI 0)
11771 (match_operand:SI 1))
11772 (set (reg:SI SP_REG)
11773 (plus:SI (reg:SI SP_REG)
11774 (match_operand:SI 3)))])]
11777 ix86_expand_call (NULL, operands[0], operands[1],
11778 operands[2], operands[3], false);
11782 (define_insn "*call_pop"
11783 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
11785 (set (reg:SI SP_REG)
11786 (plus:SI (reg:SI SP_REG)
11787 (match_operand:SI 2 "immediate_operand" "i")))]
11788 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11789 "* return ix86_output_call_insn (insn, operands[0]);"
11790 [(set_attr "type" "call")])
11792 (define_insn "*sibcall_pop"
11793 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
11795 (set (reg:SI SP_REG)
11796 (plus:SI (reg:SI SP_REG)
11797 (match_operand:SI 2 "immediate_operand" "i")))]
11798 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11799 "* return ix86_output_call_insn (insn, operands[0]);"
11800 [(set_attr "type" "call")])
11802 (define_insn "*sibcall_pop_memory"
11803 [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
11805 (set (reg:SI SP_REG)
11806 (plus:SI (reg:SI SP_REG)
11807 (match_operand:SI 2 "immediate_operand" "i")))
11808 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11810 "* return ix86_output_call_insn (insn, operands[0]);"
11811 [(set_attr "type" "call")])
11814 [(set (match_operand:SI 0 "register_operand")
11815 (match_operand:SI 1 "memory_operand"))
11816 (parallel [(call (mem:QI (match_dup 0))
11818 (set (reg:SI SP_REG)
11819 (plus:SI (reg:SI SP_REG)
11820 (match_operand:SI 4 "immediate_operand")))])]
11821 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11822 && peep2_reg_dead_p (2, operands[0])"
11823 [(parallel [(call (mem:QI (match_dup 1))
11825 (set (reg:SI SP_REG)
11826 (plus:SI (reg:SI SP_REG)
11828 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11831 [(set (match_operand:SI 0 "register_operand")
11832 (match_operand:SI 1 "memory_operand"))
11833 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11834 (parallel [(call (mem:QI (match_dup 0))
11836 (set (reg:SI SP_REG)
11837 (plus:SI (reg:SI SP_REG)
11838 (match_operand:SI 4 "immediate_operand")))])]
11839 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11840 && peep2_reg_dead_p (3, operands[0])"
11841 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11842 (parallel [(call (mem:QI (match_dup 1))
11844 (set (reg:SI SP_REG)
11845 (plus:SI (reg:SI SP_REG)
11847 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11849 ;; Combining simple memory jump instruction
11852 [(set (match_operand:W 0 "register_operand")
11853 (match_operand:W 1 "memory_operand"))
11854 (set (pc) (match_dup 0))]
11855 "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
11856 [(set (pc) (match_dup 1))])
11858 ;; Call subroutine, returning value in operand 0
11860 (define_expand "call_value"
11861 [(set (match_operand 0)
11862 (call (match_operand:QI 1)
11863 (match_operand 2)))
11864 (use (match_operand 3))]
11867 ix86_expand_call (operands[0], operands[1], operands[2],
11868 operands[3], NULL, false);
11872 (define_expand "sibcall_value"
11873 [(set (match_operand 0)
11874 (call (match_operand:QI 1)
11875 (match_operand 2)))
11876 (use (match_operand 3))]
11879 ix86_expand_call (operands[0], operands[1], operands[2],
11880 operands[3], NULL, true);
11884 (define_insn "*call_value"
11885 [(set (match_operand 0)
11886 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
11887 (match_operand 2)))]
11888 "!SIBLING_CALL_P (insn)"
11889 "* return ix86_output_call_insn (insn, operands[1]);"
11890 [(set_attr "type" "callv")])
11892 (define_insn "*sibcall_value"
11893 [(set (match_operand 0)
11894 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
11895 (match_operand 2)))]
11896 "SIBLING_CALL_P (insn)"
11897 "* return ix86_output_call_insn (insn, operands[1]);"
11898 [(set_attr "type" "callv")])
11900 (define_insn "*sibcall_value_memory"
11901 [(set (match_operand 0)
11902 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
11903 (match_operand 2)))
11904 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11906 "* return ix86_output_call_insn (insn, operands[1]);"
11907 [(set_attr "type" "callv")])
11910 [(set (match_operand:W 0 "register_operand")
11911 (match_operand:W 1 "memory_operand"))
11912 (set (match_operand 2)
11913 (call (mem:QI (match_dup 0))
11914 (match_operand 3)))]
11915 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11916 && peep2_reg_dead_p (2, operands[0])"
11917 [(parallel [(set (match_dup 2)
11918 (call (mem:QI (match_dup 1))
11920 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11923 [(set (match_operand:W 0 "register_operand")
11924 (match_operand:W 1 "memory_operand"))
11925 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11926 (set (match_operand 2)
11927 (call (mem:QI (match_dup 0))
11928 (match_operand 3)))]
11929 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11930 && peep2_reg_dead_p (3, operands[0])"
11931 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11932 (parallel [(set (match_dup 2)
11933 (call (mem:QI (match_dup 1))
11935 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11937 (define_expand "call_value_pop"
11938 [(parallel [(set (match_operand 0)
11939 (call (match_operand:QI 1)
11940 (match_operand:SI 2)))
11941 (set (reg:SI SP_REG)
11942 (plus:SI (reg:SI SP_REG)
11943 (match_operand:SI 4)))])]
11946 ix86_expand_call (operands[0], operands[1], operands[2],
11947 operands[3], operands[4], false);
11951 (define_insn "*call_value_pop"
11952 [(set (match_operand 0)
11953 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
11954 (match_operand 2)))
11955 (set (reg:SI SP_REG)
11956 (plus:SI (reg:SI SP_REG)
11957 (match_operand:SI 3 "immediate_operand" "i")))]
11958 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11959 "* return ix86_output_call_insn (insn, operands[1]);"
11960 [(set_attr "type" "callv")])
11962 (define_insn "*sibcall_value_pop"
11963 [(set (match_operand 0)
11964 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
11965 (match_operand 2)))
11966 (set (reg:SI SP_REG)
11967 (plus:SI (reg:SI SP_REG)
11968 (match_operand:SI 3 "immediate_operand" "i")))]
11969 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11970 "* return ix86_output_call_insn (insn, operands[1]);"
11971 [(set_attr "type" "callv")])
11973 (define_insn "*sibcall_value_pop_memory"
11974 [(set (match_operand 0)
11975 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
11976 (match_operand 2)))
11977 (set (reg:SI SP_REG)
11978 (plus:SI (reg:SI SP_REG)
11979 (match_operand:SI 3 "immediate_operand" "i")))
11980 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11982 "* return ix86_output_call_insn (insn, operands[1]);"
11983 [(set_attr "type" "callv")])
11986 [(set (match_operand:SI 0 "register_operand")
11987 (match_operand:SI 1 "memory_operand"))
11988 (parallel [(set (match_operand 2)
11989 (call (mem:QI (match_dup 0))
11990 (match_operand 3)))
11991 (set (reg:SI SP_REG)
11992 (plus:SI (reg:SI SP_REG)
11993 (match_operand:SI 4 "immediate_operand")))])]
11994 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11995 && peep2_reg_dead_p (2, operands[0])"
11996 [(parallel [(set (match_dup 2)
11997 (call (mem:QI (match_dup 1))
11999 (set (reg:SI SP_REG)
12000 (plus:SI (reg:SI SP_REG)
12002 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12005 [(set (match_operand:SI 0 "register_operand")
12006 (match_operand:SI 1 "memory_operand"))
12007 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12008 (parallel [(set (match_operand 2)
12009 (call (mem:QI (match_dup 0))
12010 (match_operand 3)))
12011 (set (reg:SI SP_REG)
12012 (plus:SI (reg:SI SP_REG)
12013 (match_operand:SI 4 "immediate_operand")))])]
12014 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12015 && peep2_reg_dead_p (3, operands[0])"
12016 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12017 (parallel [(set (match_dup 2)
12018 (call (mem:QI (match_dup 1))
12020 (set (reg:SI SP_REG)
12021 (plus:SI (reg:SI SP_REG)
12023 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12025 ;; Call subroutine returning any type.
12027 (define_expand "untyped_call"
12028 [(parallel [(call (match_operand 0)
12031 (match_operand 2)])]
12036 /* In order to give reg-stack an easier job in validating two
12037 coprocessor registers as containing a possible return value,
12038 simply pretend the untyped call returns a complex long double
12041 We can't use SSE_REGPARM_MAX here since callee is unprototyped
12042 and should have the default ABI. */
12044 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12045 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12046 operands[0], const0_rtx,
12047 GEN_INT ((TARGET_64BIT
12048 ? (ix86_abi == SYSV_ABI
12049 ? X86_64_SSE_REGPARM_MAX
12050 : X86_64_MS_SSE_REGPARM_MAX)
12051 : X86_32_SSE_REGPARM_MAX)
12055 for (i = 0; i < XVECLEN (operands[2], 0); i++)
12057 rtx set = XVECEXP (operands[2], 0, i);
12058 emit_move_insn (SET_DEST (set), SET_SRC (set));
12061 /* The optimizer does not know that the call sets the function value
12062 registers we stored in the result block. We avoid problems by
12063 claiming that all hard registers are used and clobbered at this
12065 emit_insn (gen_blockage ());
12070 ;; Prologue and epilogue instructions
12072 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12073 ;; all of memory. This blocks insns from being moved across this point.
12075 (define_insn "blockage"
12076 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12079 [(set_attr "length" "0")])
12081 ;; Do not schedule instructions accessing memory across this point.
12083 (define_expand "memory_blockage"
12084 [(set (match_dup 0)
12085 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12088 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12089 MEM_VOLATILE_P (operands[0]) = 1;
12092 (define_insn "*memory_blockage"
12093 [(set (match_operand:BLK 0)
12094 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12097 [(set_attr "length" "0")])
12099 ;; As USE insns aren't meaningful after reload, this is used instead
12100 ;; to prevent deleting instructions setting registers for PIC code
12101 (define_insn "prologue_use"
12102 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12105 [(set_attr "length" "0")])
12107 ;; Insn emitted into the body of a function to return from a function.
12108 ;; This is only done if the function's epilogue is known to be simple.
12109 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12111 (define_expand "return"
12113 "ix86_can_use_return_insn_p ()"
12115 if (crtl->args.pops_args)
12117 rtx popc = GEN_INT (crtl->args.pops_args);
12118 emit_jump_insn (gen_simple_return_pop_internal (popc));
12123 ;; We need to disable this for TARGET_SEH, as otherwise
12124 ;; shrink-wrapped prologue gets enabled too. This might exceed
12125 ;; the maximum size of prologue in unwind information.
12127 (define_expand "simple_return"
12131 if (crtl->args.pops_args)
12133 rtx popc = GEN_INT (crtl->args.pops_args);
12134 emit_jump_insn (gen_simple_return_pop_internal (popc));
12139 (define_insn "simple_return_internal"
12143 [(set_attr "length_nobnd" "1")
12144 (set_attr "atom_unit" "jeu")
12145 (set_attr "length_immediate" "0")
12146 (set_attr "modrm" "0")])
12148 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12149 ;; instruction Athlon and K8 have.
12151 (define_insn "simple_return_internal_long"
12153 (unspec [(const_int 0)] UNSPEC_REP)]
12156 if (ix86_bnd_prefixed_insn_p (insn))
12159 return "rep%; ret";
12161 [(set_attr "length" "2")
12162 (set_attr "atom_unit" "jeu")
12163 (set_attr "length_immediate" "0")
12164 (set_attr "prefix_rep" "1")
12165 (set_attr "modrm" "0")])
12167 (define_insn "simple_return_pop_internal"
12169 (use (match_operand:SI 0 "const_int_operand"))]
12172 [(set_attr "length_nobnd" "3")
12173 (set_attr "atom_unit" "jeu")
12174 (set_attr "length_immediate" "2")
12175 (set_attr "modrm" "0")])
12177 (define_insn "simple_return_indirect_internal"
12179 (use (match_operand:SI 0 "register_operand" "r"))]
12182 [(set_attr "type" "ibr")
12183 (set_attr "length_immediate" "0")])
12189 [(set_attr "length" "1")
12190 (set_attr "length_immediate" "0")
12191 (set_attr "modrm" "0")])
12193 ;; Generate nops. Operand 0 is the number of nops, up to 8.
12194 (define_insn "nops"
12195 [(unspec_volatile [(match_operand 0 "const_int_operand")]
12199 int num = INTVAL (operands[0]);
12201 gcc_assert (IN_RANGE (num, 1, 8));
12204 fputs ("\tnop\n", asm_out_file);
12208 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12209 (set_attr "length_immediate" "0")
12210 (set_attr "modrm" "0")])
12212 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12213 ;; branch prediction penalty for the third jump in a 16-byte
12217 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12220 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12221 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12223 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12224 The align insn is used to avoid 3 jump instructions in the row to improve
12225 branch prediction and the benefits hardly outweigh the cost of extra 8
12226 nops on the average inserted by full alignment pseudo operation. */
12230 [(set_attr "length" "16")])
12232 (define_expand "prologue"
12235 "ix86_expand_prologue (); DONE;")
12237 (define_insn "set_got"
12238 [(set (match_operand:SI 0 "register_operand" "=r")
12239 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12240 (clobber (reg:CC FLAGS_REG))]
12242 "* return output_set_got (operands[0], NULL_RTX);"
12243 [(set_attr "type" "multi")
12244 (set_attr "length" "12")])
12246 (define_insn "set_got_labelled"
12247 [(set (match_operand:SI 0 "register_operand" "=r")
12248 (unspec:SI [(label_ref (match_operand 1))]
12250 (clobber (reg:CC FLAGS_REG))]
12252 "* return output_set_got (operands[0], operands[1]);"
12253 [(set_attr "type" "multi")
12254 (set_attr "length" "12")])
12256 (define_insn "set_got_rex64"
12257 [(set (match_operand:DI 0 "register_operand" "=r")
12258 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12260 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12261 [(set_attr "type" "lea")
12262 (set_attr "length_address" "4")
12263 (set_attr "mode" "DI")])
12265 (define_insn "set_rip_rex64"
12266 [(set (match_operand:DI 0 "register_operand" "=r")
12267 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12269 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12270 [(set_attr "type" "lea")
12271 (set_attr "length_address" "4")
12272 (set_attr "mode" "DI")])
12274 (define_insn "set_got_offset_rex64"
12275 [(set (match_operand:DI 0 "register_operand" "=r")
12277 [(label_ref (match_operand 1))]
12278 UNSPEC_SET_GOT_OFFSET))]
12280 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12281 [(set_attr "type" "imov")
12282 (set_attr "length_immediate" "0")
12283 (set_attr "length_address" "8")
12284 (set_attr "mode" "DI")])
12286 (define_expand "epilogue"
12289 "ix86_expand_epilogue (1); DONE;")
12291 (define_expand "sibcall_epilogue"
12294 "ix86_expand_epilogue (0); DONE;")
12296 (define_expand "eh_return"
12297 [(use (match_operand 0 "register_operand"))]
12300 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12302 /* Tricky bit: we write the address of the handler to which we will
12303 be returning into someone else's stack frame, one word below the
12304 stack address we wish to restore. */
12305 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12306 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12307 tmp = gen_rtx_MEM (Pmode, tmp);
12308 emit_move_insn (tmp, ra);
12310 emit_jump_insn (gen_eh_return_internal ());
12315 (define_insn_and_split "eh_return_internal"
12319 "epilogue_completed"
12321 "ix86_expand_epilogue (2); DONE;")
12323 (define_insn "leave"
12324 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12325 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12326 (clobber (mem:BLK (scratch)))]
12329 [(set_attr "type" "leave")])
12331 (define_insn "leave_rex64"
12332 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12333 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12334 (clobber (mem:BLK (scratch)))]
12337 [(set_attr "type" "leave")])
12339 ;; Handle -fsplit-stack.
12341 (define_expand "split_stack_prologue"
12345 ix86_expand_split_stack_prologue ();
12349 ;; In order to support the call/return predictor, we use a return
12350 ;; instruction which the middle-end doesn't see.
12351 (define_insn "split_stack_return"
12352 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12353 UNSPECV_SPLIT_STACK_RETURN)]
12356 if (operands[0] == const0_rtx)
12361 [(set_attr "atom_unit" "jeu")
12362 (set_attr "modrm" "0")
12363 (set (attr "length")
12364 (if_then_else (match_operand:SI 0 "const0_operand")
12367 (set (attr "length_immediate")
12368 (if_then_else (match_operand:SI 0 "const0_operand")
12372 ;; If there are operand 0 bytes available on the stack, jump to
12375 (define_expand "split_stack_space_check"
12376 [(set (pc) (if_then_else
12377 (ltu (minus (reg SP_REG)
12378 (match_operand 0 "register_operand"))
12379 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12380 (label_ref (match_operand 1))
12384 rtx reg, size, limit;
12386 reg = gen_reg_rtx (Pmode);
12387 size = force_reg (Pmode, operands[0]);
12388 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12389 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12390 UNSPEC_STACK_CHECK);
12391 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12392 ix86_expand_branch (GEU, reg, limit, operands[1]);
12397 ;; Bit manipulation instructions.
12399 (define_expand "ffs<mode>2"
12400 [(set (match_dup 2) (const_int -1))
12401 (parallel [(set (match_dup 3) (match_dup 4))
12402 (set (match_operand:SWI48 0 "register_operand")
12404 (match_operand:SWI48 1 "nonimmediate_operand")))])
12405 (set (match_dup 0) (if_then_else:SWI48
12406 (eq (match_dup 3) (const_int 0))
12409 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12410 (clobber (reg:CC FLAGS_REG))])]
12413 machine_mode flags_mode;
12415 if (<MODE>mode == SImode && !TARGET_CMOVE)
12417 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12422 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12424 operands[2] = gen_reg_rtx (<MODE>mode);
12425 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12426 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12429 (define_insn_and_split "ffssi2_no_cmove"
12430 [(set (match_operand:SI 0 "register_operand" "=r")
12431 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12432 (clobber (match_scratch:SI 2 "=&q"))
12433 (clobber (reg:CC FLAGS_REG))]
12436 "&& reload_completed"
12437 [(parallel [(set (match_dup 4) (match_dup 5))
12438 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12439 (set (strict_low_part (match_dup 3))
12440 (eq:QI (match_dup 4) (const_int 0)))
12441 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12442 (clobber (reg:CC FLAGS_REG))])
12443 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12444 (clobber (reg:CC FLAGS_REG))])
12445 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12446 (clobber (reg:CC FLAGS_REG))])]
12448 machine_mode flags_mode
12449 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12451 operands[3] = gen_lowpart (QImode, operands[2]);
12452 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12453 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12455 ix86_expand_clear (operands[2]);
12458 (define_insn "*tzcnt<mode>_1"
12459 [(set (reg:CCC FLAGS_REG)
12460 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12462 (set (match_operand:SWI48 0 "register_operand" "=r")
12463 (ctz:SWI48 (match_dup 1)))]
12464 "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
12465 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12466 [(set_attr "type" "alu1")
12467 (set_attr "prefix_0f" "1")
12468 (set_attr "prefix_rep" "1")
12469 (set_attr "btver2_decode" "double")
12470 (set_attr "mode" "<MODE>")])
12472 (define_insn "*bsf<mode>_1"
12473 [(set (reg:CCZ FLAGS_REG)
12474 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12476 (set (match_operand:SWI48 0 "register_operand" "=r")
12477 (ctz:SWI48 (match_dup 1)))]
12479 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12480 [(set_attr "type" "alu1")
12481 (set_attr "prefix_0f" "1")
12482 (set_attr "btver2_decode" "double")
12483 (set_attr "mode" "<MODE>")])
12485 (define_expand "ctz<mode>2"
12487 [(set (match_operand:SWI248 0 "register_operand")
12489 (match_operand:SWI248 1 "nonimmediate_operand")))
12490 (clobber (reg:CC FLAGS_REG))])])
12492 ; False dependency happens when destination is only updated by tzcnt,
12493 ; lzcnt or popcnt. There is no false dependency when destination is
12494 ; also used in source.
12495 (define_insn_and_split "*ctz<mode>2_falsedep_1"
12496 [(set (match_operand:SWI48 0 "register_operand" "=r")
12498 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12499 (clobber (reg:CC FLAGS_REG))]
12500 "(TARGET_BMI || TARGET_GENERIC)
12501 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12503 "&& reload_completed"
12505 [(set (match_dup 0)
12506 (ctz:SWI48 (match_dup 1)))
12507 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12508 (clobber (reg:CC FLAGS_REG))])]
12510 if (!reg_mentioned_p (operands[0], operands[1]))
12511 ix86_expand_clear (operands[0]);
12514 (define_insn "*ctz<mode>2_falsedep"
12515 [(set (match_operand:SWI48 0 "register_operand" "=r")
12517 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12518 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12519 UNSPEC_INSN_FALSE_DEP)
12520 (clobber (reg:CC FLAGS_REG))]
12524 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12525 else if (TARGET_GENERIC)
12526 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12527 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12529 gcc_unreachable ();
12531 [(set_attr "type" "alu1")
12532 (set_attr "prefix_0f" "1")
12533 (set_attr "prefix_rep" "1")
12534 (set_attr "mode" "<MODE>")])
12536 (define_insn "*ctz<mode>2"
12537 [(set (match_operand:SWI248 0 "register_operand" "=r")
12538 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12539 (clobber (reg:CC FLAGS_REG))]
12543 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12544 else if (optimize_function_for_size_p (cfun))
12546 else if (TARGET_GENERIC)
12547 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12548 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12550 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12552 [(set_attr "type" "alu1")
12553 (set_attr "prefix_0f" "1")
12554 (set (attr "prefix_rep")
12556 (ior (match_test "TARGET_BMI")
12557 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12558 (match_test "TARGET_GENERIC")))
12560 (const_string "0")))
12561 (set_attr "mode" "<MODE>")])
12563 (define_expand "clz<mode>2"
12565 [(set (match_operand:SWI248 0 "register_operand")
12568 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12569 (clobber (reg:CC FLAGS_REG))])
12571 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12572 (clobber (reg:CC FLAGS_REG))])]
12577 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12580 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12583 (define_expand "clz<mode>2_lzcnt"
12585 [(set (match_operand:SWI248 0 "register_operand")
12587 (match_operand:SWI248 1 "nonimmediate_operand")))
12588 (clobber (reg:CC FLAGS_REG))])]
12591 (define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
12592 [(set (match_operand:SWI48 0 "register_operand" "=r")
12594 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12595 (clobber (reg:CC FLAGS_REG))]
12597 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12599 "&& reload_completed"
12601 [(set (match_dup 0)
12602 (clz:SWI48 (match_dup 1)))
12603 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12604 (clobber (reg:CC FLAGS_REG))])]
12606 if (!reg_mentioned_p (operands[0], operands[1]))
12607 ix86_expand_clear (operands[0]);
12610 (define_insn "*clz<mode>2_lzcnt_falsedep"
12611 [(set (match_operand:SWI48 0 "register_operand" "=r")
12613 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12614 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12615 UNSPEC_INSN_FALSE_DEP)
12616 (clobber (reg:CC FLAGS_REG))]
12618 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12619 [(set_attr "prefix_rep" "1")
12620 (set_attr "type" "bitmanip")
12621 (set_attr "mode" "<MODE>")])
12623 (define_insn "*clz<mode>2_lzcnt"
12624 [(set (match_operand:SWI248 0 "register_operand" "=r")
12625 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12626 (clobber (reg:CC FLAGS_REG))]
12628 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12629 [(set_attr "prefix_rep" "1")
12630 (set_attr "type" "bitmanip")
12631 (set_attr "mode" "<MODE>")])
12633 ;; BMI instructions.
12634 (define_insn "*bmi_andn_<mode>"
12635 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12638 (match_operand:SWI48 1 "register_operand" "r,r"))
12639 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12640 (clobber (reg:CC FLAGS_REG))]
12642 "andn\t{%2, %1, %0|%0, %1, %2}"
12643 [(set_attr "type" "bitmanip")
12644 (set_attr "btver2_decode" "direct, double")
12645 (set_attr "mode" "<MODE>")])
12647 (define_insn "bmi_bextr_<mode>"
12648 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12649 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12650 (match_operand:SWI48 2 "register_operand" "r,r")]
12652 (clobber (reg:CC FLAGS_REG))]
12654 "bextr\t{%2, %1, %0|%0, %1, %2}"
12655 [(set_attr "type" "bitmanip")
12656 (set_attr "btver2_decode" "direct, double")
12657 (set_attr "mode" "<MODE>")])
12659 (define_insn "*bmi_blsi_<mode>"
12660 [(set (match_operand:SWI48 0 "register_operand" "=r")
12663 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12665 (clobber (reg:CC FLAGS_REG))]
12667 "blsi\t{%1, %0|%0, %1}"
12668 [(set_attr "type" "bitmanip")
12669 (set_attr "btver2_decode" "double")
12670 (set_attr "mode" "<MODE>")])
12672 (define_insn "*bmi_blsmsk_<mode>"
12673 [(set (match_operand:SWI48 0 "register_operand" "=r")
12676 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12679 (clobber (reg:CC FLAGS_REG))]
12681 "blsmsk\t{%1, %0|%0, %1}"
12682 [(set_attr "type" "bitmanip")
12683 (set_attr "btver2_decode" "double")
12684 (set_attr "mode" "<MODE>")])
12686 (define_insn "*bmi_blsr_<mode>"
12687 [(set (match_operand:SWI48 0 "register_operand" "=r")
12690 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12693 (clobber (reg:CC FLAGS_REG))]
12695 "blsr\t{%1, %0|%0, %1}"
12696 [(set_attr "type" "bitmanip")
12697 (set_attr "btver2_decode" "double")
12698 (set_attr "mode" "<MODE>")])
12700 ;; BMI2 instructions.
12701 (define_expand "bmi2_bzhi_<mode>3"
12703 [(set (match_operand:SWI48 0 "register_operand")
12704 (zero_extract:SWI48
12705 (match_operand:SWI48 1 "nonimmediate_operand")
12707 (and:SWI48 (match_operand:SWI48 2 "register_operand")
12711 (clobber (reg:CC FLAGS_REG))])]
12713 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
12715 (define_insn "*bmi2_bzhi_<mode>3"
12716 [(set (match_operand:SWI48 0 "register_operand" "=r")
12717 (zero_extract:SWI48
12718 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12720 (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
12722 (match_operand:SWI48 3 "const_int_operand" "n"))
12724 (clobber (reg:CC FLAGS_REG))]
12725 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12726 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12727 [(set_attr "type" "bitmanip")
12728 (set_attr "prefix" "vex")
12729 (set_attr "mode" "<MODE>")])
12731 (define_mode_attr k [(SI "k") (DI "q")])
12732 (define_insn "*bmi2_bzhi_<mode>3_1"
12733 [(set (match_operand:SWI48 0 "register_operand" "=r")
12734 (zero_extract:SWI48
12735 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12737 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
12738 (match_operand:SWI48 3 "const_int_operand" "n"))
12740 (clobber (reg:CC FLAGS_REG))]
12741 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12742 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
12743 [(set_attr "type" "bitmanip")
12744 (set_attr "prefix" "vex")
12745 (set_attr "mode" "<MODE>")])
12747 (define_insn "bmi2_pdep_<mode>3"
12748 [(set (match_operand:SWI48 0 "register_operand" "=r")
12749 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12750 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12753 "pdep\t{%2, %1, %0|%0, %1, %2}"
12754 [(set_attr "type" "bitmanip")
12755 (set_attr "prefix" "vex")
12756 (set_attr "mode" "<MODE>")])
12758 (define_insn "bmi2_pext_<mode>3"
12759 [(set (match_operand:SWI48 0 "register_operand" "=r")
12760 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12761 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12764 "pext\t{%2, %1, %0|%0, %1, %2}"
12765 [(set_attr "type" "bitmanip")
12766 (set_attr "prefix" "vex")
12767 (set_attr "mode" "<MODE>")])
12769 ;; TBM instructions.
12770 (define_insn "tbm_bextri_<mode>"
12771 [(set (match_operand:SWI48 0 "register_operand" "=r")
12772 (zero_extract:SWI48
12773 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12774 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12775 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12776 (clobber (reg:CC FLAGS_REG))]
12779 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12780 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12782 [(set_attr "type" "bitmanip")
12783 (set_attr "mode" "<MODE>")])
12785 (define_insn "*tbm_blcfill_<mode>"
12786 [(set (match_operand:SWI48 0 "register_operand" "=r")
12789 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12792 (clobber (reg:CC FLAGS_REG))]
12794 "blcfill\t{%1, %0|%0, %1}"
12795 [(set_attr "type" "bitmanip")
12796 (set_attr "mode" "<MODE>")])
12798 (define_insn "*tbm_blci_<mode>"
12799 [(set (match_operand:SWI48 0 "register_operand" "=r")
12803 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12806 (clobber (reg:CC FLAGS_REG))]
12808 "blci\t{%1, %0|%0, %1}"
12809 [(set_attr "type" "bitmanip")
12810 (set_attr "mode" "<MODE>")])
12812 (define_insn "*tbm_blcic_<mode>"
12813 [(set (match_operand:SWI48 0 "register_operand" "=r")
12816 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12820 (clobber (reg:CC FLAGS_REG))]
12822 "blcic\t{%1, %0|%0, %1}"
12823 [(set_attr "type" "bitmanip")
12824 (set_attr "mode" "<MODE>")])
12826 (define_insn "*tbm_blcmsk_<mode>"
12827 [(set (match_operand:SWI48 0 "register_operand" "=r")
12830 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12833 (clobber (reg:CC FLAGS_REG))]
12835 "blcmsk\t{%1, %0|%0, %1}"
12836 [(set_attr "type" "bitmanip")
12837 (set_attr "mode" "<MODE>")])
12839 (define_insn "*tbm_blcs_<mode>"
12840 [(set (match_operand:SWI48 0 "register_operand" "=r")
12843 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12846 (clobber (reg:CC FLAGS_REG))]
12848 "blcs\t{%1, %0|%0, %1}"
12849 [(set_attr "type" "bitmanip")
12850 (set_attr "mode" "<MODE>")])
12852 (define_insn "*tbm_blsfill_<mode>"
12853 [(set (match_operand:SWI48 0 "register_operand" "=r")
12856 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12859 (clobber (reg:CC FLAGS_REG))]
12861 "blsfill\t{%1, %0|%0, %1}"
12862 [(set_attr "type" "bitmanip")
12863 (set_attr "mode" "<MODE>")])
12865 (define_insn "*tbm_blsic_<mode>"
12866 [(set (match_operand:SWI48 0 "register_operand" "=r")
12869 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12873 (clobber (reg:CC FLAGS_REG))]
12875 "blsic\t{%1, %0|%0, %1}"
12876 [(set_attr "type" "bitmanip")
12877 (set_attr "mode" "<MODE>")])
12879 (define_insn "*tbm_t1mskc_<mode>"
12880 [(set (match_operand:SWI48 0 "register_operand" "=r")
12883 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12887 (clobber (reg:CC FLAGS_REG))]
12889 "t1mskc\t{%1, %0|%0, %1}"
12890 [(set_attr "type" "bitmanip")
12891 (set_attr "mode" "<MODE>")])
12893 (define_insn "*tbm_tzmsk_<mode>"
12894 [(set (match_operand:SWI48 0 "register_operand" "=r")
12897 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12901 (clobber (reg:CC FLAGS_REG))]
12903 "tzmsk\t{%1, %0|%0, %1}"
12904 [(set_attr "type" "bitmanip")
12905 (set_attr "mode" "<MODE>")])
12907 (define_insn "bsr_rex64"
12908 [(set (match_operand:DI 0 "register_operand" "=r")
12909 (minus:DI (const_int 63)
12910 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12911 (clobber (reg:CC FLAGS_REG))]
12913 "bsr{q}\t{%1, %0|%0, %1}"
12914 [(set_attr "type" "alu1")
12915 (set_attr "prefix_0f" "1")
12916 (set_attr "mode" "DI")])
12919 [(set (match_operand:SI 0 "register_operand" "=r")
12920 (minus:SI (const_int 31)
12921 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12922 (clobber (reg:CC FLAGS_REG))]
12924 "bsr{l}\t{%1, %0|%0, %1}"
12925 [(set_attr "type" "alu1")
12926 (set_attr "prefix_0f" "1")
12927 (set_attr "mode" "SI")])
12929 (define_insn "*bsrhi"
12930 [(set (match_operand:HI 0 "register_operand" "=r")
12931 (minus:HI (const_int 15)
12932 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12933 (clobber (reg:CC FLAGS_REG))]
12935 "bsr{w}\t{%1, %0|%0, %1}"
12936 [(set_attr "type" "alu1")
12937 (set_attr "prefix_0f" "1")
12938 (set_attr "mode" "HI")])
12940 (define_expand "popcount<mode>2"
12942 [(set (match_operand:SWI248 0 "register_operand")
12944 (match_operand:SWI248 1 "nonimmediate_operand")))
12945 (clobber (reg:CC FLAGS_REG))])]
12948 (define_insn_and_split "*popcount<mode>2_falsedep_1"
12949 [(set (match_operand:SWI48 0 "register_operand" "=r")
12951 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12952 (clobber (reg:CC FLAGS_REG))]
12954 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12956 "&& reload_completed"
12958 [(set (match_dup 0)
12959 (popcount:SWI48 (match_dup 1)))
12960 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12961 (clobber (reg:CC FLAGS_REG))])]
12963 if (!reg_mentioned_p (operands[0], operands[1]))
12964 ix86_expand_clear (operands[0]);
12967 (define_insn "*popcount<mode>2_falsedep"
12968 [(set (match_operand:SWI48 0 "register_operand" "=r")
12970 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12971 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12972 UNSPEC_INSN_FALSE_DEP)
12973 (clobber (reg:CC FLAGS_REG))]
12977 return "popcnt\t{%1, %0|%0, %1}";
12979 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12982 [(set_attr "prefix_rep" "1")
12983 (set_attr "type" "bitmanip")
12984 (set_attr "mode" "<MODE>")])
12986 (define_insn "*popcount<mode>2"
12987 [(set (match_operand:SWI248 0 "register_operand" "=r")
12989 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12990 (clobber (reg:CC FLAGS_REG))]
12994 return "popcnt\t{%1, %0|%0, %1}";
12996 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12999 [(set_attr "prefix_rep" "1")
13000 (set_attr "type" "bitmanip")
13001 (set_attr "mode" "<MODE>")])
13003 (define_expand "bswapdi2"
13004 [(set (match_operand:DI 0 "register_operand")
13005 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
13009 operands[1] = force_reg (DImode, operands[1]);
13012 (define_expand "bswapsi2"
13013 [(set (match_operand:SI 0 "register_operand")
13014 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
13019 else if (TARGET_BSWAP)
13020 operands[1] = force_reg (SImode, operands[1]);
13023 rtx x = operands[0];
13025 emit_move_insn (x, operands[1]);
13026 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13027 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
13028 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13033 (define_insn "*bswap<mode>2_movbe"
13034 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
13035 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
13037 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13040 movbe\t{%1, %0|%0, %1}
13041 movbe\t{%1, %0|%0, %1}"
13042 [(set_attr "type" "bitmanip,imov,imov")
13043 (set_attr "modrm" "0,1,1")
13044 (set_attr "prefix_0f" "*,1,1")
13045 (set_attr "prefix_extra" "*,1,1")
13046 (set_attr "mode" "<MODE>")])
13048 (define_insn "*bswap<mode>2"
13049 [(set (match_operand:SWI48 0 "register_operand" "=r")
13050 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
13053 [(set_attr "type" "bitmanip")
13054 (set_attr "modrm" "0")
13055 (set_attr "mode" "<MODE>")])
13057 (define_insn "*bswaphi_lowpart_1"
13058 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
13059 (bswap:HI (match_dup 0)))
13060 (clobber (reg:CC FLAGS_REG))]
13061 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
13063 xchg{b}\t{%h0, %b0|%b0, %h0}
13064 rol{w}\t{$8, %0|%0, 8}"
13065 [(set_attr "length" "2,4")
13066 (set_attr "mode" "QI,HI")])
13068 (define_insn "bswaphi_lowpart"
13069 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
13070 (bswap:HI (match_dup 0)))
13071 (clobber (reg:CC FLAGS_REG))]
13073 "rol{w}\t{$8, %0|%0, 8}"
13074 [(set_attr "length" "4")
13075 (set_attr "mode" "HI")])
13077 (define_expand "paritydi2"
13078 [(set (match_operand:DI 0 "register_operand")
13079 (parity:DI (match_operand:DI 1 "register_operand")))]
13082 rtx scratch = gen_reg_rtx (QImode);
13085 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
13086 NULL_RTX, operands[1]));
13088 cond = gen_rtx_fmt_ee (ORDERED, QImode,
13089 gen_rtx_REG (CCmode, FLAGS_REG),
13091 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
13094 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
13097 rtx tmp = gen_reg_rtx (SImode);
13099 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
13100 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
13105 (define_expand "paritysi2"
13106 [(set (match_operand:SI 0 "register_operand")
13107 (parity:SI (match_operand:SI 1 "register_operand")))]
13110 rtx scratch = gen_reg_rtx (QImode);
13113 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
13115 cond = gen_rtx_fmt_ee (ORDERED, QImode,
13116 gen_rtx_REG (CCmode, FLAGS_REG),
13118 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
13120 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
13124 (define_insn_and_split "paritydi2_cmp"
13125 [(set (reg:CC FLAGS_REG)
13126 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
13128 (clobber (match_scratch:DI 0 "=r"))
13129 (clobber (match_scratch:SI 1 "=&r"))
13130 (clobber (match_scratch:HI 2 "=Q"))]
13133 "&& reload_completed"
13135 [(set (match_dup 1)
13136 (xor:SI (match_dup 1) (match_dup 4)))
13137 (clobber (reg:CC FLAGS_REG))])
13139 [(set (reg:CC FLAGS_REG)
13140 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13141 (clobber (match_dup 1))
13142 (clobber (match_dup 2))])]
13144 operands[4] = gen_lowpart (SImode, operands[3]);
13148 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
13149 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
13152 operands[1] = gen_highpart (SImode, operands[3]);
13155 (define_insn_and_split "paritysi2_cmp"
13156 [(set (reg:CC FLAGS_REG)
13157 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
13159 (clobber (match_scratch:SI 0 "=r"))
13160 (clobber (match_scratch:HI 1 "=&Q"))]
13163 "&& reload_completed"
13165 [(set (match_dup 1)
13166 (xor:HI (match_dup 1) (match_dup 3)))
13167 (clobber (reg:CC FLAGS_REG))])
13169 [(set (reg:CC FLAGS_REG)
13170 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13171 (clobber (match_dup 1))])]
13173 operands[3] = gen_lowpart (HImode, operands[2]);
13175 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
13176 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
13179 (define_insn "*parityhi2_cmp"
13180 [(set (reg:CC FLAGS_REG)
13181 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
13183 (clobber (match_scratch:HI 0 "=Q"))]
13185 "xor{b}\t{%h0, %b0|%b0, %h0}"
13186 [(set_attr "length" "2")
13187 (set_attr "mode" "HI")])
13190 ;; Thread-local storage patterns for ELF.
13192 ;; Note that these code sequences must appear exactly as shown
13193 ;; in order to allow linker relaxation.
13195 (define_insn "*tls_global_dynamic_32_gnu"
13196 [(set (match_operand:SI 0 "register_operand" "=a")
13198 [(match_operand:SI 1 "register_operand" "b")
13199 (match_operand 2 "tls_symbolic_operand")
13200 (match_operand 3 "constant_call_address_operand" "Bz")
13203 (clobber (match_scratch:SI 4 "=d"))
13204 (clobber (match_scratch:SI 5 "=c"))
13205 (clobber (reg:CC FLAGS_REG))]
13206 "!TARGET_64BIT && TARGET_GNU_TLS"
13209 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
13210 if (TARGET_SUN_TLS)
13211 #ifdef HAVE_AS_IX86_TLSGDPLT
13212 return "call\t%a2@tlsgdplt";
13214 return "call\t%p3@plt";
13216 return "call\t%P3";
13218 [(set_attr "type" "multi")
13219 (set_attr "length" "12")])
13221 (define_expand "tls_global_dynamic_32"
13223 [(set (match_operand:SI 0 "register_operand")
13224 (unspec:SI [(match_operand:SI 2 "register_operand")
13225 (match_operand 1 "tls_symbolic_operand")
13226 (match_operand 3 "constant_call_address_operand")
13229 (clobber (match_scratch:SI 4))
13230 (clobber (match_scratch:SI 5))
13231 (clobber (reg:CC FLAGS_REG))])]
13233 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13235 (define_insn "*tls_global_dynamic_64_<mode>"
13236 [(set (match_operand:P 0 "register_operand" "=a")
13238 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
13239 (match_operand 3)))
13240 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
13245 fputs (ASM_BYTE "0x66\n", asm_out_file);
13247 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13248 fputs (ASM_SHORT "0x6666\n", asm_out_file);
13249 fputs ("\trex64\n", asm_out_file);
13250 if (TARGET_SUN_TLS)
13251 return "call\t%p2@plt";
13252 return "call\t%P2";
13254 [(set_attr "type" "multi")
13255 (set (attr "length")
13256 (symbol_ref "TARGET_X32 ? 15 : 16"))])
13258 (define_insn "*tls_global_dynamic_64_largepic"
13259 [(set (match_operand:DI 0 "register_operand" "=a")
13261 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
13262 (match_operand:DI 3 "immediate_operand" "i")))
13263 (match_operand 4)))
13264 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13266 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13267 && GET_CODE (operands[3]) == CONST
13268 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13269 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13272 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13273 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13274 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13275 return "call\t{*%%rax|rax}";
13277 [(set_attr "type" "multi")
13278 (set_attr "length" "22")])
13280 (define_expand "tls_global_dynamic_64_<mode>"
13282 [(set (match_operand:P 0 "register_operand")
13284 (mem:QI (match_operand 2))
13286 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
13289 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13291 (define_insn "*tls_local_dynamic_base_32_gnu"
13292 [(set (match_operand:SI 0 "register_operand" "=a")
13294 [(match_operand:SI 1 "register_operand" "b")
13295 (match_operand 2 "constant_call_address_operand" "Bz")
13297 UNSPEC_TLS_LD_BASE))
13298 (clobber (match_scratch:SI 3 "=d"))
13299 (clobber (match_scratch:SI 4 "=c"))
13300 (clobber (reg:CC FLAGS_REG))]
13301 "!TARGET_64BIT && TARGET_GNU_TLS"
13304 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13305 if (TARGET_SUN_TLS)
13307 if (HAVE_AS_IX86_TLSLDMPLT)
13308 return "call\t%&@tlsldmplt";
13310 return "call\t%p2@plt";
13312 return "call\t%P2";
13314 [(set_attr "type" "multi")
13315 (set_attr "length" "11")])
13317 (define_expand "tls_local_dynamic_base_32"
13319 [(set (match_operand:SI 0 "register_operand")
13321 [(match_operand:SI 1 "register_operand")
13322 (match_operand 2 "constant_call_address_operand")
13324 UNSPEC_TLS_LD_BASE))
13325 (clobber (match_scratch:SI 3))
13326 (clobber (match_scratch:SI 4))
13327 (clobber (reg:CC FLAGS_REG))])]
13329 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13331 (define_insn "*tls_local_dynamic_base_64_<mode>"
13332 [(set (match_operand:P 0 "register_operand" "=a")
13334 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13335 (match_operand 2)))
13336 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13340 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13341 if (TARGET_SUN_TLS)
13342 return "call\t%p1@plt";
13343 return "call\t%P1";
13345 [(set_attr "type" "multi")
13346 (set_attr "length" "12")])
13348 (define_insn "*tls_local_dynamic_base_64_largepic"
13349 [(set (match_operand:DI 0 "register_operand" "=a")
13351 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13352 (match_operand:DI 2 "immediate_operand" "i")))
13353 (match_operand 3)))
13354 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13355 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13356 && GET_CODE (operands[2]) == CONST
13357 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13358 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13361 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13362 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13363 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13364 return "call\t{*%%rax|rax}";
13366 [(set_attr "type" "multi")
13367 (set_attr "length" "22")])
13369 (define_expand "tls_local_dynamic_base_64_<mode>"
13371 [(set (match_operand:P 0 "register_operand")
13373 (mem:QI (match_operand 1))
13375 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13377 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13379 ;; Local dynamic of a single variable is a lose. Show combine how
13380 ;; to convert that back to global dynamic.
13382 (define_insn_and_split "*tls_local_dynamic_32_once"
13383 [(set (match_operand:SI 0 "register_operand" "=a")
13385 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13386 (match_operand 2 "constant_call_address_operand" "Bz")
13388 UNSPEC_TLS_LD_BASE)
13389 (const:SI (unspec:SI
13390 [(match_operand 3 "tls_symbolic_operand")]
13392 (clobber (match_scratch:SI 4 "=d"))
13393 (clobber (match_scratch:SI 5 "=c"))
13394 (clobber (reg:CC FLAGS_REG))]
13399 [(set (match_dup 0)
13400 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13403 (clobber (match_dup 4))
13404 (clobber (match_dup 5))
13405 (clobber (reg:CC FLAGS_REG))])])
13407 ;; Segment register for the thread base ptr load
13408 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13410 ;; Load and add the thread base pointer from %<tp_seg>:0.
13411 (define_insn "*load_tp_x32"
13412 [(set (match_operand:SI 0 "register_operand" "=r")
13413 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13415 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13416 [(set_attr "type" "imov")
13417 (set_attr "modrm" "0")
13418 (set_attr "length" "7")
13419 (set_attr "memory" "load")
13420 (set_attr "imm_disp" "false")])
13422 (define_insn "*load_tp_x32_zext"
13423 [(set (match_operand:DI 0 "register_operand" "=r")
13424 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13426 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13427 [(set_attr "type" "imov")
13428 (set_attr "modrm" "0")
13429 (set_attr "length" "7")
13430 (set_attr "memory" "load")
13431 (set_attr "imm_disp" "false")])
13433 (define_insn "*load_tp_<mode>"
13434 [(set (match_operand:P 0 "register_operand" "=r")
13435 (unspec:P [(const_int 0)] UNSPEC_TP))]
13437 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13438 [(set_attr "type" "imov")
13439 (set_attr "modrm" "0")
13440 (set_attr "length" "7")
13441 (set_attr "memory" "load")
13442 (set_attr "imm_disp" "false")])
13444 (define_insn "*add_tp_x32"
13445 [(set (match_operand:SI 0 "register_operand" "=r")
13446 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13447 (match_operand:SI 1 "register_operand" "0")))
13448 (clobber (reg:CC FLAGS_REG))]
13450 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13451 [(set_attr "type" "alu")
13452 (set_attr "modrm" "0")
13453 (set_attr "length" "7")
13454 (set_attr "memory" "load")
13455 (set_attr "imm_disp" "false")])
13457 (define_insn "*add_tp_x32_zext"
13458 [(set (match_operand:DI 0 "register_operand" "=r")
13460 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13461 (match_operand:SI 1 "register_operand" "0"))))
13462 (clobber (reg:CC FLAGS_REG))]
13464 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13465 [(set_attr "type" "alu")
13466 (set_attr "modrm" "0")
13467 (set_attr "length" "7")
13468 (set_attr "memory" "load")
13469 (set_attr "imm_disp" "false")])
13471 (define_insn "*add_tp_<mode>"
13472 [(set (match_operand:P 0 "register_operand" "=r")
13473 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13474 (match_operand:P 1 "register_operand" "0")))
13475 (clobber (reg:CC FLAGS_REG))]
13477 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13478 [(set_attr "type" "alu")
13479 (set_attr "modrm" "0")
13480 (set_attr "length" "7")
13481 (set_attr "memory" "load")
13482 (set_attr "imm_disp" "false")])
13484 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13485 ;; %rax as destination of the initial executable code sequence.
13486 (define_insn "tls_initial_exec_64_sun"
13487 [(set (match_operand:DI 0 "register_operand" "=a")
13489 [(match_operand 1 "tls_symbolic_operand")]
13490 UNSPEC_TLS_IE_SUN))
13491 (clobber (reg:CC FLAGS_REG))]
13492 "TARGET_64BIT && TARGET_SUN_TLS"
13495 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13496 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13498 [(set_attr "type" "multi")])
13500 ;; GNU2 TLS patterns can be split.
13502 (define_expand "tls_dynamic_gnu2_32"
13503 [(set (match_dup 3)
13504 (plus:SI (match_operand:SI 2 "register_operand")
13506 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13509 [(set (match_operand:SI 0 "register_operand")
13510 (unspec:SI [(match_dup 1) (match_dup 3)
13511 (match_dup 2) (reg:SI SP_REG)]
13513 (clobber (reg:CC FLAGS_REG))])]
13514 "!TARGET_64BIT && TARGET_GNU2_TLS"
13516 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13517 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13520 (define_insn "*tls_dynamic_gnu2_lea_32"
13521 [(set (match_operand:SI 0 "register_operand" "=r")
13522 (plus:SI (match_operand:SI 1 "register_operand" "b")
13524 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13525 UNSPEC_TLSDESC))))]
13526 "!TARGET_64BIT && TARGET_GNU2_TLS"
13527 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13528 [(set_attr "type" "lea")
13529 (set_attr "mode" "SI")
13530 (set_attr "length" "6")
13531 (set_attr "length_address" "4")])
13533 (define_insn "*tls_dynamic_gnu2_call_32"
13534 [(set (match_operand:SI 0 "register_operand" "=a")
13535 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13536 (match_operand:SI 2 "register_operand" "0")
13537 ;; we have to make sure %ebx still points to the GOT
13538 (match_operand:SI 3 "register_operand" "b")
13541 (clobber (reg:CC FLAGS_REG))]
13542 "!TARGET_64BIT && TARGET_GNU2_TLS"
13543 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13544 [(set_attr "type" "call")
13545 (set_attr "length" "2")
13546 (set_attr "length_address" "0")])
13548 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13549 [(set (match_operand:SI 0 "register_operand" "=&a")
13551 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13552 (match_operand:SI 4)
13553 (match_operand:SI 2 "register_operand" "b")
13556 (const:SI (unspec:SI
13557 [(match_operand 1 "tls_symbolic_operand")]
13559 (clobber (reg:CC FLAGS_REG))]
13560 "!TARGET_64BIT && TARGET_GNU2_TLS"
13563 [(set (match_dup 0) (match_dup 5))]
13565 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13566 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13569 (define_expand "tls_dynamic_gnu2_64"
13570 [(set (match_dup 2)
13571 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13574 [(set (match_operand:DI 0 "register_operand")
13575 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13577 (clobber (reg:CC FLAGS_REG))])]
13578 "TARGET_64BIT && TARGET_GNU2_TLS"
13580 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13581 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13584 (define_insn "*tls_dynamic_gnu2_lea_64"
13585 [(set (match_operand:DI 0 "register_operand" "=r")
13586 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13588 "TARGET_64BIT && TARGET_GNU2_TLS"
13589 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13590 [(set_attr "type" "lea")
13591 (set_attr "mode" "DI")
13592 (set_attr "length" "7")
13593 (set_attr "length_address" "4")])
13595 (define_insn "*tls_dynamic_gnu2_call_64"
13596 [(set (match_operand:DI 0 "register_operand" "=a")
13597 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13598 (match_operand:DI 2 "register_operand" "0")
13601 (clobber (reg:CC FLAGS_REG))]
13602 "TARGET_64BIT && TARGET_GNU2_TLS"
13603 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13604 [(set_attr "type" "call")
13605 (set_attr "length" "2")
13606 (set_attr "length_address" "0")])
13608 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13609 [(set (match_operand:DI 0 "register_operand" "=&a")
13611 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13612 (match_operand:DI 3)
13615 (const:DI (unspec:DI
13616 [(match_operand 1 "tls_symbolic_operand")]
13618 (clobber (reg:CC FLAGS_REG))]
13619 "TARGET_64BIT && TARGET_GNU2_TLS"
13622 [(set (match_dup 0) (match_dup 4))]
13624 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13625 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13628 ;; These patterns match the binary 387 instructions for addM3, subM3,
13629 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13630 ;; SFmode. The first is the normal insn, the second the same insn but
13631 ;; with one operand a conversion, and the third the same insn but with
13632 ;; the other operand a conversion. The conversion may be SFmode or
13633 ;; SImode if the target mode DFmode, but only SImode if the target mode
13636 ;; Gcc is slightly more smart about handling normal two address instructions
13637 ;; so use special patterns for add and mull.
13639 (define_insn "*fop_<mode>_comm_mixed"
13640 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13641 (match_operator:MODEF 3 "binary_fp_operator"
13642 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13643 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13644 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13645 && COMMUTATIVE_ARITH_P (operands[3])
13646 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13647 "* return output_387_binary_op (insn, operands);"
13648 [(set (attr "type")
13649 (if_then_else (eq_attr "alternative" "1,2")
13650 (if_then_else (match_operand:MODEF 3 "mult_operator")
13651 (const_string "ssemul")
13652 (const_string "sseadd"))
13653 (if_then_else (match_operand:MODEF 3 "mult_operator")
13654 (const_string "fmul")
13655 (const_string "fop"))))
13656 (set_attr "isa" "*,noavx,avx")
13657 (set_attr "prefix" "orig,orig,vex")
13658 (set_attr "mode" "<MODE>")])
13660 (define_insn "*fop_<mode>_comm_sse"
13661 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
13662 (match_operator:MODEF 3 "binary_fp_operator"
13663 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
13664 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
13665 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13666 && COMMUTATIVE_ARITH_P (operands[3])
13667 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13668 "* return output_387_binary_op (insn, operands);"
13669 [(set (attr "type")
13670 (if_then_else (match_operand:MODEF 3 "mult_operator")
13671 (const_string "ssemul")
13672 (const_string "sseadd")))
13673 (set_attr "isa" "noavx,avx")
13674 (set_attr "prefix" "orig,vex")
13675 (set_attr "mode" "<MODE>")])
13677 (define_insn "*fop_<mode>_comm_i387"
13678 [(set (match_operand:MODEF 0 "register_operand" "=f")
13679 (match_operator:MODEF 3 "binary_fp_operator"
13680 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13681 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13682 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13683 && COMMUTATIVE_ARITH_P (operands[3])
13684 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13685 "* return output_387_binary_op (insn, operands);"
13686 [(set (attr "type")
13687 (if_then_else (match_operand:MODEF 3 "mult_operator")
13688 (const_string "fmul")
13689 (const_string "fop")))
13690 (set_attr "mode" "<MODE>")])
13692 (define_insn "*fop_<mode>_1_mixed"
13693 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13694 (match_operator:MODEF 3 "binary_fp_operator"
13695 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13696 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13697 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13698 && !COMMUTATIVE_ARITH_P (operands[3])
13699 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13700 "* return output_387_binary_op (insn, operands);"
13701 [(set (attr "type")
13702 (cond [(and (eq_attr "alternative" "2,3")
13703 (match_operand:MODEF 3 "mult_operator"))
13704 (const_string "ssemul")
13705 (and (eq_attr "alternative" "2,3")
13706 (match_operand:MODEF 3 "div_operator"))
13707 (const_string "ssediv")
13708 (eq_attr "alternative" "2,3")
13709 (const_string "sseadd")
13710 (match_operand:MODEF 3 "mult_operator")
13711 (const_string "fmul")
13712 (match_operand:MODEF 3 "div_operator")
13713 (const_string "fdiv")
13715 (const_string "fop")))
13716 (set_attr "isa" "*,*,noavx,avx")
13717 (set_attr "prefix" "orig,orig,orig,vex")
13718 (set_attr "mode" "<MODE>")])
13720 (define_insn "*rcpsf2_sse"
13721 [(set (match_operand:SF 0 "register_operand" "=x")
13722 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13725 "%vrcpss\t{%1, %d0|%d0, %1}"
13726 [(set_attr "type" "sse")
13727 (set_attr "atom_sse_attr" "rcp")
13728 (set_attr "btver2_sse_attr" "rcp")
13729 (set_attr "prefix" "maybe_vex")
13730 (set_attr "mode" "SF")])
13732 (define_insn "*fop_<mode>_1_sse"
13733 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13734 (match_operator:MODEF 3 "binary_fp_operator"
13735 [(match_operand:MODEF 1 "register_operand" "0,x")
13736 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13737 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13738 && !COMMUTATIVE_ARITH_P (operands[3])"
13739 "* return output_387_binary_op (insn, operands);"
13740 [(set (attr "type")
13741 (cond [(match_operand:MODEF 3 "mult_operator")
13742 (const_string "ssemul")
13743 (match_operand:MODEF 3 "div_operator")
13744 (const_string "ssediv")
13746 (const_string "sseadd")))
13747 (set_attr "isa" "noavx,avx")
13748 (set_attr "prefix" "orig,vex")
13749 (set_attr "mode" "<MODE>")])
13751 ;; This pattern is not fully shadowed by the pattern above.
13752 (define_insn "*fop_<mode>_1_i387"
13753 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13754 (match_operator:MODEF 3 "binary_fp_operator"
13755 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13756 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13757 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13758 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13759 && !COMMUTATIVE_ARITH_P (operands[3])
13760 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13761 "* return output_387_binary_op (insn, operands);"
13762 [(set (attr "type")
13763 (cond [(match_operand:MODEF 3 "mult_operator")
13764 (const_string "fmul")
13765 (match_operand:MODEF 3 "div_operator")
13766 (const_string "fdiv")
13768 (const_string "fop")))
13769 (set_attr "mode" "<MODE>")])
13771 ;; ??? Add SSE splitters for these!
13772 (define_insn "*fop_<MODEF:mode>_2_i387"
13773 [(set (match_operand:MODEF 0 "register_operand" "=f")
13774 (match_operator:MODEF 3 "binary_fp_operator"
13776 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13777 (match_operand:MODEF 2 "register_operand" "0")]))]
13778 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13779 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13780 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13781 || optimize_function_for_size_p (cfun))"
13782 { return output_387_binary_op (insn, operands); }
13783 [(set (attr "type")
13784 (cond [(match_operand:MODEF 3 "mult_operator")
13785 (const_string "fmul")
13786 (match_operand:MODEF 3 "div_operator")
13787 (const_string "fdiv")
13789 (const_string "fop")))
13790 (set_attr "fp_int_src" "true")
13791 (set_attr "mode" "<SWI24:MODE>")])
13793 (define_insn "*fop_<MODEF:mode>_3_i387"
13794 [(set (match_operand:MODEF 0 "register_operand" "=f")
13795 (match_operator:MODEF 3 "binary_fp_operator"
13796 [(match_operand:MODEF 1 "register_operand" "0")
13798 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13799 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13800 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13801 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13802 || optimize_function_for_size_p (cfun))"
13803 { return output_387_binary_op (insn, operands); }
13804 [(set (attr "type")
13805 (cond [(match_operand:MODEF 3 "mult_operator")
13806 (const_string "fmul")
13807 (match_operand:MODEF 3 "div_operator")
13808 (const_string "fdiv")
13810 (const_string "fop")))
13811 (set_attr "fp_int_src" "true")
13812 (set_attr "mode" "<MODE>")])
13814 (define_insn "*fop_df_4_i387"
13815 [(set (match_operand:DF 0 "register_operand" "=f,f")
13816 (match_operator:DF 3 "binary_fp_operator"
13818 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13819 (match_operand:DF 2 "register_operand" "0,f")]))]
13820 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13821 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13822 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13823 "* return output_387_binary_op (insn, operands);"
13824 [(set (attr "type")
13825 (cond [(match_operand:DF 3 "mult_operator")
13826 (const_string "fmul")
13827 (match_operand:DF 3 "div_operator")
13828 (const_string "fdiv")
13830 (const_string "fop")))
13831 (set_attr "mode" "SF")])
13833 (define_insn "*fop_df_5_i387"
13834 [(set (match_operand:DF 0 "register_operand" "=f,f")
13835 (match_operator:DF 3 "binary_fp_operator"
13836 [(match_operand:DF 1 "register_operand" "0,f")
13838 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13839 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13840 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13841 "* return output_387_binary_op (insn, operands);"
13842 [(set (attr "type")
13843 (cond [(match_operand:DF 3 "mult_operator")
13844 (const_string "fmul")
13845 (match_operand:DF 3 "div_operator")
13846 (const_string "fdiv")
13848 (const_string "fop")))
13849 (set_attr "mode" "SF")])
13851 (define_insn "*fop_df_6_i387"
13852 [(set (match_operand:DF 0 "register_operand" "=f,f")
13853 (match_operator:DF 3 "binary_fp_operator"
13855 (match_operand:SF 1 "register_operand" "0,f"))
13857 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13858 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13859 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13860 "* return output_387_binary_op (insn, operands);"
13861 [(set (attr "type")
13862 (cond [(match_operand:DF 3 "mult_operator")
13863 (const_string "fmul")
13864 (match_operand:DF 3 "div_operator")
13865 (const_string "fdiv")
13867 (const_string "fop")))
13868 (set_attr "mode" "SF")])
13870 (define_insn "*fop_xf_comm_i387"
13871 [(set (match_operand:XF 0 "register_operand" "=f")
13872 (match_operator:XF 3 "binary_fp_operator"
13873 [(match_operand:XF 1 "register_operand" "%0")
13874 (match_operand:XF 2 "register_operand" "f")]))]
13876 && COMMUTATIVE_ARITH_P (operands[3])"
13877 "* return output_387_binary_op (insn, operands);"
13878 [(set (attr "type")
13879 (if_then_else (match_operand:XF 3 "mult_operator")
13880 (const_string "fmul")
13881 (const_string "fop")))
13882 (set_attr "mode" "XF")])
13884 (define_insn "*fop_xf_1_i387"
13885 [(set (match_operand:XF 0 "register_operand" "=f,f")
13886 (match_operator:XF 3 "binary_fp_operator"
13887 [(match_operand:XF 1 "register_operand" "0,f")
13888 (match_operand:XF 2 "register_operand" "f,0")]))]
13890 && !COMMUTATIVE_ARITH_P (operands[3])"
13891 "* return output_387_binary_op (insn, operands);"
13892 [(set (attr "type")
13893 (cond [(match_operand:XF 3 "mult_operator")
13894 (const_string "fmul")
13895 (match_operand:XF 3 "div_operator")
13896 (const_string "fdiv")
13898 (const_string "fop")))
13899 (set_attr "mode" "XF")])
13901 (define_insn "*fop_xf_2_i387"
13902 [(set (match_operand:XF 0 "register_operand" "=f")
13903 (match_operator:XF 3 "binary_fp_operator"
13905 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13906 (match_operand:XF 2 "register_operand" "0")]))]
13908 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13909 { return output_387_binary_op (insn, operands); }
13910 [(set (attr "type")
13911 (cond [(match_operand:XF 3 "mult_operator")
13912 (const_string "fmul")
13913 (match_operand:XF 3 "div_operator")
13914 (const_string "fdiv")
13916 (const_string "fop")))
13917 (set_attr "fp_int_src" "true")
13918 (set_attr "mode" "<MODE>")])
13920 (define_insn "*fop_xf_3_i387"
13921 [(set (match_operand:XF 0 "register_operand" "=f")
13922 (match_operator:XF 3 "binary_fp_operator"
13923 [(match_operand:XF 1 "register_operand" "0")
13925 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13927 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13928 { return output_387_binary_op (insn, operands); }
13929 [(set (attr "type")
13930 (cond [(match_operand:XF 3 "mult_operator")
13931 (const_string "fmul")
13932 (match_operand:XF 3 "div_operator")
13933 (const_string "fdiv")
13935 (const_string "fop")))
13936 (set_attr "fp_int_src" "true")
13937 (set_attr "mode" "<MODE>")])
13939 (define_insn "*fop_xf_4_i387"
13940 [(set (match_operand:XF 0 "register_operand" "=f,f")
13941 (match_operator:XF 3 "binary_fp_operator"
13943 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13944 (match_operand:XF 2 "register_operand" "0,f")]))]
13946 "* return output_387_binary_op (insn, operands);"
13947 [(set (attr "type")
13948 (cond [(match_operand:XF 3 "mult_operator")
13949 (const_string "fmul")
13950 (match_operand:XF 3 "div_operator")
13951 (const_string "fdiv")
13953 (const_string "fop")))
13954 (set_attr "mode" "<MODE>")])
13956 (define_insn "*fop_xf_5_i387"
13957 [(set (match_operand:XF 0 "register_operand" "=f,f")
13958 (match_operator:XF 3 "binary_fp_operator"
13959 [(match_operand:XF 1 "register_operand" "0,f")
13961 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13963 "* return output_387_binary_op (insn, operands);"
13964 [(set (attr "type")
13965 (cond [(match_operand:XF 3 "mult_operator")
13966 (const_string "fmul")
13967 (match_operand:XF 3 "div_operator")
13968 (const_string "fdiv")
13970 (const_string "fop")))
13971 (set_attr "mode" "<MODE>")])
13973 (define_insn "*fop_xf_6_i387"
13974 [(set (match_operand:XF 0 "register_operand" "=f,f")
13975 (match_operator:XF 3 "binary_fp_operator"
13977 (match_operand:MODEF 1 "register_operand" "0,f"))
13979 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13981 "* return output_387_binary_op (insn, operands);"
13982 [(set (attr "type")
13983 (cond [(match_operand:XF 3 "mult_operator")
13984 (const_string "fmul")
13985 (match_operand:XF 3 "div_operator")
13986 (const_string "fdiv")
13988 (const_string "fop")))
13989 (set_attr "mode" "<MODE>")])
13991 ;; FPU special functions.
13993 ;; This pattern implements a no-op XFmode truncation for
13994 ;; all fancy i386 XFmode math functions.
13996 (define_insn "truncxf<mode>2_i387_noop_unspec"
13997 [(set (match_operand:MODEF 0 "register_operand" "=f")
13998 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13999 UNSPEC_TRUNC_NOOP))]
14000 "TARGET_USE_FANCY_MATH_387"
14001 "* return output_387_reg_move (insn, operands);"
14002 [(set_attr "type" "fmov")
14003 (set_attr "mode" "<MODE>")])
14005 (define_insn "sqrtxf2"
14006 [(set (match_operand:XF 0 "register_operand" "=f")
14007 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14008 "TARGET_USE_FANCY_MATH_387"
14010 [(set_attr "type" "fpspc")
14011 (set_attr "mode" "XF")
14012 (set_attr "athlon_decode" "direct")
14013 (set_attr "amdfam10_decode" "direct")
14014 (set_attr "bdver1_decode" "direct")])
14016 (define_insn "sqrt_extend<mode>xf2_i387"
14017 [(set (match_operand:XF 0 "register_operand" "=f")
14020 (match_operand:MODEF 1 "register_operand" "0"))))]
14021 "TARGET_USE_FANCY_MATH_387"
14023 [(set_attr "type" "fpspc")
14024 (set_attr "mode" "XF")
14025 (set_attr "athlon_decode" "direct")
14026 (set_attr "amdfam10_decode" "direct")
14027 (set_attr "bdver1_decode" "direct")])
14029 (define_insn "*rsqrtsf2_sse"
14030 [(set (match_operand:SF 0 "register_operand" "=x")
14031 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14034 "%vrsqrtss\t{%1, %d0|%d0, %1}"
14035 [(set_attr "type" "sse")
14036 (set_attr "atom_sse_attr" "rcp")
14037 (set_attr "btver2_sse_attr" "rcp")
14038 (set_attr "prefix" "maybe_vex")
14039 (set_attr "mode" "SF")])
14041 (define_expand "rsqrtsf2"
14042 [(set (match_operand:SF 0 "register_operand")
14043 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
14047 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
14051 (define_insn "*sqrt<mode>2_sse"
14052 [(set (match_operand:MODEF 0 "register_operand" "=x")
14054 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
14055 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14056 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
14057 [(set_attr "type" "sse")
14058 (set_attr "atom_sse_attr" "sqrt")
14059 (set_attr "btver2_sse_attr" "sqrt")
14060 (set_attr "prefix" "maybe_vex")
14061 (set_attr "mode" "<MODE>")
14062 (set_attr "athlon_decode" "*")
14063 (set_attr "amdfam10_decode" "*")
14064 (set_attr "bdver1_decode" "*")])
14066 (define_expand "sqrt<mode>2"
14067 [(set (match_operand:MODEF 0 "register_operand")
14069 (match_operand:MODEF 1 "nonimmediate_operand")))]
14070 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
14071 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14073 if (<MODE>mode == SFmode
14075 && TARGET_RECIP_SQRT
14076 && !optimize_function_for_size_p (cfun)
14077 && flag_finite_math_only && !flag_trapping_math
14078 && flag_unsafe_math_optimizations)
14080 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
14084 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
14086 rtx op0 = gen_reg_rtx (XFmode);
14087 rtx op1 = force_reg (<MODE>mode, operands[1]);
14089 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
14090 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
14095 (define_insn "fpremxf4_i387"
14096 [(set (match_operand:XF 0 "register_operand" "=f")
14097 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14098 (match_operand:XF 3 "register_operand" "1")]
14100 (set (match_operand:XF 1 "register_operand" "=u")
14101 (unspec:XF [(match_dup 2) (match_dup 3)]
14103 (set (reg:CCFP FPSR_REG)
14104 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14106 "TARGET_USE_FANCY_MATH_387
14107 && flag_finite_math_only"
14109 [(set_attr "type" "fpspc")
14110 (set_attr "mode" "XF")])
14112 (define_expand "fmodxf3"
14113 [(use (match_operand:XF 0 "register_operand"))
14114 (use (match_operand:XF 1 "general_operand"))
14115 (use (match_operand:XF 2 "general_operand"))]
14116 "TARGET_USE_FANCY_MATH_387
14117 && flag_finite_math_only"
14119 rtx_code_label *label = gen_label_rtx ();
14121 rtx op1 = gen_reg_rtx (XFmode);
14122 rtx op2 = gen_reg_rtx (XFmode);
14124 emit_move_insn (op2, operands[2]);
14125 emit_move_insn (op1, operands[1]);
14127 emit_label (label);
14128 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14129 ix86_emit_fp_unordered_jump (label);
14130 LABEL_NUSES (label) = 1;
14132 emit_move_insn (operands[0], op1);
14136 (define_expand "fmod<mode>3"
14137 [(use (match_operand:MODEF 0 "register_operand"))
14138 (use (match_operand:MODEF 1 "general_operand"))
14139 (use (match_operand:MODEF 2 "general_operand"))]
14140 "TARGET_USE_FANCY_MATH_387
14141 && flag_finite_math_only"
14143 rtx (*gen_truncxf) (rtx, rtx);
14145 rtx_code_label *label = gen_label_rtx ();
14147 rtx op1 = gen_reg_rtx (XFmode);
14148 rtx op2 = gen_reg_rtx (XFmode);
14150 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14151 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14153 emit_label (label);
14154 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14155 ix86_emit_fp_unordered_jump (label);
14156 LABEL_NUSES (label) = 1;
14158 /* Truncate the result properly for strict SSE math. */
14159 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14160 && !TARGET_MIX_SSE_I387)
14161 gen_truncxf = gen_truncxf<mode>2;
14163 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14165 emit_insn (gen_truncxf (operands[0], op1));
14169 (define_insn "fprem1xf4_i387"
14170 [(set (match_operand:XF 0 "register_operand" "=f")
14171 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14172 (match_operand:XF 3 "register_operand" "1")]
14174 (set (match_operand:XF 1 "register_operand" "=u")
14175 (unspec:XF [(match_dup 2) (match_dup 3)]
14177 (set (reg:CCFP FPSR_REG)
14178 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14180 "TARGET_USE_FANCY_MATH_387
14181 && flag_finite_math_only"
14183 [(set_attr "type" "fpspc")
14184 (set_attr "mode" "XF")])
14186 (define_expand "remainderxf3"
14187 [(use (match_operand:XF 0 "register_operand"))
14188 (use (match_operand:XF 1 "general_operand"))
14189 (use (match_operand:XF 2 "general_operand"))]
14190 "TARGET_USE_FANCY_MATH_387
14191 && flag_finite_math_only"
14193 rtx_code_label *label = gen_label_rtx ();
14195 rtx op1 = gen_reg_rtx (XFmode);
14196 rtx op2 = gen_reg_rtx (XFmode);
14198 emit_move_insn (op2, operands[2]);
14199 emit_move_insn (op1, operands[1]);
14201 emit_label (label);
14202 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14203 ix86_emit_fp_unordered_jump (label);
14204 LABEL_NUSES (label) = 1;
14206 emit_move_insn (operands[0], op1);
14210 (define_expand "remainder<mode>3"
14211 [(use (match_operand:MODEF 0 "register_operand"))
14212 (use (match_operand:MODEF 1 "general_operand"))
14213 (use (match_operand:MODEF 2 "general_operand"))]
14214 "TARGET_USE_FANCY_MATH_387
14215 && flag_finite_math_only"
14217 rtx (*gen_truncxf) (rtx, rtx);
14219 rtx_code_label *label = gen_label_rtx ();
14221 rtx op1 = gen_reg_rtx (XFmode);
14222 rtx op2 = gen_reg_rtx (XFmode);
14224 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14225 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14227 emit_label (label);
14229 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14230 ix86_emit_fp_unordered_jump (label);
14231 LABEL_NUSES (label) = 1;
14233 /* Truncate the result properly for strict SSE math. */
14234 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14235 && !TARGET_MIX_SSE_I387)
14236 gen_truncxf = gen_truncxf<mode>2;
14238 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14240 emit_insn (gen_truncxf (operands[0], op1));
14244 (define_int_iterator SINCOS
14248 (define_int_attr sincos
14249 [(UNSPEC_SIN "sin")
14250 (UNSPEC_COS "cos")])
14252 (define_insn "*<sincos>xf2_i387"
14253 [(set (match_operand:XF 0 "register_operand" "=f")
14254 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14256 "TARGET_USE_FANCY_MATH_387
14257 && flag_unsafe_math_optimizations"
14259 [(set_attr "type" "fpspc")
14260 (set_attr "mode" "XF")])
14262 (define_insn "*<sincos>_extend<mode>xf2_i387"
14263 [(set (match_operand:XF 0 "register_operand" "=f")
14264 (unspec:XF [(float_extend:XF
14265 (match_operand:MODEF 1 "register_operand" "0"))]
14267 "TARGET_USE_FANCY_MATH_387
14268 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14269 || TARGET_MIX_SSE_I387)
14270 && flag_unsafe_math_optimizations"
14272 [(set_attr "type" "fpspc")
14273 (set_attr "mode" "XF")])
14275 ;; When sincos pattern is defined, sin and cos builtin functions will be
14276 ;; expanded to sincos pattern with one of its outputs left unused.
14277 ;; CSE pass will figure out if two sincos patterns can be combined,
14278 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14279 ;; depending on the unused output.
14281 (define_insn "sincosxf3"
14282 [(set (match_operand:XF 0 "register_operand" "=f")
14283 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14284 UNSPEC_SINCOS_COS))
14285 (set (match_operand:XF 1 "register_operand" "=u")
14286 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14287 "TARGET_USE_FANCY_MATH_387
14288 && flag_unsafe_math_optimizations"
14290 [(set_attr "type" "fpspc")
14291 (set_attr "mode" "XF")])
14294 [(set (match_operand:XF 0 "register_operand")
14295 (unspec:XF [(match_operand:XF 2 "register_operand")]
14296 UNSPEC_SINCOS_COS))
14297 (set (match_operand:XF 1 "register_operand")
14298 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14299 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14300 && can_create_pseudo_p ()"
14301 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14304 [(set (match_operand:XF 0 "register_operand")
14305 (unspec:XF [(match_operand:XF 2 "register_operand")]
14306 UNSPEC_SINCOS_COS))
14307 (set (match_operand:XF 1 "register_operand")
14308 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14309 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14310 && can_create_pseudo_p ()"
14311 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14313 (define_insn "sincos_extend<mode>xf3_i387"
14314 [(set (match_operand:XF 0 "register_operand" "=f")
14315 (unspec:XF [(float_extend:XF
14316 (match_operand:MODEF 2 "register_operand" "0"))]
14317 UNSPEC_SINCOS_COS))
14318 (set (match_operand:XF 1 "register_operand" "=u")
14319 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14320 "TARGET_USE_FANCY_MATH_387
14321 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14322 || TARGET_MIX_SSE_I387)
14323 && flag_unsafe_math_optimizations"
14325 [(set_attr "type" "fpspc")
14326 (set_attr "mode" "XF")])
14329 [(set (match_operand:XF 0 "register_operand")
14330 (unspec:XF [(float_extend:XF
14331 (match_operand:MODEF 2 "register_operand"))]
14332 UNSPEC_SINCOS_COS))
14333 (set (match_operand:XF 1 "register_operand")
14334 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14335 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14336 && can_create_pseudo_p ()"
14337 [(set (match_dup 1)
14338 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14341 [(set (match_operand:XF 0 "register_operand")
14342 (unspec:XF [(float_extend:XF
14343 (match_operand:MODEF 2 "register_operand"))]
14344 UNSPEC_SINCOS_COS))
14345 (set (match_operand:XF 1 "register_operand")
14346 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14347 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14348 && can_create_pseudo_p ()"
14349 [(set (match_dup 0)
14350 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14352 (define_expand "sincos<mode>3"
14353 [(use (match_operand:MODEF 0 "register_operand"))
14354 (use (match_operand:MODEF 1 "register_operand"))
14355 (use (match_operand:MODEF 2 "register_operand"))]
14356 "TARGET_USE_FANCY_MATH_387
14357 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14358 || TARGET_MIX_SSE_I387)
14359 && flag_unsafe_math_optimizations"
14361 rtx op0 = gen_reg_rtx (XFmode);
14362 rtx op1 = gen_reg_rtx (XFmode);
14364 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14365 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14366 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14370 (define_insn "fptanxf4_i387"
14371 [(set (match_operand:XF 0 "register_operand" "=f")
14372 (match_operand:XF 3 "const_double_operand" "F"))
14373 (set (match_operand:XF 1 "register_operand" "=u")
14374 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14376 "TARGET_USE_FANCY_MATH_387
14377 && flag_unsafe_math_optimizations
14378 && standard_80387_constant_p (operands[3]) == 2"
14380 [(set_attr "type" "fpspc")
14381 (set_attr "mode" "XF")])
14383 (define_insn "fptan_extend<mode>xf4_i387"
14384 [(set (match_operand:MODEF 0 "register_operand" "=f")
14385 (match_operand:MODEF 3 "const_double_operand" "F"))
14386 (set (match_operand:XF 1 "register_operand" "=u")
14387 (unspec:XF [(float_extend:XF
14388 (match_operand:MODEF 2 "register_operand" "0"))]
14390 "TARGET_USE_FANCY_MATH_387
14391 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14392 || TARGET_MIX_SSE_I387)
14393 && flag_unsafe_math_optimizations
14394 && standard_80387_constant_p (operands[3]) == 2"
14396 [(set_attr "type" "fpspc")
14397 (set_attr "mode" "XF")])
14399 (define_expand "tanxf2"
14400 [(use (match_operand:XF 0 "register_operand"))
14401 (use (match_operand:XF 1 "register_operand"))]
14402 "TARGET_USE_FANCY_MATH_387
14403 && flag_unsafe_math_optimizations"
14405 rtx one = gen_reg_rtx (XFmode);
14406 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14408 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14412 (define_expand "tan<mode>2"
14413 [(use (match_operand:MODEF 0 "register_operand"))
14414 (use (match_operand:MODEF 1 "register_operand"))]
14415 "TARGET_USE_FANCY_MATH_387
14416 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14417 || TARGET_MIX_SSE_I387)
14418 && flag_unsafe_math_optimizations"
14420 rtx op0 = gen_reg_rtx (XFmode);
14422 rtx one = gen_reg_rtx (<MODE>mode);
14423 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14425 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14426 operands[1], op2));
14427 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14431 (define_insn "*fpatanxf3_i387"
14432 [(set (match_operand:XF 0 "register_operand" "=f")
14433 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14434 (match_operand:XF 2 "register_operand" "u")]
14436 (clobber (match_scratch:XF 3 "=2"))]
14437 "TARGET_USE_FANCY_MATH_387
14438 && flag_unsafe_math_optimizations"
14440 [(set_attr "type" "fpspc")
14441 (set_attr "mode" "XF")])
14443 (define_insn "fpatan_extend<mode>xf3_i387"
14444 [(set (match_operand:XF 0 "register_operand" "=f")
14445 (unspec:XF [(float_extend:XF
14446 (match_operand:MODEF 1 "register_operand" "0"))
14448 (match_operand:MODEF 2 "register_operand" "u"))]
14450 (clobber (match_scratch:XF 3 "=2"))]
14451 "TARGET_USE_FANCY_MATH_387
14452 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14453 || TARGET_MIX_SSE_I387)
14454 && flag_unsafe_math_optimizations"
14456 [(set_attr "type" "fpspc")
14457 (set_attr "mode" "XF")])
14459 (define_expand "atan2xf3"
14460 [(parallel [(set (match_operand:XF 0 "register_operand")
14461 (unspec:XF [(match_operand:XF 2 "register_operand")
14462 (match_operand:XF 1 "register_operand")]
14464 (clobber (match_scratch:XF 3))])]
14465 "TARGET_USE_FANCY_MATH_387
14466 && flag_unsafe_math_optimizations")
14468 (define_expand "atan2<mode>3"
14469 [(use (match_operand:MODEF 0 "register_operand"))
14470 (use (match_operand:MODEF 1 "register_operand"))
14471 (use (match_operand:MODEF 2 "register_operand"))]
14472 "TARGET_USE_FANCY_MATH_387
14473 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14474 || TARGET_MIX_SSE_I387)
14475 && flag_unsafe_math_optimizations"
14477 rtx op0 = gen_reg_rtx (XFmode);
14479 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14480 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14484 (define_expand "atanxf2"
14485 [(parallel [(set (match_operand:XF 0 "register_operand")
14486 (unspec:XF [(match_dup 2)
14487 (match_operand:XF 1 "register_operand")]
14489 (clobber (match_scratch:XF 3))])]
14490 "TARGET_USE_FANCY_MATH_387
14491 && flag_unsafe_math_optimizations"
14493 operands[2] = gen_reg_rtx (XFmode);
14494 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14497 (define_expand "atan<mode>2"
14498 [(use (match_operand:MODEF 0 "register_operand"))
14499 (use (match_operand:MODEF 1 "register_operand"))]
14500 "TARGET_USE_FANCY_MATH_387
14501 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14502 || TARGET_MIX_SSE_I387)
14503 && flag_unsafe_math_optimizations"
14505 rtx op0 = gen_reg_rtx (XFmode);
14507 rtx op2 = gen_reg_rtx (<MODE>mode);
14508 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14510 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14511 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14515 (define_expand "asinxf2"
14516 [(set (match_dup 2)
14517 (mult:XF (match_operand:XF 1 "register_operand")
14519 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14520 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14521 (parallel [(set (match_operand:XF 0 "register_operand")
14522 (unspec:XF [(match_dup 5) (match_dup 1)]
14524 (clobber (match_scratch:XF 6))])]
14525 "TARGET_USE_FANCY_MATH_387
14526 && flag_unsafe_math_optimizations"
14530 if (optimize_insn_for_size_p ())
14533 for (i = 2; i < 6; i++)
14534 operands[i] = gen_reg_rtx (XFmode);
14536 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14539 (define_expand "asin<mode>2"
14540 [(use (match_operand:MODEF 0 "register_operand"))
14541 (use (match_operand:MODEF 1 "general_operand"))]
14542 "TARGET_USE_FANCY_MATH_387
14543 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14544 || TARGET_MIX_SSE_I387)
14545 && flag_unsafe_math_optimizations"
14547 rtx op0 = gen_reg_rtx (XFmode);
14548 rtx op1 = gen_reg_rtx (XFmode);
14550 if (optimize_insn_for_size_p ())
14553 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14554 emit_insn (gen_asinxf2 (op0, op1));
14555 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14559 (define_expand "acosxf2"
14560 [(set (match_dup 2)
14561 (mult:XF (match_operand:XF 1 "register_operand")
14563 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14564 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14565 (parallel [(set (match_operand:XF 0 "register_operand")
14566 (unspec:XF [(match_dup 1) (match_dup 5)]
14568 (clobber (match_scratch:XF 6))])]
14569 "TARGET_USE_FANCY_MATH_387
14570 && flag_unsafe_math_optimizations"
14574 if (optimize_insn_for_size_p ())
14577 for (i = 2; i < 6; i++)
14578 operands[i] = gen_reg_rtx (XFmode);
14580 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14583 (define_expand "acos<mode>2"
14584 [(use (match_operand:MODEF 0 "register_operand"))
14585 (use (match_operand:MODEF 1 "general_operand"))]
14586 "TARGET_USE_FANCY_MATH_387
14587 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14588 || TARGET_MIX_SSE_I387)
14589 && flag_unsafe_math_optimizations"
14591 rtx op0 = gen_reg_rtx (XFmode);
14592 rtx op1 = gen_reg_rtx (XFmode);
14594 if (optimize_insn_for_size_p ())
14597 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14598 emit_insn (gen_acosxf2 (op0, op1));
14599 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14603 (define_insn "fyl2xxf3_i387"
14604 [(set (match_operand:XF 0 "register_operand" "=f")
14605 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14606 (match_operand:XF 2 "register_operand" "u")]
14608 (clobber (match_scratch:XF 3 "=2"))]
14609 "TARGET_USE_FANCY_MATH_387
14610 && flag_unsafe_math_optimizations"
14612 [(set_attr "type" "fpspc")
14613 (set_attr "mode" "XF")])
14615 (define_insn "fyl2x_extend<mode>xf3_i387"
14616 [(set (match_operand:XF 0 "register_operand" "=f")
14617 (unspec:XF [(float_extend:XF
14618 (match_operand:MODEF 1 "register_operand" "0"))
14619 (match_operand:XF 2 "register_operand" "u")]
14621 (clobber (match_scratch:XF 3 "=2"))]
14622 "TARGET_USE_FANCY_MATH_387
14623 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14624 || TARGET_MIX_SSE_I387)
14625 && flag_unsafe_math_optimizations"
14627 [(set_attr "type" "fpspc")
14628 (set_attr "mode" "XF")])
14630 (define_expand "logxf2"
14631 [(parallel [(set (match_operand:XF 0 "register_operand")
14632 (unspec:XF [(match_operand:XF 1 "register_operand")
14633 (match_dup 2)] UNSPEC_FYL2X))
14634 (clobber (match_scratch:XF 3))])]
14635 "TARGET_USE_FANCY_MATH_387
14636 && flag_unsafe_math_optimizations"
14638 operands[2] = gen_reg_rtx (XFmode);
14639 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14642 (define_expand "log<mode>2"
14643 [(use (match_operand:MODEF 0 "register_operand"))
14644 (use (match_operand:MODEF 1 "register_operand"))]
14645 "TARGET_USE_FANCY_MATH_387
14646 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14647 || TARGET_MIX_SSE_I387)
14648 && flag_unsafe_math_optimizations"
14650 rtx op0 = gen_reg_rtx (XFmode);
14652 rtx op2 = gen_reg_rtx (XFmode);
14653 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14655 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14656 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14660 (define_expand "log10xf2"
14661 [(parallel [(set (match_operand:XF 0 "register_operand")
14662 (unspec:XF [(match_operand:XF 1 "register_operand")
14663 (match_dup 2)] UNSPEC_FYL2X))
14664 (clobber (match_scratch:XF 3))])]
14665 "TARGET_USE_FANCY_MATH_387
14666 && flag_unsafe_math_optimizations"
14668 operands[2] = gen_reg_rtx (XFmode);
14669 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14672 (define_expand "log10<mode>2"
14673 [(use (match_operand:MODEF 0 "register_operand"))
14674 (use (match_operand:MODEF 1 "register_operand"))]
14675 "TARGET_USE_FANCY_MATH_387
14676 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14677 || TARGET_MIX_SSE_I387)
14678 && flag_unsafe_math_optimizations"
14680 rtx op0 = gen_reg_rtx (XFmode);
14682 rtx op2 = gen_reg_rtx (XFmode);
14683 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14685 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14686 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14690 (define_expand "log2xf2"
14691 [(parallel [(set (match_operand:XF 0 "register_operand")
14692 (unspec:XF [(match_operand:XF 1 "register_operand")
14693 (match_dup 2)] UNSPEC_FYL2X))
14694 (clobber (match_scratch:XF 3))])]
14695 "TARGET_USE_FANCY_MATH_387
14696 && flag_unsafe_math_optimizations"
14698 operands[2] = gen_reg_rtx (XFmode);
14699 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14702 (define_expand "log2<mode>2"
14703 [(use (match_operand:MODEF 0 "register_operand"))
14704 (use (match_operand:MODEF 1 "register_operand"))]
14705 "TARGET_USE_FANCY_MATH_387
14706 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14707 || TARGET_MIX_SSE_I387)
14708 && flag_unsafe_math_optimizations"
14710 rtx op0 = gen_reg_rtx (XFmode);
14712 rtx op2 = gen_reg_rtx (XFmode);
14713 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14715 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14716 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14720 (define_insn "fyl2xp1xf3_i387"
14721 [(set (match_operand:XF 0 "register_operand" "=f")
14722 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14723 (match_operand:XF 2 "register_operand" "u")]
14725 (clobber (match_scratch:XF 3 "=2"))]
14726 "TARGET_USE_FANCY_MATH_387
14727 && flag_unsafe_math_optimizations"
14729 [(set_attr "type" "fpspc")
14730 (set_attr "mode" "XF")])
14732 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14733 [(set (match_operand:XF 0 "register_operand" "=f")
14734 (unspec:XF [(float_extend:XF
14735 (match_operand:MODEF 1 "register_operand" "0"))
14736 (match_operand:XF 2 "register_operand" "u")]
14738 (clobber (match_scratch:XF 3 "=2"))]
14739 "TARGET_USE_FANCY_MATH_387
14740 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14741 || TARGET_MIX_SSE_I387)
14742 && flag_unsafe_math_optimizations"
14744 [(set_attr "type" "fpspc")
14745 (set_attr "mode" "XF")])
14747 (define_expand "log1pxf2"
14748 [(use (match_operand:XF 0 "register_operand"))
14749 (use (match_operand:XF 1 "register_operand"))]
14750 "TARGET_USE_FANCY_MATH_387
14751 && flag_unsafe_math_optimizations"
14753 if (optimize_insn_for_size_p ())
14756 ix86_emit_i387_log1p (operands[0], operands[1]);
14760 (define_expand "log1p<mode>2"
14761 [(use (match_operand:MODEF 0 "register_operand"))
14762 (use (match_operand:MODEF 1 "register_operand"))]
14763 "TARGET_USE_FANCY_MATH_387
14764 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14765 || TARGET_MIX_SSE_I387)
14766 && flag_unsafe_math_optimizations"
14770 if (optimize_insn_for_size_p ())
14773 op0 = gen_reg_rtx (XFmode);
14775 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14777 ix86_emit_i387_log1p (op0, operands[1]);
14778 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14782 (define_insn "fxtractxf3_i387"
14783 [(set (match_operand:XF 0 "register_operand" "=f")
14784 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14785 UNSPEC_XTRACT_FRACT))
14786 (set (match_operand:XF 1 "register_operand" "=u")
14787 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14788 "TARGET_USE_FANCY_MATH_387
14789 && flag_unsafe_math_optimizations"
14791 [(set_attr "type" "fpspc")
14792 (set_attr "mode" "XF")])
14794 (define_insn "fxtract_extend<mode>xf3_i387"
14795 [(set (match_operand:XF 0 "register_operand" "=f")
14796 (unspec:XF [(float_extend:XF
14797 (match_operand:MODEF 2 "register_operand" "0"))]
14798 UNSPEC_XTRACT_FRACT))
14799 (set (match_operand:XF 1 "register_operand" "=u")
14800 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14801 "TARGET_USE_FANCY_MATH_387
14802 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14803 || TARGET_MIX_SSE_I387)
14804 && flag_unsafe_math_optimizations"
14806 [(set_attr "type" "fpspc")
14807 (set_attr "mode" "XF")])
14809 (define_expand "logbxf2"
14810 [(parallel [(set (match_dup 2)
14811 (unspec:XF [(match_operand:XF 1 "register_operand")]
14812 UNSPEC_XTRACT_FRACT))
14813 (set (match_operand:XF 0 "register_operand")
14814 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14815 "TARGET_USE_FANCY_MATH_387
14816 && flag_unsafe_math_optimizations"
14817 "operands[2] = gen_reg_rtx (XFmode);")
14819 (define_expand "logb<mode>2"
14820 [(use (match_operand:MODEF 0 "register_operand"))
14821 (use (match_operand:MODEF 1 "register_operand"))]
14822 "TARGET_USE_FANCY_MATH_387
14823 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14824 || TARGET_MIX_SSE_I387)
14825 && flag_unsafe_math_optimizations"
14827 rtx op0 = gen_reg_rtx (XFmode);
14828 rtx op1 = gen_reg_rtx (XFmode);
14830 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14831 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14835 (define_expand "ilogbxf2"
14836 [(use (match_operand:SI 0 "register_operand"))
14837 (use (match_operand:XF 1 "register_operand"))]
14838 "TARGET_USE_FANCY_MATH_387
14839 && flag_unsafe_math_optimizations"
14843 if (optimize_insn_for_size_p ())
14846 op0 = gen_reg_rtx (XFmode);
14847 op1 = gen_reg_rtx (XFmode);
14849 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14850 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14854 (define_expand "ilogb<mode>2"
14855 [(use (match_operand:SI 0 "register_operand"))
14856 (use (match_operand:MODEF 1 "register_operand"))]
14857 "TARGET_USE_FANCY_MATH_387
14858 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14859 || TARGET_MIX_SSE_I387)
14860 && flag_unsafe_math_optimizations"
14864 if (optimize_insn_for_size_p ())
14867 op0 = gen_reg_rtx (XFmode);
14868 op1 = gen_reg_rtx (XFmode);
14870 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14871 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14875 (define_insn "*f2xm1xf2_i387"
14876 [(set (match_operand:XF 0 "register_operand" "=f")
14877 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14879 "TARGET_USE_FANCY_MATH_387
14880 && flag_unsafe_math_optimizations"
14882 [(set_attr "type" "fpspc")
14883 (set_attr "mode" "XF")])
14885 (define_insn "fscalexf4_i387"
14886 [(set (match_operand:XF 0 "register_operand" "=f")
14887 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14888 (match_operand:XF 3 "register_operand" "1")]
14889 UNSPEC_FSCALE_FRACT))
14890 (set (match_operand:XF 1 "register_operand" "=u")
14891 (unspec:XF [(match_dup 2) (match_dup 3)]
14892 UNSPEC_FSCALE_EXP))]
14893 "TARGET_USE_FANCY_MATH_387
14894 && flag_unsafe_math_optimizations"
14896 [(set_attr "type" "fpspc")
14897 (set_attr "mode" "XF")])
14899 (define_expand "expNcorexf3"
14900 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14901 (match_operand:XF 2 "register_operand")))
14902 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14903 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14904 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14905 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14906 (parallel [(set (match_operand:XF 0 "register_operand")
14907 (unspec:XF [(match_dup 8) (match_dup 4)]
14908 UNSPEC_FSCALE_FRACT))
14910 (unspec:XF [(match_dup 8) (match_dup 4)]
14911 UNSPEC_FSCALE_EXP))])]
14912 "TARGET_USE_FANCY_MATH_387
14913 && flag_unsafe_math_optimizations"
14917 if (optimize_insn_for_size_p ())
14920 for (i = 3; i < 10; i++)
14921 operands[i] = gen_reg_rtx (XFmode);
14923 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14926 (define_expand "expxf2"
14927 [(use (match_operand:XF 0 "register_operand"))
14928 (use (match_operand:XF 1 "register_operand"))]
14929 "TARGET_USE_FANCY_MATH_387
14930 && flag_unsafe_math_optimizations"
14934 if (optimize_insn_for_size_p ())
14937 op2 = gen_reg_rtx (XFmode);
14938 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14940 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14944 (define_expand "exp<mode>2"
14945 [(use (match_operand:MODEF 0 "register_operand"))
14946 (use (match_operand:MODEF 1 "general_operand"))]
14947 "TARGET_USE_FANCY_MATH_387
14948 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14949 || TARGET_MIX_SSE_I387)
14950 && flag_unsafe_math_optimizations"
14954 if (optimize_insn_for_size_p ())
14957 op0 = gen_reg_rtx (XFmode);
14958 op1 = gen_reg_rtx (XFmode);
14960 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14961 emit_insn (gen_expxf2 (op0, op1));
14962 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14966 (define_expand "exp10xf2"
14967 [(use (match_operand:XF 0 "register_operand"))
14968 (use (match_operand:XF 1 "register_operand"))]
14969 "TARGET_USE_FANCY_MATH_387
14970 && flag_unsafe_math_optimizations"
14974 if (optimize_insn_for_size_p ())
14977 op2 = gen_reg_rtx (XFmode);
14978 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14980 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14984 (define_expand "exp10<mode>2"
14985 [(use (match_operand:MODEF 0 "register_operand"))
14986 (use (match_operand:MODEF 1 "general_operand"))]
14987 "TARGET_USE_FANCY_MATH_387
14988 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14989 || TARGET_MIX_SSE_I387)
14990 && flag_unsafe_math_optimizations"
14994 if (optimize_insn_for_size_p ())
14997 op0 = gen_reg_rtx (XFmode);
14998 op1 = gen_reg_rtx (XFmode);
15000 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15001 emit_insn (gen_exp10xf2 (op0, op1));
15002 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15006 (define_expand "exp2xf2"
15007 [(use (match_operand:XF 0 "register_operand"))
15008 (use (match_operand:XF 1 "register_operand"))]
15009 "TARGET_USE_FANCY_MATH_387
15010 && flag_unsafe_math_optimizations"
15014 if (optimize_insn_for_size_p ())
15017 op2 = gen_reg_rtx (XFmode);
15018 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15020 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15024 (define_expand "exp2<mode>2"
15025 [(use (match_operand:MODEF 0 "register_operand"))
15026 (use (match_operand:MODEF 1 "general_operand"))]
15027 "TARGET_USE_FANCY_MATH_387
15028 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15029 || TARGET_MIX_SSE_I387)
15030 && flag_unsafe_math_optimizations"
15034 if (optimize_insn_for_size_p ())
15037 op0 = gen_reg_rtx (XFmode);
15038 op1 = gen_reg_rtx (XFmode);
15040 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15041 emit_insn (gen_exp2xf2 (op0, op1));
15042 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15046 (define_expand "expm1xf2"
15047 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15049 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15050 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15051 (set (match_dup 9) (float_extend:XF (match_dup 13)))
15052 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15053 (parallel [(set (match_dup 7)
15054 (unspec:XF [(match_dup 6) (match_dup 4)]
15055 UNSPEC_FSCALE_FRACT))
15057 (unspec:XF [(match_dup 6) (match_dup 4)]
15058 UNSPEC_FSCALE_EXP))])
15059 (parallel [(set (match_dup 10)
15060 (unspec:XF [(match_dup 9) (match_dup 8)]
15061 UNSPEC_FSCALE_FRACT))
15062 (set (match_dup 11)
15063 (unspec:XF [(match_dup 9) (match_dup 8)]
15064 UNSPEC_FSCALE_EXP))])
15065 (set (match_dup 12) (minus:XF (match_dup 10)
15066 (float_extend:XF (match_dup 13))))
15067 (set (match_operand:XF 0 "register_operand")
15068 (plus:XF (match_dup 12) (match_dup 7)))]
15069 "TARGET_USE_FANCY_MATH_387
15070 && flag_unsafe_math_optimizations"
15074 if (optimize_insn_for_size_p ())
15077 for (i = 2; i < 13; i++)
15078 operands[i] = gen_reg_rtx (XFmode);
15081 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
15083 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
15086 (define_expand "expm1<mode>2"
15087 [(use (match_operand:MODEF 0 "register_operand"))
15088 (use (match_operand:MODEF 1 "general_operand"))]
15089 "TARGET_USE_FANCY_MATH_387
15090 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15091 || TARGET_MIX_SSE_I387)
15092 && flag_unsafe_math_optimizations"
15096 if (optimize_insn_for_size_p ())
15099 op0 = gen_reg_rtx (XFmode);
15100 op1 = gen_reg_rtx (XFmode);
15102 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15103 emit_insn (gen_expm1xf2 (op0, op1));
15104 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15108 (define_expand "ldexpxf3"
15109 [(match_operand:XF 0 "register_operand")
15110 (match_operand:XF 1 "register_operand")
15111 (match_operand:SI 2 "register_operand")]
15112 "TARGET_USE_FANCY_MATH_387
15113 && flag_unsafe_math_optimizations"
15116 if (optimize_insn_for_size_p ())
15119 tmp1 = gen_reg_rtx (XFmode);
15120 tmp2 = gen_reg_rtx (XFmode);
15122 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
15123 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
15124 operands[1], tmp1));
15128 (define_expand "ldexp<mode>3"
15129 [(use (match_operand:MODEF 0 "register_operand"))
15130 (use (match_operand:MODEF 1 "general_operand"))
15131 (use (match_operand:SI 2 "register_operand"))]
15132 "TARGET_USE_FANCY_MATH_387
15133 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15134 || TARGET_MIX_SSE_I387)
15135 && flag_unsafe_math_optimizations"
15139 if (optimize_insn_for_size_p ())
15142 op0 = gen_reg_rtx (XFmode);
15143 op1 = gen_reg_rtx (XFmode);
15145 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15146 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15147 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15151 (define_expand "scalbxf3"
15152 [(parallel [(set (match_operand:XF 0 " register_operand")
15153 (unspec:XF [(match_operand:XF 1 "register_operand")
15154 (match_operand:XF 2 "register_operand")]
15155 UNSPEC_FSCALE_FRACT))
15157 (unspec:XF [(match_dup 1) (match_dup 2)]
15158 UNSPEC_FSCALE_EXP))])]
15159 "TARGET_USE_FANCY_MATH_387
15160 && flag_unsafe_math_optimizations"
15162 if (optimize_insn_for_size_p ())
15165 operands[3] = gen_reg_rtx (XFmode);
15168 (define_expand "scalb<mode>3"
15169 [(use (match_operand:MODEF 0 "register_operand"))
15170 (use (match_operand:MODEF 1 "general_operand"))
15171 (use (match_operand:MODEF 2 "general_operand"))]
15172 "TARGET_USE_FANCY_MATH_387
15173 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15174 || TARGET_MIX_SSE_I387)
15175 && flag_unsafe_math_optimizations"
15179 if (optimize_insn_for_size_p ())
15182 op0 = gen_reg_rtx (XFmode);
15183 op1 = gen_reg_rtx (XFmode);
15184 op2 = gen_reg_rtx (XFmode);
15186 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15187 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15188 emit_insn (gen_scalbxf3 (op0, op1, op2));
15189 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15193 (define_expand "significandxf2"
15194 [(parallel [(set (match_operand:XF 0 "register_operand")
15195 (unspec:XF [(match_operand:XF 1 "register_operand")]
15196 UNSPEC_XTRACT_FRACT))
15198 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15199 "TARGET_USE_FANCY_MATH_387
15200 && flag_unsafe_math_optimizations"
15201 "operands[2] = gen_reg_rtx (XFmode);")
15203 (define_expand "significand<mode>2"
15204 [(use (match_operand:MODEF 0 "register_operand"))
15205 (use (match_operand:MODEF 1 "register_operand"))]
15206 "TARGET_USE_FANCY_MATH_387
15207 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15208 || TARGET_MIX_SSE_I387)
15209 && flag_unsafe_math_optimizations"
15211 rtx op0 = gen_reg_rtx (XFmode);
15212 rtx op1 = gen_reg_rtx (XFmode);
15214 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15215 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15220 (define_insn "sse4_1_round<mode>2"
15221 [(set (match_operand:MODEF 0 "register_operand" "=x")
15222 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
15223 (match_operand:SI 2 "const_0_to_15_operand" "n")]
15226 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15227 [(set_attr "type" "ssecvt")
15228 (set_attr "prefix_extra" "1")
15229 (set_attr "prefix" "maybe_vex")
15230 (set_attr "mode" "<MODE>")])
15232 (define_insn "rintxf2"
15233 [(set (match_operand:XF 0 "register_operand" "=f")
15234 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15236 "TARGET_USE_FANCY_MATH_387
15237 && flag_unsafe_math_optimizations"
15239 [(set_attr "type" "fpspc")
15240 (set_attr "mode" "XF")])
15242 (define_expand "rint<mode>2"
15243 [(use (match_operand:MODEF 0 "register_operand"))
15244 (use (match_operand:MODEF 1 "register_operand"))]
15245 "(TARGET_USE_FANCY_MATH_387
15246 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15247 || TARGET_MIX_SSE_I387)
15248 && flag_unsafe_math_optimizations)
15249 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15250 && !flag_trapping_math)"
15252 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15253 && !flag_trapping_math)
15256 emit_insn (gen_sse4_1_round<mode>2
15257 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
15258 else if (optimize_insn_for_size_p ())
15261 ix86_expand_rint (operands[0], operands[1]);
15265 rtx op0 = gen_reg_rtx (XFmode);
15266 rtx op1 = gen_reg_rtx (XFmode);
15268 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15269 emit_insn (gen_rintxf2 (op0, op1));
15271 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15276 (define_expand "round<mode>2"
15277 [(match_operand:X87MODEF 0 "register_operand")
15278 (match_operand:X87MODEF 1 "nonimmediate_operand")]
15279 "(TARGET_USE_FANCY_MATH_387
15280 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15281 || TARGET_MIX_SSE_I387)
15282 && flag_unsafe_math_optimizations)
15283 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15284 && !flag_trapping_math && !flag_rounding_math)"
15286 if (optimize_insn_for_size_p ())
15289 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15290 && !flag_trapping_math && !flag_rounding_math)
15294 operands[1] = force_reg (<MODE>mode, operands[1]);
15295 ix86_expand_round_sse4 (operands[0], operands[1]);
15297 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15298 ix86_expand_round (operands[0], operands[1]);
15300 ix86_expand_rounddf_32 (operands[0], operands[1]);
15304 operands[1] = force_reg (<MODE>mode, operands[1]);
15305 ix86_emit_i387_round (operands[0], operands[1]);
15310 (define_insn_and_split "*fistdi2_1"
15311 [(set (match_operand:DI 0 "nonimmediate_operand")
15312 (unspec:DI [(match_operand:XF 1 "register_operand")]
15314 "TARGET_USE_FANCY_MATH_387
15315 && can_create_pseudo_p ()"
15320 if (memory_operand (operands[0], VOIDmode))
15321 emit_insn (gen_fistdi2 (operands[0], operands[1]));
15324 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15325 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15330 [(set_attr "type" "fpspc")
15331 (set_attr "mode" "DI")])
15333 (define_insn "fistdi2"
15334 [(set (match_operand:DI 0 "memory_operand" "=m")
15335 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15337 (clobber (match_scratch:XF 2 "=&1f"))]
15338 "TARGET_USE_FANCY_MATH_387"
15339 "* return output_fix_trunc (insn, operands, false);"
15340 [(set_attr "type" "fpspc")
15341 (set_attr "mode" "DI")])
15343 (define_insn "fistdi2_with_temp"
15344 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15345 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15347 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15348 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15349 "TARGET_USE_FANCY_MATH_387"
15351 [(set_attr "type" "fpspc")
15352 (set_attr "mode" "DI")])
15355 [(set (match_operand:DI 0 "register_operand")
15356 (unspec:DI [(match_operand:XF 1 "register_operand")]
15358 (clobber (match_operand:DI 2 "memory_operand"))
15359 (clobber (match_scratch 3))]
15361 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15362 (clobber (match_dup 3))])
15363 (set (match_dup 0) (match_dup 2))])
15366 [(set (match_operand:DI 0 "memory_operand")
15367 (unspec:DI [(match_operand:XF 1 "register_operand")]
15369 (clobber (match_operand:DI 2 "memory_operand"))
15370 (clobber (match_scratch 3))]
15372 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15373 (clobber (match_dup 3))])])
15375 (define_insn_and_split "*fist<mode>2_1"
15376 [(set (match_operand:SWI24 0 "register_operand")
15377 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15379 "TARGET_USE_FANCY_MATH_387
15380 && can_create_pseudo_p ()"
15385 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15386 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15390 [(set_attr "type" "fpspc")
15391 (set_attr "mode" "<MODE>")])
15393 (define_insn "fist<mode>2"
15394 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15395 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15397 "TARGET_USE_FANCY_MATH_387"
15398 "* return output_fix_trunc (insn, operands, false);"
15399 [(set_attr "type" "fpspc")
15400 (set_attr "mode" "<MODE>")])
15402 (define_insn "fist<mode>2_with_temp"
15403 [(set (match_operand:SWI24 0 "register_operand" "=r")
15404 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15406 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15407 "TARGET_USE_FANCY_MATH_387"
15409 [(set_attr "type" "fpspc")
15410 (set_attr "mode" "<MODE>")])
15413 [(set (match_operand:SWI24 0 "register_operand")
15414 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15416 (clobber (match_operand:SWI24 2 "memory_operand"))]
15418 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15419 (set (match_dup 0) (match_dup 2))])
15422 [(set (match_operand:SWI24 0 "memory_operand")
15423 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15425 (clobber (match_operand:SWI24 2 "memory_operand"))]
15427 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15429 (define_expand "lrintxf<mode>2"
15430 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15431 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15433 "TARGET_USE_FANCY_MATH_387")
15435 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15436 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15437 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15438 UNSPEC_FIX_NOTRUNC))]
15439 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15441 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15442 [(match_operand:SWI248x 0 "nonimmediate_operand")
15443 (match_operand:X87MODEF 1 "register_operand")]
15444 "(TARGET_USE_FANCY_MATH_387
15445 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15446 || TARGET_MIX_SSE_I387)
15447 && flag_unsafe_math_optimizations)
15448 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15449 && <SWI248x:MODE>mode != HImode
15450 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15451 && !flag_trapping_math && !flag_rounding_math)"
15453 if (optimize_insn_for_size_p ())
15456 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15457 && <SWI248x:MODE>mode != HImode
15458 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15459 && !flag_trapping_math && !flag_rounding_math)
15460 ix86_expand_lround (operands[0], operands[1]);
15462 ix86_emit_i387_round (operands[0], operands[1]);
15466 (define_int_iterator FRNDINT_ROUNDING
15467 [UNSPEC_FRNDINT_FLOOR
15468 UNSPEC_FRNDINT_CEIL
15469 UNSPEC_FRNDINT_TRUNC])
15471 (define_int_iterator FIST_ROUNDING
15475 ;; Base name for define_insn
15476 (define_int_attr rounding_insn
15477 [(UNSPEC_FRNDINT_FLOOR "floor")
15478 (UNSPEC_FRNDINT_CEIL "ceil")
15479 (UNSPEC_FRNDINT_TRUNC "btrunc")
15480 (UNSPEC_FIST_FLOOR "floor")
15481 (UNSPEC_FIST_CEIL "ceil")])
15483 (define_int_attr rounding
15484 [(UNSPEC_FRNDINT_FLOOR "floor")
15485 (UNSPEC_FRNDINT_CEIL "ceil")
15486 (UNSPEC_FRNDINT_TRUNC "trunc")
15487 (UNSPEC_FIST_FLOOR "floor")
15488 (UNSPEC_FIST_CEIL "ceil")])
15490 (define_int_attr ROUNDING
15491 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15492 (UNSPEC_FRNDINT_CEIL "CEIL")
15493 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15494 (UNSPEC_FIST_FLOOR "FLOOR")
15495 (UNSPEC_FIST_CEIL "CEIL")])
15497 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15498 (define_insn_and_split "frndintxf2_<rounding>"
15499 [(set (match_operand:XF 0 "register_operand")
15500 (unspec:XF [(match_operand:XF 1 "register_operand")]
15502 (clobber (reg:CC FLAGS_REG))]
15503 "TARGET_USE_FANCY_MATH_387
15504 && flag_unsafe_math_optimizations
15505 && can_create_pseudo_p ()"
15510 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15512 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15513 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15515 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15516 operands[2], operands[3]));
15519 [(set_attr "type" "frndint")
15520 (set_attr "i387_cw" "<rounding>")
15521 (set_attr "mode" "XF")])
15523 (define_insn "frndintxf2_<rounding>_i387"
15524 [(set (match_operand:XF 0 "register_operand" "=f")
15525 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15527 (use (match_operand:HI 2 "memory_operand" "m"))
15528 (use (match_operand:HI 3 "memory_operand" "m"))]
15529 "TARGET_USE_FANCY_MATH_387
15530 && flag_unsafe_math_optimizations"
15531 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15532 [(set_attr "type" "frndint")
15533 (set_attr "i387_cw" "<rounding>")
15534 (set_attr "mode" "XF")])
15536 (define_expand "<rounding_insn>xf2"
15537 [(parallel [(set (match_operand:XF 0 "register_operand")
15538 (unspec:XF [(match_operand:XF 1 "register_operand")]
15540 (clobber (reg:CC FLAGS_REG))])]
15541 "TARGET_USE_FANCY_MATH_387
15542 && flag_unsafe_math_optimizations
15543 && !optimize_insn_for_size_p ()")
15545 (define_expand "<rounding_insn><mode>2"
15546 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15547 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15549 (clobber (reg:CC FLAGS_REG))])]
15550 "(TARGET_USE_FANCY_MATH_387
15551 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15552 || TARGET_MIX_SSE_I387)
15553 && flag_unsafe_math_optimizations)
15554 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15555 && !flag_trapping_math)"
15557 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15558 && !flag_trapping_math)
15561 emit_insn (gen_sse4_1_round<mode>2
15562 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15563 else if (optimize_insn_for_size_p ())
15565 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15567 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15568 ix86_expand_floorceil (operands[0], operands[1], true);
15569 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15570 ix86_expand_floorceil (operands[0], operands[1], false);
15571 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15572 ix86_expand_trunc (operands[0], operands[1]);
15574 gcc_unreachable ();
15578 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15579 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15580 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15581 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15582 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15583 ix86_expand_truncdf_32 (operands[0], operands[1]);
15585 gcc_unreachable ();
15592 if (optimize_insn_for_size_p ())
15595 op0 = gen_reg_rtx (XFmode);
15596 op1 = gen_reg_rtx (XFmode);
15597 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15598 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15600 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15605 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15606 (define_insn_and_split "frndintxf2_mask_pm"
15607 [(set (match_operand:XF 0 "register_operand")
15608 (unspec:XF [(match_operand:XF 1 "register_operand")]
15609 UNSPEC_FRNDINT_MASK_PM))
15610 (clobber (reg:CC FLAGS_REG))]
15611 "TARGET_USE_FANCY_MATH_387
15612 && flag_unsafe_math_optimizations
15613 && can_create_pseudo_p ()"
15618 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15620 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15621 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15623 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15624 operands[2], operands[3]));
15627 [(set_attr "type" "frndint")
15628 (set_attr "i387_cw" "mask_pm")
15629 (set_attr "mode" "XF")])
15631 (define_insn "frndintxf2_mask_pm_i387"
15632 [(set (match_operand:XF 0 "register_operand" "=f")
15633 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15634 UNSPEC_FRNDINT_MASK_PM))
15635 (use (match_operand:HI 2 "memory_operand" "m"))
15636 (use (match_operand:HI 3 "memory_operand" "m"))]
15637 "TARGET_USE_FANCY_MATH_387
15638 && flag_unsafe_math_optimizations"
15639 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15640 [(set_attr "type" "frndint")
15641 (set_attr "i387_cw" "mask_pm")
15642 (set_attr "mode" "XF")])
15644 (define_expand "nearbyintxf2"
15645 [(parallel [(set (match_operand:XF 0 "register_operand")
15646 (unspec:XF [(match_operand:XF 1 "register_operand")]
15647 UNSPEC_FRNDINT_MASK_PM))
15648 (clobber (reg:CC FLAGS_REG))])]
15649 "TARGET_USE_FANCY_MATH_387
15650 && flag_unsafe_math_optimizations")
15652 (define_expand "nearbyint<mode>2"
15653 [(use (match_operand:MODEF 0 "register_operand"))
15654 (use (match_operand:MODEF 1 "register_operand"))]
15655 "TARGET_USE_FANCY_MATH_387
15656 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15657 || TARGET_MIX_SSE_I387)
15658 && flag_unsafe_math_optimizations"
15660 rtx op0 = gen_reg_rtx (XFmode);
15661 rtx op1 = gen_reg_rtx (XFmode);
15663 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15664 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15666 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15670 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15671 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15672 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15673 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15675 (clobber (reg:CC FLAGS_REG))]
15676 "TARGET_USE_FANCY_MATH_387
15677 && flag_unsafe_math_optimizations
15678 && can_create_pseudo_p ()"
15683 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15685 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15686 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15687 if (memory_operand (operands[0], VOIDmode))
15688 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15689 operands[2], operands[3]));
15692 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15693 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15694 (operands[0], operands[1], operands[2],
15695 operands[3], operands[4]));
15699 [(set_attr "type" "fistp")
15700 (set_attr "i387_cw" "<rounding>")
15701 (set_attr "mode" "<MODE>")])
15703 (define_insn "fistdi2_<rounding>"
15704 [(set (match_operand:DI 0 "memory_operand" "=m")
15705 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15707 (use (match_operand:HI 2 "memory_operand" "m"))
15708 (use (match_operand:HI 3 "memory_operand" "m"))
15709 (clobber (match_scratch:XF 4 "=&1f"))]
15710 "TARGET_USE_FANCY_MATH_387
15711 && flag_unsafe_math_optimizations"
15712 "* return output_fix_trunc (insn, operands, false);"
15713 [(set_attr "type" "fistp")
15714 (set_attr "i387_cw" "<rounding>")
15715 (set_attr "mode" "DI")])
15717 (define_insn "fistdi2_<rounding>_with_temp"
15718 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15719 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15721 (use (match_operand:HI 2 "memory_operand" "m,m"))
15722 (use (match_operand:HI 3 "memory_operand" "m,m"))
15723 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15724 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15725 "TARGET_USE_FANCY_MATH_387
15726 && flag_unsafe_math_optimizations"
15728 [(set_attr "type" "fistp")
15729 (set_attr "i387_cw" "<rounding>")
15730 (set_attr "mode" "DI")])
15733 [(set (match_operand:DI 0 "register_operand")
15734 (unspec:DI [(match_operand:XF 1 "register_operand")]
15736 (use (match_operand:HI 2 "memory_operand"))
15737 (use (match_operand:HI 3 "memory_operand"))
15738 (clobber (match_operand:DI 4 "memory_operand"))
15739 (clobber (match_scratch 5))]
15741 [(parallel [(set (match_dup 4)
15742 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15743 (use (match_dup 2))
15744 (use (match_dup 3))
15745 (clobber (match_dup 5))])
15746 (set (match_dup 0) (match_dup 4))])
15749 [(set (match_operand:DI 0 "memory_operand")
15750 (unspec:DI [(match_operand:XF 1 "register_operand")]
15752 (use (match_operand:HI 2 "memory_operand"))
15753 (use (match_operand:HI 3 "memory_operand"))
15754 (clobber (match_operand:DI 4 "memory_operand"))
15755 (clobber (match_scratch 5))]
15757 [(parallel [(set (match_dup 0)
15758 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15759 (use (match_dup 2))
15760 (use (match_dup 3))
15761 (clobber (match_dup 5))])])
15763 (define_insn "fist<mode>2_<rounding>"
15764 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15765 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15767 (use (match_operand:HI 2 "memory_operand" "m"))
15768 (use (match_operand:HI 3 "memory_operand" "m"))]
15769 "TARGET_USE_FANCY_MATH_387
15770 && flag_unsafe_math_optimizations"
15771 "* return output_fix_trunc (insn, operands, false);"
15772 [(set_attr "type" "fistp")
15773 (set_attr "i387_cw" "<rounding>")
15774 (set_attr "mode" "<MODE>")])
15776 (define_insn "fist<mode>2_<rounding>_with_temp"
15777 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15778 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15780 (use (match_operand:HI 2 "memory_operand" "m,m"))
15781 (use (match_operand:HI 3 "memory_operand" "m,m"))
15782 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15783 "TARGET_USE_FANCY_MATH_387
15784 && flag_unsafe_math_optimizations"
15786 [(set_attr "type" "fistp")
15787 (set_attr "i387_cw" "<rounding>")
15788 (set_attr "mode" "<MODE>")])
15791 [(set (match_operand:SWI24 0 "register_operand")
15792 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15794 (use (match_operand:HI 2 "memory_operand"))
15795 (use (match_operand:HI 3 "memory_operand"))
15796 (clobber (match_operand:SWI24 4 "memory_operand"))]
15798 [(parallel [(set (match_dup 4)
15799 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15800 (use (match_dup 2))
15801 (use (match_dup 3))])
15802 (set (match_dup 0) (match_dup 4))])
15805 [(set (match_operand:SWI24 0 "memory_operand")
15806 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15808 (use (match_operand:HI 2 "memory_operand"))
15809 (use (match_operand:HI 3 "memory_operand"))
15810 (clobber (match_operand:SWI24 4 "memory_operand"))]
15812 [(parallel [(set (match_dup 0)
15813 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15814 (use (match_dup 2))
15815 (use (match_dup 3))])])
15817 (define_expand "l<rounding_insn>xf<mode>2"
15818 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15819 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15821 (clobber (reg:CC FLAGS_REG))])]
15822 "TARGET_USE_FANCY_MATH_387
15823 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15824 && flag_unsafe_math_optimizations")
15826 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15827 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15828 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15830 (clobber (reg:CC FLAGS_REG))])]
15831 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15832 && !flag_trapping_math"
15834 if (TARGET_64BIT && optimize_insn_for_size_p ())
15837 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15838 ix86_expand_lfloorceil (operands[0], operands[1], true);
15839 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15840 ix86_expand_lfloorceil (operands[0], operands[1], false);
15842 gcc_unreachable ();
15847 (define_insn "fxam<mode>2_i387"
15848 [(set (match_operand:HI 0 "register_operand" "=a")
15850 [(match_operand:X87MODEF 1 "register_operand" "f")]
15852 "TARGET_USE_FANCY_MATH_387"
15853 "fxam\n\tfnstsw\t%0"
15854 [(set_attr "type" "multi")
15855 (set_attr "length" "4")
15856 (set_attr "unit" "i387")
15857 (set_attr "mode" "<MODE>")])
15859 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15860 [(set (match_operand:HI 0 "register_operand")
15862 [(match_operand:MODEF 1 "memory_operand")]
15864 "TARGET_USE_FANCY_MATH_387
15865 && can_create_pseudo_p ()"
15868 [(set (match_dup 2)(match_dup 1))
15870 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15872 operands[2] = gen_reg_rtx (<MODE>mode);
15874 MEM_VOLATILE_P (operands[1]) = 1;
15876 [(set_attr "type" "multi")
15877 (set_attr "unit" "i387")
15878 (set_attr "mode" "<MODE>")])
15880 (define_expand "isinfxf2"
15881 [(use (match_operand:SI 0 "register_operand"))
15882 (use (match_operand:XF 1 "register_operand"))]
15883 "TARGET_USE_FANCY_MATH_387
15884 && ix86_libc_has_function (function_c99_misc)"
15886 rtx mask = GEN_INT (0x45);
15887 rtx val = GEN_INT (0x05);
15891 rtx scratch = gen_reg_rtx (HImode);
15892 rtx res = gen_reg_rtx (QImode);
15894 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15896 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15897 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15898 cond = gen_rtx_fmt_ee (EQ, QImode,
15899 gen_rtx_REG (CCmode, FLAGS_REG),
15901 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15902 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15906 (define_expand "isinf<mode>2"
15907 [(use (match_operand:SI 0 "register_operand"))
15908 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15909 "TARGET_USE_FANCY_MATH_387
15910 && ix86_libc_has_function (function_c99_misc)
15911 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15913 rtx mask = GEN_INT (0x45);
15914 rtx val = GEN_INT (0x05);
15918 rtx scratch = gen_reg_rtx (HImode);
15919 rtx res = gen_reg_rtx (QImode);
15921 /* Remove excess precision by forcing value through memory. */
15922 if (memory_operand (operands[1], VOIDmode))
15923 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15926 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15928 emit_move_insn (temp, operands[1]);
15929 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15932 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15933 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15934 cond = gen_rtx_fmt_ee (EQ, QImode,
15935 gen_rtx_REG (CCmode, FLAGS_REG),
15937 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15938 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15942 (define_expand "signbitxf2"
15943 [(use (match_operand:SI 0 "register_operand"))
15944 (use (match_operand:XF 1 "register_operand"))]
15945 "TARGET_USE_FANCY_MATH_387"
15947 rtx scratch = gen_reg_rtx (HImode);
15949 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15950 emit_insn (gen_andsi3 (operands[0],
15951 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15955 (define_insn "movmsk_df"
15956 [(set (match_operand:SI 0 "register_operand" "=r")
15958 [(match_operand:DF 1 "register_operand" "x")]
15960 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15961 "%vmovmskpd\t{%1, %0|%0, %1}"
15962 [(set_attr "type" "ssemov")
15963 (set_attr "prefix" "maybe_vex")
15964 (set_attr "mode" "DF")])
15966 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15967 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15968 (define_expand "signbitdf2"
15969 [(use (match_operand:SI 0 "register_operand"))
15970 (use (match_operand:DF 1 "register_operand"))]
15971 "TARGET_USE_FANCY_MATH_387
15972 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15974 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15976 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15977 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15981 rtx scratch = gen_reg_rtx (HImode);
15983 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15984 emit_insn (gen_andsi3 (operands[0],
15985 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15990 (define_expand "signbitsf2"
15991 [(use (match_operand:SI 0 "register_operand"))
15992 (use (match_operand:SF 1 "register_operand"))]
15993 "TARGET_USE_FANCY_MATH_387
15994 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15996 rtx scratch = gen_reg_rtx (HImode);
15998 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15999 emit_insn (gen_andsi3 (operands[0],
16000 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16004 ;; Block operation instructions
16007 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16010 [(set_attr "length" "1")
16011 (set_attr "length_immediate" "0")
16012 (set_attr "modrm" "0")])
16014 (define_expand "movmem<mode>"
16015 [(use (match_operand:BLK 0 "memory_operand"))
16016 (use (match_operand:BLK 1 "memory_operand"))
16017 (use (match_operand:SWI48 2 "nonmemory_operand"))
16018 (use (match_operand:SWI48 3 "const_int_operand"))
16019 (use (match_operand:SI 4 "const_int_operand"))
16020 (use (match_operand:SI 5 "const_int_operand"))
16021 (use (match_operand:SI 6 ""))
16022 (use (match_operand:SI 7 ""))
16023 (use (match_operand:SI 8 ""))]
16026 if (ix86_expand_set_or_movmem (operands[0], operands[1],
16027 operands[2], NULL, operands[3],
16028 operands[4], operands[5],
16029 operands[6], operands[7],
16030 operands[8], false))
16036 ;; Most CPUs don't like single string operations
16037 ;; Handle this case here to simplify previous expander.
16039 (define_expand "strmov"
16040 [(set (match_dup 4) (match_operand 3 "memory_operand"))
16041 (set (match_operand 1 "memory_operand") (match_dup 4))
16042 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
16043 (clobber (reg:CC FLAGS_REG))])
16044 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
16045 (clobber (reg:CC FLAGS_REG))])]
16048 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16050 /* If .md ever supports :P for Pmode, these can be directly
16051 in the pattern above. */
16052 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16053 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16055 /* Can't use this if the user has appropriated esi or edi. */
16056 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16057 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16059 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16060 operands[2], operands[3],
16061 operands[5], operands[6]));
16065 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16068 (define_expand "strmov_singleop"
16069 [(parallel [(set (match_operand 1 "memory_operand")
16070 (match_operand 3 "memory_operand"))
16071 (set (match_operand 0 "register_operand")
16073 (set (match_operand 2 "register_operand")
16074 (match_operand 5))])]
16076 "ix86_current_function_needs_cld = 1;")
16078 (define_insn "*strmovdi_rex_1"
16079 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16080 (mem:DI (match_operand:P 3 "register_operand" "1")))
16081 (set (match_operand:P 0 "register_operand" "=D")
16082 (plus:P (match_dup 2)
16084 (set (match_operand:P 1 "register_operand" "=S")
16085 (plus:P (match_dup 3)
16088 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16090 [(set_attr "type" "str")
16091 (set_attr "memory" "both")
16092 (set_attr "mode" "DI")])
16094 (define_insn "*strmovsi_1"
16095 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16096 (mem:SI (match_operand:P 3 "register_operand" "1")))
16097 (set (match_operand:P 0 "register_operand" "=D")
16098 (plus:P (match_dup 2)
16100 (set (match_operand:P 1 "register_operand" "=S")
16101 (plus:P (match_dup 3)
16103 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16105 [(set_attr "type" "str")
16106 (set_attr "memory" "both")
16107 (set_attr "mode" "SI")])
16109 (define_insn "*strmovhi_1"
16110 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16111 (mem:HI (match_operand:P 3 "register_operand" "1")))
16112 (set (match_operand:P 0 "register_operand" "=D")
16113 (plus:P (match_dup 2)
16115 (set (match_operand:P 1 "register_operand" "=S")
16116 (plus:P (match_dup 3)
16118 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16120 [(set_attr "type" "str")
16121 (set_attr "memory" "both")
16122 (set_attr "mode" "HI")])
16124 (define_insn "*strmovqi_1"
16125 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16126 (mem:QI (match_operand:P 3 "register_operand" "1")))
16127 (set (match_operand:P 0 "register_operand" "=D")
16128 (plus:P (match_dup 2)
16130 (set (match_operand:P 1 "register_operand" "=S")
16131 (plus:P (match_dup 3)
16133 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16135 [(set_attr "type" "str")
16136 (set_attr "memory" "both")
16137 (set (attr "prefix_rex")
16139 (match_test "<P:MODE>mode == DImode")
16141 (const_string "*")))
16142 (set_attr "mode" "QI")])
16144 (define_expand "rep_mov"
16145 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16146 (set (match_operand 0 "register_operand")
16148 (set (match_operand 2 "register_operand")
16150 (set (match_operand 1 "memory_operand")
16151 (match_operand 3 "memory_operand"))
16152 (use (match_dup 4))])]
16154 "ix86_current_function_needs_cld = 1;")
16156 (define_insn "*rep_movdi_rex64"
16157 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16158 (set (match_operand:P 0 "register_operand" "=D")
16159 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16161 (match_operand:P 3 "register_operand" "0")))
16162 (set (match_operand:P 1 "register_operand" "=S")
16163 (plus:P (ashift:P (match_dup 5) (const_int 3))
16164 (match_operand:P 4 "register_operand" "1")))
16165 (set (mem:BLK (match_dup 3))
16166 (mem:BLK (match_dup 4)))
16167 (use (match_dup 5))]
16169 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16171 [(set_attr "type" "str")
16172 (set_attr "prefix_rep" "1")
16173 (set_attr "memory" "both")
16174 (set_attr "mode" "DI")])
16176 (define_insn "*rep_movsi"
16177 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16178 (set (match_operand:P 0 "register_operand" "=D")
16179 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16181 (match_operand:P 3 "register_operand" "0")))
16182 (set (match_operand:P 1 "register_operand" "=S")
16183 (plus:P (ashift:P (match_dup 5) (const_int 2))
16184 (match_operand:P 4 "register_operand" "1")))
16185 (set (mem:BLK (match_dup 3))
16186 (mem:BLK (match_dup 4)))
16187 (use (match_dup 5))]
16188 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16189 "%^rep{%;} movs{l|d}"
16190 [(set_attr "type" "str")
16191 (set_attr "prefix_rep" "1")
16192 (set_attr "memory" "both")
16193 (set_attr "mode" "SI")])
16195 (define_insn "*rep_movqi"
16196 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16197 (set (match_operand:P 0 "register_operand" "=D")
16198 (plus:P (match_operand:P 3 "register_operand" "0")
16199 (match_operand:P 5 "register_operand" "2")))
16200 (set (match_operand:P 1 "register_operand" "=S")
16201 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16202 (set (mem:BLK (match_dup 3))
16203 (mem:BLK (match_dup 4)))
16204 (use (match_dup 5))]
16205 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16207 [(set_attr "type" "str")
16208 (set_attr "prefix_rep" "1")
16209 (set_attr "memory" "both")
16210 (set_attr "mode" "QI")])
16212 (define_expand "setmem<mode>"
16213 [(use (match_operand:BLK 0 "memory_operand"))
16214 (use (match_operand:SWI48 1 "nonmemory_operand"))
16215 (use (match_operand:QI 2 "nonmemory_operand"))
16216 (use (match_operand 3 "const_int_operand"))
16217 (use (match_operand:SI 4 "const_int_operand"))
16218 (use (match_operand:SI 5 "const_int_operand"))
16219 (use (match_operand:SI 6 ""))
16220 (use (match_operand:SI 7 ""))
16221 (use (match_operand:SI 8 ""))]
16224 if (ix86_expand_set_or_movmem (operands[0], NULL,
16225 operands[1], operands[2],
16226 operands[3], operands[4],
16227 operands[5], operands[6],
16228 operands[7], operands[8], true))
16234 ;; Most CPUs don't like single string operations
16235 ;; Handle this case here to simplify previous expander.
16237 (define_expand "strset"
16238 [(set (match_operand 1 "memory_operand")
16239 (match_operand 2 "register_operand"))
16240 (parallel [(set (match_operand 0 "register_operand")
16242 (clobber (reg:CC FLAGS_REG))])]
16245 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16246 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16248 /* If .md ever supports :P for Pmode, this can be directly
16249 in the pattern above. */
16250 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16251 GEN_INT (GET_MODE_SIZE (GET_MODE
16253 /* Can't use this if the user has appropriated eax or edi. */
16254 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16255 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16257 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16263 (define_expand "strset_singleop"
16264 [(parallel [(set (match_operand 1 "memory_operand")
16265 (match_operand 2 "register_operand"))
16266 (set (match_operand 0 "register_operand")
16268 (unspec [(const_int 0)] UNSPEC_STOS)])]
16270 "ix86_current_function_needs_cld = 1;")
16272 (define_insn "*strsetdi_rex_1"
16273 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16274 (match_operand:DI 2 "register_operand" "a"))
16275 (set (match_operand:P 0 "register_operand" "=D")
16276 (plus:P (match_dup 1)
16278 (unspec [(const_int 0)] UNSPEC_STOS)]
16280 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16282 [(set_attr "type" "str")
16283 (set_attr "memory" "store")
16284 (set_attr "mode" "DI")])
16286 (define_insn "*strsetsi_1"
16287 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16288 (match_operand:SI 2 "register_operand" "a"))
16289 (set (match_operand:P 0 "register_operand" "=D")
16290 (plus:P (match_dup 1)
16292 (unspec [(const_int 0)] UNSPEC_STOS)]
16293 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16295 [(set_attr "type" "str")
16296 (set_attr "memory" "store")
16297 (set_attr "mode" "SI")])
16299 (define_insn "*strsethi_1"
16300 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16301 (match_operand:HI 2 "register_operand" "a"))
16302 (set (match_operand:P 0 "register_operand" "=D")
16303 (plus:P (match_dup 1)
16305 (unspec [(const_int 0)] UNSPEC_STOS)]
16306 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16308 [(set_attr "type" "str")
16309 (set_attr "memory" "store")
16310 (set_attr "mode" "HI")])
16312 (define_insn "*strsetqi_1"
16313 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16314 (match_operand:QI 2 "register_operand" "a"))
16315 (set (match_operand:P 0 "register_operand" "=D")
16316 (plus:P (match_dup 1)
16318 (unspec [(const_int 0)] UNSPEC_STOS)]
16319 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16321 [(set_attr "type" "str")
16322 (set_attr "memory" "store")
16323 (set (attr "prefix_rex")
16325 (match_test "<P:MODE>mode == DImode")
16327 (const_string "*")))
16328 (set_attr "mode" "QI")])
16330 (define_expand "rep_stos"
16331 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16332 (set (match_operand 0 "register_operand")
16334 (set (match_operand 2 "memory_operand") (const_int 0))
16335 (use (match_operand 3 "register_operand"))
16336 (use (match_dup 1))])]
16338 "ix86_current_function_needs_cld = 1;")
16340 (define_insn "*rep_stosdi_rex64"
16341 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16342 (set (match_operand:P 0 "register_operand" "=D")
16343 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16345 (match_operand:P 3 "register_operand" "0")))
16346 (set (mem:BLK (match_dup 3))
16348 (use (match_operand:DI 2 "register_operand" "a"))
16349 (use (match_dup 4))]
16351 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16353 [(set_attr "type" "str")
16354 (set_attr "prefix_rep" "1")
16355 (set_attr "memory" "store")
16356 (set_attr "mode" "DI")])
16358 (define_insn "*rep_stossi"
16359 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16360 (set (match_operand:P 0 "register_operand" "=D")
16361 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16363 (match_operand:P 3 "register_operand" "0")))
16364 (set (mem:BLK (match_dup 3))
16366 (use (match_operand:SI 2 "register_operand" "a"))
16367 (use (match_dup 4))]
16368 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16369 "%^rep{%;} stos{l|d}"
16370 [(set_attr "type" "str")
16371 (set_attr "prefix_rep" "1")
16372 (set_attr "memory" "store")
16373 (set_attr "mode" "SI")])
16375 (define_insn "*rep_stosqi"
16376 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16377 (set (match_operand:P 0 "register_operand" "=D")
16378 (plus:P (match_operand:P 3 "register_operand" "0")
16379 (match_operand:P 4 "register_operand" "1")))
16380 (set (mem:BLK (match_dup 3))
16382 (use (match_operand:QI 2 "register_operand" "a"))
16383 (use (match_dup 4))]
16384 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16386 [(set_attr "type" "str")
16387 (set_attr "prefix_rep" "1")
16388 (set_attr "memory" "store")
16389 (set (attr "prefix_rex")
16391 (match_test "<P:MODE>mode == DImode")
16393 (const_string "*")))
16394 (set_attr "mode" "QI")])
16396 (define_expand "cmpstrnsi"
16397 [(set (match_operand:SI 0 "register_operand")
16398 (compare:SI (match_operand:BLK 1 "general_operand")
16399 (match_operand:BLK 2 "general_operand")))
16400 (use (match_operand 3 "general_operand"))
16401 (use (match_operand 4 "immediate_operand"))]
16404 rtx addr1, addr2, out, outlow, count, countreg, align;
16406 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16409 /* Can't use this if the user has appropriated ecx, esi or edi. */
16410 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16415 out = gen_reg_rtx (SImode);
16417 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16418 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16419 if (addr1 != XEXP (operands[1], 0))
16420 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16421 if (addr2 != XEXP (operands[2], 0))
16422 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16424 count = operands[3];
16425 countreg = ix86_zero_extend_to_Pmode (count);
16427 /* %%% Iff we are testing strict equality, we can use known alignment
16428 to good advantage. This may be possible with combine, particularly
16429 once cc0 is dead. */
16430 align = operands[4];
16432 if (CONST_INT_P (count))
16434 if (INTVAL (count) == 0)
16436 emit_move_insn (operands[0], const0_rtx);
16439 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16440 operands[1], operands[2]));
16444 rtx (*gen_cmp) (rtx, rtx);
16446 gen_cmp = (TARGET_64BIT
16447 ? gen_cmpdi_1 : gen_cmpsi_1);
16449 emit_insn (gen_cmp (countreg, countreg));
16450 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16451 operands[1], operands[2]));
16454 outlow = gen_lowpart (QImode, out);
16455 emit_insn (gen_cmpintqi (outlow));
16456 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16458 if (operands[0] != out)
16459 emit_move_insn (operands[0], out);
16464 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16466 (define_expand "cmpintqi"
16467 [(set (match_dup 1)
16468 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16470 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16471 (parallel [(set (match_operand:QI 0 "register_operand")
16472 (minus:QI (match_dup 1)
16474 (clobber (reg:CC FLAGS_REG))])]
16477 operands[1] = gen_reg_rtx (QImode);
16478 operands[2] = gen_reg_rtx (QImode);
16481 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16482 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16484 (define_expand "cmpstrnqi_nz_1"
16485 [(parallel [(set (reg:CC FLAGS_REG)
16486 (compare:CC (match_operand 4 "memory_operand")
16487 (match_operand 5 "memory_operand")))
16488 (use (match_operand 2 "register_operand"))
16489 (use (match_operand:SI 3 "immediate_operand"))
16490 (clobber (match_operand 0 "register_operand"))
16491 (clobber (match_operand 1 "register_operand"))
16492 (clobber (match_dup 2))])]
16494 "ix86_current_function_needs_cld = 1;")
16496 (define_insn "*cmpstrnqi_nz_1"
16497 [(set (reg:CC FLAGS_REG)
16498 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16499 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16500 (use (match_operand:P 6 "register_operand" "2"))
16501 (use (match_operand:SI 3 "immediate_operand" "i"))
16502 (clobber (match_operand:P 0 "register_operand" "=S"))
16503 (clobber (match_operand:P 1 "register_operand" "=D"))
16504 (clobber (match_operand:P 2 "register_operand" "=c"))]
16505 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16507 [(set_attr "type" "str")
16508 (set_attr "mode" "QI")
16509 (set (attr "prefix_rex")
16511 (match_test "<P:MODE>mode == DImode")
16513 (const_string "*")))
16514 (set_attr "prefix_rep" "1")])
16516 ;; The same, but the count is not known to not be zero.
16518 (define_expand "cmpstrnqi_1"
16519 [(parallel [(set (reg:CC FLAGS_REG)
16520 (if_then_else:CC (ne (match_operand 2 "register_operand")
16522 (compare:CC (match_operand 4 "memory_operand")
16523 (match_operand 5 "memory_operand"))
16525 (use (match_operand:SI 3 "immediate_operand"))
16526 (use (reg:CC FLAGS_REG))
16527 (clobber (match_operand 0 "register_operand"))
16528 (clobber (match_operand 1 "register_operand"))
16529 (clobber (match_dup 2))])]
16531 "ix86_current_function_needs_cld = 1;")
16533 (define_insn "*cmpstrnqi_1"
16534 [(set (reg:CC FLAGS_REG)
16535 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16537 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16538 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16540 (use (match_operand:SI 3 "immediate_operand" "i"))
16541 (use (reg:CC FLAGS_REG))
16542 (clobber (match_operand:P 0 "register_operand" "=S"))
16543 (clobber (match_operand:P 1 "register_operand" "=D"))
16544 (clobber (match_operand:P 2 "register_operand" "=c"))]
16545 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16547 [(set_attr "type" "str")
16548 (set_attr "mode" "QI")
16549 (set (attr "prefix_rex")
16551 (match_test "<P:MODE>mode == DImode")
16553 (const_string "*")))
16554 (set_attr "prefix_rep" "1")])
16556 (define_expand "strlen<mode>"
16557 [(set (match_operand:P 0 "register_operand")
16558 (unspec:P [(match_operand:BLK 1 "general_operand")
16559 (match_operand:QI 2 "immediate_operand")
16560 (match_operand 3 "immediate_operand")]
16564 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16570 (define_expand "strlenqi_1"
16571 [(parallel [(set (match_operand 0 "register_operand")
16573 (clobber (match_operand 1 "register_operand"))
16574 (clobber (reg:CC FLAGS_REG))])]
16576 "ix86_current_function_needs_cld = 1;")
16578 (define_insn "*strlenqi_1"
16579 [(set (match_operand:P 0 "register_operand" "=&c")
16580 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16581 (match_operand:QI 2 "register_operand" "a")
16582 (match_operand:P 3 "immediate_operand" "i")
16583 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16584 (clobber (match_operand:P 1 "register_operand" "=D"))
16585 (clobber (reg:CC FLAGS_REG))]
16586 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16587 "%^repnz{%;} scasb"
16588 [(set_attr "type" "str")
16589 (set_attr "mode" "QI")
16590 (set (attr "prefix_rex")
16592 (match_test "<P:MODE>mode == DImode")
16594 (const_string "*")))
16595 (set_attr "prefix_rep" "1")])
16597 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16598 ;; handled in combine, but it is not currently up to the task.
16599 ;; When used for their truth value, the cmpstrn* expanders generate
16608 ;; The intermediate three instructions are unnecessary.
16610 ;; This one handles cmpstrn*_nz_1...
16613 (set (reg:CC FLAGS_REG)
16614 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16615 (mem:BLK (match_operand 5 "register_operand"))))
16616 (use (match_operand 6 "register_operand"))
16617 (use (match_operand:SI 3 "immediate_operand"))
16618 (clobber (match_operand 0 "register_operand"))
16619 (clobber (match_operand 1 "register_operand"))
16620 (clobber (match_operand 2 "register_operand"))])
16621 (set (match_operand:QI 7 "register_operand")
16622 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16623 (set (match_operand:QI 8 "register_operand")
16624 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16625 (set (reg FLAGS_REG)
16626 (compare (match_dup 7) (match_dup 8)))
16628 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16630 (set (reg:CC FLAGS_REG)
16631 (compare:CC (mem:BLK (match_dup 4))
16632 (mem:BLK (match_dup 5))))
16633 (use (match_dup 6))
16634 (use (match_dup 3))
16635 (clobber (match_dup 0))
16636 (clobber (match_dup 1))
16637 (clobber (match_dup 2))])])
16639 ;; ...and this one handles cmpstrn*_1.
16642 (set (reg:CC FLAGS_REG)
16643 (if_then_else:CC (ne (match_operand 6 "register_operand")
16645 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16646 (mem:BLK (match_operand 5 "register_operand")))
16648 (use (match_operand:SI 3 "immediate_operand"))
16649 (use (reg:CC FLAGS_REG))
16650 (clobber (match_operand 0 "register_operand"))
16651 (clobber (match_operand 1 "register_operand"))
16652 (clobber (match_operand 2 "register_operand"))])
16653 (set (match_operand:QI 7 "register_operand")
16654 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16655 (set (match_operand:QI 8 "register_operand")
16656 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16657 (set (reg FLAGS_REG)
16658 (compare (match_dup 7) (match_dup 8)))
16660 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16662 (set (reg:CC FLAGS_REG)
16663 (if_then_else:CC (ne (match_dup 6)
16665 (compare:CC (mem:BLK (match_dup 4))
16666 (mem:BLK (match_dup 5)))
16668 (use (match_dup 3))
16669 (use (reg:CC FLAGS_REG))
16670 (clobber (match_dup 0))
16671 (clobber (match_dup 1))
16672 (clobber (match_dup 2))])])
16674 ;; Conditional move instructions.
16676 (define_expand "mov<mode>cc"
16677 [(set (match_operand:SWIM 0 "register_operand")
16678 (if_then_else:SWIM (match_operand 1 "comparison_operator")
16679 (match_operand:SWIM 2 "<general_operand>")
16680 (match_operand:SWIM 3 "<general_operand>")))]
16682 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16684 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16685 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16686 ;; So just document what we're doing explicitly.
16688 (define_expand "x86_mov<mode>cc_0_m1"
16690 [(set (match_operand:SWI48 0 "register_operand")
16691 (if_then_else:SWI48
16692 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16693 [(match_operand 1 "flags_reg_operand")
16697 (clobber (reg:CC FLAGS_REG))])])
16699 (define_insn "*x86_mov<mode>cc_0_m1"
16700 [(set (match_operand:SWI48 0 "register_operand" "=r")
16701 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16702 [(reg FLAGS_REG) (const_int 0)])
16705 (clobber (reg:CC FLAGS_REG))]
16707 "sbb{<imodesuffix>}\t%0, %0"
16708 ; Since we don't have the proper number of operands for an alu insn,
16709 ; fill in all the blanks.
16710 [(set_attr "type" "alu")
16711 (set_attr "use_carry" "1")
16712 (set_attr "pent_pair" "pu")
16713 (set_attr "memory" "none")
16714 (set_attr "imm_disp" "false")
16715 (set_attr "mode" "<MODE>")
16716 (set_attr "length_immediate" "0")])
16718 (define_insn "*x86_mov<mode>cc_0_m1_se"
16719 [(set (match_operand:SWI48 0 "register_operand" "=r")
16720 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16721 [(reg FLAGS_REG) (const_int 0)])
16724 (clobber (reg:CC FLAGS_REG))]
16726 "sbb{<imodesuffix>}\t%0, %0"
16727 [(set_attr "type" "alu")
16728 (set_attr "use_carry" "1")
16729 (set_attr "pent_pair" "pu")
16730 (set_attr "memory" "none")
16731 (set_attr "imm_disp" "false")
16732 (set_attr "mode" "<MODE>")
16733 (set_attr "length_immediate" "0")])
16735 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16736 [(set (match_operand:SWI48 0 "register_operand" "=r")
16737 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16738 [(reg FLAGS_REG) (const_int 0)])))
16739 (clobber (reg:CC FLAGS_REG))]
16741 "sbb{<imodesuffix>}\t%0, %0"
16742 [(set_attr "type" "alu")
16743 (set_attr "use_carry" "1")
16744 (set_attr "pent_pair" "pu")
16745 (set_attr "memory" "none")
16746 (set_attr "imm_disp" "false")
16747 (set_attr "mode" "<MODE>")
16748 (set_attr "length_immediate" "0")])
16750 (define_insn "*mov<mode>cc_noc"
16751 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16752 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16753 [(reg FLAGS_REG) (const_int 0)])
16754 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16755 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16756 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16758 cmov%O2%C1\t{%2, %0|%0, %2}
16759 cmov%O2%c1\t{%3, %0|%0, %3}"
16760 [(set_attr "type" "icmov")
16761 (set_attr "mode" "<MODE>")])
16763 ;; Don't do conditional moves with memory inputs. This splitter helps
16764 ;; register starved x86_32 by forcing inputs into registers before reload.
16766 [(set (match_operand:SWI248 0 "register_operand")
16767 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16768 [(reg FLAGS_REG) (const_int 0)])
16769 (match_operand:SWI248 2 "nonimmediate_operand")
16770 (match_operand:SWI248 3 "nonimmediate_operand")))]
16771 "!TARGET_64BIT && TARGET_CMOVE
16772 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16773 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16774 && can_create_pseudo_p ()
16775 && optimize_insn_for_speed_p ()"
16776 [(set (match_dup 0)
16777 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16779 if (MEM_P (operands[2]))
16780 operands[2] = force_reg (<MODE>mode, operands[2]);
16781 if (MEM_P (operands[3]))
16782 operands[3] = force_reg (<MODE>mode, operands[3]);
16785 (define_insn "*movqicc_noc"
16786 [(set (match_operand:QI 0 "register_operand" "=r,r")
16787 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16788 [(reg FLAGS_REG) (const_int 0)])
16789 (match_operand:QI 2 "register_operand" "r,0")
16790 (match_operand:QI 3 "register_operand" "0,r")))]
16791 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16793 [(set_attr "type" "icmov")
16794 (set_attr "mode" "QI")])
16797 [(set (match_operand:SWI12 0 "register_operand")
16798 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16799 [(reg FLAGS_REG) (const_int 0)])
16800 (match_operand:SWI12 2 "register_operand")
16801 (match_operand:SWI12 3 "register_operand")))]
16802 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16803 && reload_completed"
16804 [(set (match_dup 0)
16805 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16807 operands[0] = gen_lowpart (SImode, operands[0]);
16808 operands[2] = gen_lowpart (SImode, operands[2]);
16809 operands[3] = gen_lowpart (SImode, operands[3]);
16812 ;; Don't do conditional moves with memory inputs
16814 [(match_scratch:SWI248 2 "r")
16815 (set (match_operand:SWI248 0 "register_operand")
16816 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16817 [(reg FLAGS_REG) (const_int 0)])
16819 (match_operand:SWI248 3 "memory_operand")))]
16820 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16821 && optimize_insn_for_speed_p ()"
16822 [(set (match_dup 2) (match_dup 3))
16824 (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16827 [(match_scratch:SWI248 2 "r")
16828 (set (match_operand:SWI248 0 "register_operand")
16829 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16830 [(reg FLAGS_REG) (const_int 0)])
16831 (match_operand:SWI248 3 "memory_operand")
16833 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16834 && optimize_insn_for_speed_p ()"
16835 [(set (match_dup 2) (match_dup 3))
16837 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16839 (define_expand "mov<mode>cc"
16840 [(set (match_operand:X87MODEF 0 "register_operand")
16841 (if_then_else:X87MODEF
16842 (match_operand 1 "comparison_operator")
16843 (match_operand:X87MODEF 2 "register_operand")
16844 (match_operand:X87MODEF 3 "register_operand")))]
16845 "(TARGET_80387 && TARGET_CMOVE)
16846 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16847 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16849 (define_insn "*movxfcc_1"
16850 [(set (match_operand:XF 0 "register_operand" "=f,f")
16851 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16852 [(reg FLAGS_REG) (const_int 0)])
16853 (match_operand:XF 2 "register_operand" "f,0")
16854 (match_operand:XF 3 "register_operand" "0,f")))]
16855 "TARGET_80387 && TARGET_CMOVE"
16857 fcmov%F1\t{%2, %0|%0, %2}
16858 fcmov%f1\t{%3, %0|%0, %3}"
16859 [(set_attr "type" "fcmov")
16860 (set_attr "mode" "XF")])
16862 (define_insn "*movdfcc_1"
16863 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16864 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16865 [(reg FLAGS_REG) (const_int 0)])
16866 (match_operand:DF 2 "nonimmediate_operand"
16868 (match_operand:DF 3 "nonimmediate_operand"
16869 "0 ,f,0 ,rm,0, rm")))]
16870 "TARGET_80387 && TARGET_CMOVE
16871 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16873 fcmov%F1\t{%2, %0|%0, %2}
16874 fcmov%f1\t{%3, %0|%0, %3}
16877 cmov%O2%C1\t{%2, %0|%0, %2}
16878 cmov%O2%c1\t{%3, %0|%0, %3}"
16879 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16880 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16881 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16884 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16885 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16886 [(reg FLAGS_REG) (const_int 0)])
16887 (match_operand:DF 2 "nonimmediate_operand")
16888 (match_operand:DF 3 "nonimmediate_operand")))]
16889 "!TARGET_64BIT && reload_completed"
16890 [(set (match_dup 2)
16891 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16893 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16895 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16896 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16899 (define_insn "*movsfcc_1_387"
16900 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16901 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16902 [(reg FLAGS_REG) (const_int 0)])
16903 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16904 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16905 "TARGET_80387 && TARGET_CMOVE
16906 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16908 fcmov%F1\t{%2, %0|%0, %2}
16909 fcmov%f1\t{%3, %0|%0, %3}
16910 cmov%O2%C1\t{%2, %0|%0, %2}
16911 cmov%O2%c1\t{%3, %0|%0, %3}"
16912 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16913 (set_attr "mode" "SF,SF,SI,SI")])
16915 ;; Don't do conditional moves with memory inputs. This splitter helps
16916 ;; register starved x86_32 by forcing inputs into registers before reload.
16918 [(set (match_operand:MODEF 0 "register_operand")
16919 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16920 [(reg FLAGS_REG) (const_int 0)])
16921 (match_operand:MODEF 2 "nonimmediate_operand")
16922 (match_operand:MODEF 3 "nonimmediate_operand")))]
16923 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16924 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16925 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16926 && can_create_pseudo_p ()
16927 && optimize_insn_for_speed_p ()"
16928 [(set (match_dup 0)
16929 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16931 if (MEM_P (operands[2]))
16932 operands[2] = force_reg (<MODE>mode, operands[2]);
16933 if (MEM_P (operands[3]))
16934 operands[3] = force_reg (<MODE>mode, operands[3]);
16937 ;; Don't do conditional moves with memory inputs
16939 [(match_scratch:MODEF 2 "r")
16940 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16941 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16942 [(reg FLAGS_REG) (const_int 0)])
16944 (match_operand:MODEF 3 "memory_operand")))]
16945 "(<MODE>mode != DFmode || TARGET_64BIT)
16946 && TARGET_80387 && TARGET_CMOVE
16947 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16948 && optimize_insn_for_speed_p ()"
16949 [(set (match_dup 2) (match_dup 3))
16951 (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16954 [(match_scratch:MODEF 2 "r")
16955 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16956 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16957 [(reg FLAGS_REG) (const_int 0)])
16958 (match_operand:MODEF 3 "memory_operand")
16960 "(<MODE>mode != DFmode || TARGET_64BIT)
16961 && TARGET_80387 && TARGET_CMOVE
16962 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16963 && optimize_insn_for_speed_p ()"
16964 [(set (match_dup 2) (match_dup 3))
16966 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16968 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16969 ;; the scalar versions to have only XMM registers as operands.
16971 ;; XOP conditional move
16972 (define_insn "*xop_pcmov_<mode>"
16973 [(set (match_operand:MODEF 0 "register_operand" "=x")
16974 (if_then_else:MODEF
16975 (match_operand:MODEF 1 "register_operand" "x")
16976 (match_operand:MODEF 2 "register_operand" "x")
16977 (match_operand:MODEF 3 "register_operand" "x")))]
16979 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16980 [(set_attr "type" "sse4arg")])
16982 ;; These versions of the min/max patterns are intentionally ignorant of
16983 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16984 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16985 ;; are undefined in this condition, we're certain this is correct.
16987 (define_insn "<code><mode>3"
16988 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16990 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16991 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16992 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16994 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16995 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16996 [(set_attr "isa" "noavx,avx")
16997 (set_attr "prefix" "orig,vex")
16998 (set_attr "type" "sseadd")
16999 (set_attr "mode" "<MODE>")])
17001 ;; These versions of the min/max patterns implement exactly the operations
17002 ;; min = (op1 < op2 ? op1 : op2)
17003 ;; max = (!(op1 < op2) ? op1 : op2)
17004 ;; Their operands are not commutative, and thus they may be used in the
17005 ;; presence of -0.0 and NaN.
17007 (define_int_iterator IEEE_MAXMIN
17011 (define_int_attr ieee_maxmin
17012 [(UNSPEC_IEEE_MAX "max")
17013 (UNSPEC_IEEE_MIN "min")])
17015 (define_insn "*ieee_s<ieee_maxmin><mode>3"
17016 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
17018 [(match_operand:MODEF 1 "register_operand" "0,x")
17019 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
17021 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17023 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
17024 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17025 [(set_attr "isa" "noavx,avx")
17026 (set_attr "prefix" "orig,vex")
17027 (set_attr "type" "sseadd")
17028 (set_attr "mode" "<MODE>")])
17030 ;; Make two stack loads independent:
17032 ;; fld %st(0) -> fld bb
17033 ;; fmul bb fmul %st(1), %st
17035 ;; Actually we only match the last two instructions for simplicity.
17037 [(set (match_operand 0 "fp_register_operand")
17038 (match_operand 1 "fp_register_operand"))
17040 (match_operator 2 "binary_fp_operator"
17042 (match_operand 3 "memory_operand")]))]
17043 "REGNO (operands[0]) != REGNO (operands[1])"
17044 [(set (match_dup 0) (match_dup 3))
17045 (set (match_dup 0) (match_dup 4))]
17047 ;; The % modifier is not operational anymore in peephole2's, so we have to
17048 ;; swap the operands manually in the case of addition and multiplication.
17052 if (COMMUTATIVE_ARITH_P (operands[2]))
17053 op0 = operands[0], op1 = operands[1];
17055 op0 = operands[1], op1 = operands[0];
17057 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
17058 GET_MODE (operands[2]),
17062 ;; Conditional addition patterns
17063 (define_expand "add<mode>cc"
17064 [(match_operand:SWI 0 "register_operand")
17065 (match_operand 1 "ordered_comparison_operator")
17066 (match_operand:SWI 2 "register_operand")
17067 (match_operand:SWI 3 "const_int_operand")]
17069 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17071 ;; Misc patterns (?)
17073 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17074 ;; Otherwise there will be nothing to keep
17076 ;; [(set (reg ebp) (reg esp))]
17077 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17078 ;; (clobber (eflags)]
17079 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17081 ;; in proper program order.
17083 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
17084 [(set (match_operand:P 0 "register_operand" "=r,r")
17085 (plus:P (match_operand:P 1 "register_operand" "0,r")
17086 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17087 (clobber (reg:CC FLAGS_REG))
17088 (clobber (mem:BLK (scratch)))]
17091 switch (get_attr_type (insn))
17094 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17097 gcc_assert (rtx_equal_p (operands[0], operands[1]));
17098 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17099 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17101 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17104 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17105 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17108 [(set (attr "type")
17109 (cond [(and (eq_attr "alternative" "0")
17110 (not (match_test "TARGET_OPT_AGU")))
17111 (const_string "alu")
17112 (match_operand:<MODE> 2 "const0_operand")
17113 (const_string "imov")
17115 (const_string "lea")))
17116 (set (attr "length_immediate")
17117 (cond [(eq_attr "type" "imov")
17119 (and (eq_attr "type" "alu")
17120 (match_operand 2 "const128_operand"))
17123 (const_string "*")))
17124 (set_attr "mode" "<MODE>")])
17126 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
17127 [(set (match_operand:P 0 "register_operand" "=r")
17128 (minus:P (match_operand:P 1 "register_operand" "0")
17129 (match_operand:P 2 "register_operand" "r")))
17130 (clobber (reg:CC FLAGS_REG))
17131 (clobber (mem:BLK (scratch)))]
17133 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17134 [(set_attr "type" "alu")
17135 (set_attr "mode" "<MODE>")])
17137 (define_insn "allocate_stack_worker_probe_<mode>"
17138 [(set (match_operand:P 0 "register_operand" "=a")
17139 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17140 UNSPECV_STACK_PROBE))
17141 (clobber (reg:CC FLAGS_REG))]
17142 "ix86_target_stack_probe ()"
17143 "call\t___chkstk_ms"
17144 [(set_attr "type" "multi")
17145 (set_attr "length" "5")])
17147 (define_expand "allocate_stack"
17148 [(match_operand 0 "register_operand")
17149 (match_operand 1 "general_operand")]
17150 "ix86_target_stack_probe ()"
17154 #ifndef CHECK_STACK_LIMIT
17155 #define CHECK_STACK_LIMIT 0
17158 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17159 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17163 rtx (*insn) (rtx, rtx);
17165 x = copy_to_mode_reg (Pmode, operands[1]);
17167 insn = (TARGET_64BIT
17168 ? gen_allocate_stack_worker_probe_di
17169 : gen_allocate_stack_worker_probe_si);
17171 emit_insn (insn (x, x));
17174 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17175 stack_pointer_rtx, 0, OPTAB_DIRECT);
17177 if (x != stack_pointer_rtx)
17178 emit_move_insn (stack_pointer_rtx, x);
17180 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17184 ;; Use IOR for stack probes, this is shorter.
17185 (define_expand "probe_stack"
17186 [(match_operand 0 "memory_operand")]
17189 rtx (*gen_ior3) (rtx, rtx, rtx);
17191 gen_ior3 = (GET_MODE (operands[0]) == DImode
17192 ? gen_iordi3 : gen_iorsi3);
17194 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
17198 (define_insn "adjust_stack_and_probe<mode>"
17199 [(set (match_operand:P 0 "register_operand" "=r")
17200 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17201 UNSPECV_PROBE_STACK_RANGE))
17202 (set (reg:P SP_REG)
17203 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17204 (clobber (reg:CC FLAGS_REG))
17205 (clobber (mem:BLK (scratch)))]
17207 "* return output_adjust_stack_and_probe (operands[0]);"
17208 [(set_attr "type" "multi")])
17210 (define_insn "probe_stack_range<mode>"
17211 [(set (match_operand:P 0 "register_operand" "=r")
17212 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17213 (match_operand:P 2 "const_int_operand" "n")]
17214 UNSPECV_PROBE_STACK_RANGE))
17215 (clobber (reg:CC FLAGS_REG))]
17217 "* return output_probe_stack_range (operands[0], operands[2]);"
17218 [(set_attr "type" "multi")])
17220 (define_expand "builtin_setjmp_receiver"
17221 [(label_ref (match_operand 0))]
17222 "!TARGET_64BIT && flag_pic"
17228 rtx_code_label *label_rtx = gen_label_rtx ();
17229 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17230 xops[0] = xops[1] = pic_offset_table_rtx;
17231 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17232 ix86_expand_binary_operator (MINUS, SImode, xops);
17236 emit_insn (gen_set_got (pic_offset_table_rtx));
17240 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17241 ;; Do not split instructions with mask registers.
17243 [(set (match_operand 0 "general_reg_operand")
17244 (match_operator 3 "promotable_binary_operator"
17245 [(match_operand 1 "general_reg_operand")
17246 (match_operand 2 "aligned_operand")]))
17247 (clobber (reg:CC FLAGS_REG))]
17248 "! TARGET_PARTIAL_REG_STALL && reload_completed
17249 && ((GET_MODE (operands[0]) == HImode
17250 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17251 /* ??? next two lines just !satisfies_constraint_K (...) */
17252 || !CONST_INT_P (operands[2])
17253 || satisfies_constraint_K (operands[2])))
17254 || (GET_MODE (operands[0]) == QImode
17255 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17256 [(parallel [(set (match_dup 0)
17257 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17258 (clobber (reg:CC FLAGS_REG))])]
17260 operands[0] = gen_lowpart (SImode, operands[0]);
17261 operands[1] = gen_lowpart (SImode, operands[1]);
17262 if (GET_CODE (operands[3]) != ASHIFT)
17263 operands[2] = gen_lowpart (SImode, operands[2]);
17264 operands[3] = shallow_copy_rtx (operands[3]);
17265 PUT_MODE (operands[3], SImode);
17268 ; Promote the QImode tests, as i386 has encoding of the AND
17269 ; instruction with 32-bit sign-extended immediate and thus the
17270 ; instruction size is unchanged, except in the %eax case for
17271 ; which it is increased by one byte, hence the ! optimize_size.
17273 [(set (match_operand 0 "flags_reg_operand")
17274 (match_operator 2 "compare_operator"
17275 [(and (match_operand 3 "aligned_operand")
17276 (match_operand 4 "const_int_operand"))
17278 (set (match_operand 1 "register_operand")
17279 (and (match_dup 3) (match_dup 4)))]
17280 "! TARGET_PARTIAL_REG_STALL && reload_completed
17281 && optimize_insn_for_speed_p ()
17282 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17283 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17284 /* Ensure that the operand will remain sign-extended immediate. */
17285 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17286 [(parallel [(set (match_dup 0)
17287 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17290 (and:SI (match_dup 3) (match_dup 4)))])]
17293 = gen_int_mode (INTVAL (operands[4])
17294 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17295 operands[1] = gen_lowpart (SImode, operands[1]);
17296 operands[3] = gen_lowpart (SImode, operands[3]);
17299 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17300 ; the TEST instruction with 32-bit sign-extended immediate and thus
17301 ; the instruction size would at least double, which is not what we
17302 ; want even with ! optimize_size.
17304 [(set (match_operand 0 "flags_reg_operand")
17305 (match_operator 1 "compare_operator"
17306 [(and (match_operand:HI 2 "aligned_operand")
17307 (match_operand:HI 3 "const_int_operand"))
17309 "! TARGET_PARTIAL_REG_STALL && reload_completed
17310 && ! TARGET_FAST_PREFIX
17311 && optimize_insn_for_speed_p ()
17312 /* Ensure that the operand will remain sign-extended immediate. */
17313 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17314 [(set (match_dup 0)
17315 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17319 = gen_int_mode (INTVAL (operands[3])
17320 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17321 operands[2] = gen_lowpart (SImode, operands[2]);
17325 [(set (match_operand 0 "register_operand")
17326 (neg (match_operand 1 "register_operand")))
17327 (clobber (reg:CC FLAGS_REG))]
17328 "! TARGET_PARTIAL_REG_STALL && reload_completed
17329 && (GET_MODE (operands[0]) == HImode
17330 || (GET_MODE (operands[0]) == QImode
17331 && (TARGET_PROMOTE_QImode
17332 || optimize_insn_for_size_p ())))"
17333 [(parallel [(set (match_dup 0)
17334 (neg:SI (match_dup 1)))
17335 (clobber (reg:CC FLAGS_REG))])]
17337 operands[0] = gen_lowpart (SImode, operands[0]);
17338 operands[1] = gen_lowpart (SImode, operands[1]);
17341 ;; Do not split instructions with mask regs.
17343 [(set (match_operand 0 "general_reg_operand")
17344 (not (match_operand 1 "general_reg_operand")))]
17345 "! TARGET_PARTIAL_REG_STALL && reload_completed
17346 && (GET_MODE (operands[0]) == HImode
17347 || (GET_MODE (operands[0]) == QImode
17348 && (TARGET_PROMOTE_QImode
17349 || optimize_insn_for_size_p ())))"
17350 [(set (match_dup 0)
17351 (not:SI (match_dup 1)))]
17353 operands[0] = gen_lowpart (SImode, operands[0]);
17354 operands[1] = gen_lowpart (SImode, operands[1]);
17357 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17358 ;; transform a complex memory operation into two memory to register operations.
17360 ;; Don't push memory operands
17362 [(set (match_operand:SWI 0 "push_operand")
17363 (match_operand:SWI 1 "memory_operand"))
17364 (match_scratch:SWI 2 "<r>")]
17365 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17366 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17367 [(set (match_dup 2) (match_dup 1))
17368 (set (match_dup 0) (match_dup 2))])
17370 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17373 [(set (match_operand:SF 0 "push_operand")
17374 (match_operand:SF 1 "memory_operand"))
17375 (match_scratch:SF 2 "r")]
17376 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17377 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17378 [(set (match_dup 2) (match_dup 1))
17379 (set (match_dup 0) (match_dup 2))])
17381 ;; Don't move an immediate directly to memory when the instruction
17382 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17384 [(match_scratch:SWI124 1 "<r>")
17385 (set (match_operand:SWI124 0 "memory_operand")
17387 "optimize_insn_for_speed_p ()
17388 && ((<MODE>mode == HImode
17389 && TARGET_LCP_STALL)
17390 || (!TARGET_USE_MOV0
17391 && TARGET_SPLIT_LONG_MOVES
17392 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17393 && peep2_regno_dead_p (0, FLAGS_REG)"
17394 [(parallel [(set (match_dup 2) (const_int 0))
17395 (clobber (reg:CC FLAGS_REG))])
17396 (set (match_dup 0) (match_dup 1))]
17397 "operands[2] = gen_lowpart (SImode, operands[1]);")
17400 [(match_scratch:SWI124 2 "<r>")
17401 (set (match_operand:SWI124 0 "memory_operand")
17402 (match_operand:SWI124 1 "immediate_operand"))]
17403 "optimize_insn_for_speed_p ()
17404 && ((<MODE>mode == HImode
17405 && TARGET_LCP_STALL)
17406 || (TARGET_SPLIT_LONG_MOVES
17407 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17408 [(set (match_dup 2) (match_dup 1))
17409 (set (match_dup 0) (match_dup 2))])
17411 ;; Don't compare memory with zero, load and use a test instead.
17413 [(set (match_operand 0 "flags_reg_operand")
17414 (match_operator 1 "compare_operator"
17415 [(match_operand:SI 2 "memory_operand")
17417 (match_scratch:SI 3 "r")]
17418 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17419 [(set (match_dup 3) (match_dup 2))
17420 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17422 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17423 ;; Don't split NOTs with a displacement operand, because resulting XOR
17424 ;; will not be pairable anyway.
17426 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17427 ;; represented using a modRM byte. The XOR replacement is long decoded,
17428 ;; so this split helps here as well.
17430 ;; Note: Can't do this as a regular split because we can't get proper
17431 ;; lifetime information then.
17434 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
17435 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
17436 "optimize_insn_for_speed_p ()
17437 && ((TARGET_NOT_UNPAIRABLE
17438 && (!MEM_P (operands[0])
17439 || !memory_displacement_operand (operands[0], <MODE>mode)))
17440 || (TARGET_NOT_VECTORMODE
17441 && long_memory_operand (operands[0], <MODE>mode)))
17442 && peep2_regno_dead_p (0, FLAGS_REG)"
17443 [(parallel [(set (match_dup 0)
17444 (xor:SWI124 (match_dup 1) (const_int -1)))
17445 (clobber (reg:CC FLAGS_REG))])])
17447 ;; Non pairable "test imm, reg" instructions can be translated to
17448 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17449 ;; byte opcode instead of two, have a short form for byte operands),
17450 ;; so do it for other CPUs as well. Given that the value was dead,
17451 ;; this should not create any new dependencies. Pass on the sub-word
17452 ;; versions if we're concerned about partial register stalls.
17455 [(set (match_operand 0 "flags_reg_operand")
17456 (match_operator 1 "compare_operator"
17457 [(and:SI (match_operand:SI 2 "register_operand")
17458 (match_operand:SI 3 "immediate_operand"))
17460 "ix86_match_ccmode (insn, CCNOmode)
17461 && (true_regnum (operands[2]) != AX_REG
17462 || satisfies_constraint_K (operands[3]))
17463 && peep2_reg_dead_p (1, operands[2])"
17465 [(set (match_dup 0)
17466 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17469 (and:SI (match_dup 2) (match_dup 3)))])])
17471 ;; We don't need to handle HImode case, because it will be promoted to SImode
17472 ;; on ! TARGET_PARTIAL_REG_STALL
17475 [(set (match_operand 0 "flags_reg_operand")
17476 (match_operator 1 "compare_operator"
17477 [(and:QI (match_operand:QI 2 "register_operand")
17478 (match_operand:QI 3 "immediate_operand"))
17480 "! TARGET_PARTIAL_REG_STALL
17481 && ix86_match_ccmode (insn, CCNOmode)
17482 && true_regnum (operands[2]) != AX_REG
17483 && peep2_reg_dead_p (1, operands[2])"
17485 [(set (match_dup 0)
17486 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17489 (and:QI (match_dup 2) (match_dup 3)))])])
17492 [(set (match_operand 0 "flags_reg_operand")
17493 (match_operator 1 "compare_operator"
17496 (match_operand 2 "ext_register_operand")
17499 (match_operand 3 "const_int_operand"))
17501 "! TARGET_PARTIAL_REG_STALL
17502 && ix86_match_ccmode (insn, CCNOmode)
17503 && true_regnum (operands[2]) != AX_REG
17504 && peep2_reg_dead_p (1, operands[2])"
17505 [(parallel [(set (match_dup 0)
17514 (set (zero_extract:SI (match_dup 2)
17522 (match_dup 3)))])])
17524 ;; Don't do logical operations with memory inputs.
17526 [(match_scratch:SI 2 "r")
17527 (parallel [(set (match_operand:SI 0 "register_operand")
17528 (match_operator:SI 3 "arith_or_logical_operator"
17530 (match_operand:SI 1 "memory_operand")]))
17531 (clobber (reg:CC FLAGS_REG))])]
17532 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17533 [(set (match_dup 2) (match_dup 1))
17534 (parallel [(set (match_dup 0)
17535 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17536 (clobber (reg:CC FLAGS_REG))])])
17539 [(match_scratch:SI 2 "r")
17540 (parallel [(set (match_operand:SI 0 "register_operand")
17541 (match_operator:SI 3 "arith_or_logical_operator"
17542 [(match_operand:SI 1 "memory_operand")
17544 (clobber (reg:CC FLAGS_REG))])]
17545 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17546 [(set (match_dup 2) (match_dup 1))
17547 (parallel [(set (match_dup 0)
17548 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17549 (clobber (reg:CC FLAGS_REG))])])
17551 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17552 ;; refers to the destination of the load!
17555 [(set (match_operand:SI 0 "register_operand")
17556 (match_operand:SI 1 "register_operand"))
17557 (parallel [(set (match_dup 0)
17558 (match_operator:SI 3 "commutative_operator"
17560 (match_operand:SI 2 "memory_operand")]))
17561 (clobber (reg:CC FLAGS_REG))])]
17562 "REGNO (operands[0]) != REGNO (operands[1])
17563 && GENERAL_REGNO_P (REGNO (operands[0]))
17564 && GENERAL_REGNO_P (REGNO (operands[1]))"
17565 [(set (match_dup 0) (match_dup 4))
17566 (parallel [(set (match_dup 0)
17567 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17568 (clobber (reg:CC FLAGS_REG))])]
17569 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17572 [(set (match_operand 0 "register_operand")
17573 (match_operand 1 "register_operand"))
17575 (match_operator 3 "commutative_operator"
17577 (match_operand 2 "memory_operand")]))]
17578 "REGNO (operands[0]) != REGNO (operands[1])
17579 && ((MMX_REGNO_P (REGNO (operands[0]))
17580 && MMX_REGNO_P (REGNO (operands[1])))
17581 || (SSE_REGNO_P (REGNO (operands[0]))
17582 && SSE_REGNO_P (REGNO (operands[1]))))"
17583 [(set (match_dup 0) (match_dup 2))
17585 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17587 ; Don't do logical operations with memory outputs
17589 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17590 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17591 ; the same decoder scheduling characteristics as the original.
17594 [(match_scratch:SI 2 "r")
17595 (parallel [(set (match_operand:SI 0 "memory_operand")
17596 (match_operator:SI 3 "arith_or_logical_operator"
17598 (match_operand:SI 1 "nonmemory_operand")]))
17599 (clobber (reg:CC FLAGS_REG))])]
17600 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17601 /* Do not split stack checking probes. */
17602 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17603 [(set (match_dup 2) (match_dup 0))
17604 (parallel [(set (match_dup 2)
17605 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17606 (clobber (reg:CC FLAGS_REG))])
17607 (set (match_dup 0) (match_dup 2))])
17610 [(match_scratch:SI 2 "r")
17611 (parallel [(set (match_operand:SI 0 "memory_operand")
17612 (match_operator:SI 3 "arith_or_logical_operator"
17613 [(match_operand:SI 1 "nonmemory_operand")
17615 (clobber (reg:CC FLAGS_REG))])]
17616 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17617 /* Do not split stack checking probes. */
17618 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17619 [(set (match_dup 2) (match_dup 0))
17620 (parallel [(set (match_dup 2)
17621 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17622 (clobber (reg:CC FLAGS_REG))])
17623 (set (match_dup 0) (match_dup 2))])
17625 ;; Attempt to use arith or logical operations with memory outputs with
17626 ;; setting of flags.
17628 [(set (match_operand:SWI 0 "register_operand")
17629 (match_operand:SWI 1 "memory_operand"))
17630 (parallel [(set (match_dup 0)
17631 (match_operator:SWI 3 "plusminuslogic_operator"
17633 (match_operand:SWI 2 "<nonmemory_operand>")]))
17634 (clobber (reg:CC FLAGS_REG))])
17635 (set (match_dup 1) (match_dup 0))
17636 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17637 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17638 && peep2_reg_dead_p (4, operands[0])
17639 && !reg_overlap_mentioned_p (operands[0], operands[1])
17640 && !reg_overlap_mentioned_p (operands[0], operands[2])
17641 && (<MODE>mode != QImode
17642 || immediate_operand (operands[2], QImode)
17643 || q_regs_operand (operands[2], QImode))
17644 && ix86_match_ccmode (peep2_next_insn (3),
17645 (GET_CODE (operands[3]) == PLUS
17646 || GET_CODE (operands[3]) == MINUS)
17647 ? CCGOCmode : CCNOmode)"
17648 [(parallel [(set (match_dup 4) (match_dup 5))
17649 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17650 (match_dup 2)]))])]
17652 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17653 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17654 copy_rtx (operands[1]),
17655 copy_rtx (operands[2]));
17656 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17657 operands[5], const0_rtx);
17661 [(parallel [(set (match_operand:SWI 0 "register_operand")
17662 (match_operator:SWI 2 "plusminuslogic_operator"
17664 (match_operand:SWI 1 "memory_operand")]))
17665 (clobber (reg:CC FLAGS_REG))])
17666 (set (match_dup 1) (match_dup 0))
17667 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17668 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17669 && GET_CODE (operands[2]) != MINUS
17670 && peep2_reg_dead_p (3, operands[0])
17671 && !reg_overlap_mentioned_p (operands[0], operands[1])
17672 && ix86_match_ccmode (peep2_next_insn (2),
17673 GET_CODE (operands[2]) == PLUS
17674 ? CCGOCmode : CCNOmode)"
17675 [(parallel [(set (match_dup 3) (match_dup 4))
17676 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17677 (match_dup 0)]))])]
17679 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17680 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17681 copy_rtx (operands[1]),
17682 copy_rtx (operands[0]));
17683 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17684 operands[4], const0_rtx);
17688 [(set (match_operand:SWI12 0 "register_operand")
17689 (match_operand:SWI12 1 "memory_operand"))
17690 (parallel [(set (match_operand:SI 4 "register_operand")
17691 (match_operator:SI 3 "plusminuslogic_operator"
17693 (match_operand:SI 2 "nonmemory_operand")]))
17694 (clobber (reg:CC FLAGS_REG))])
17695 (set (match_dup 1) (match_dup 0))
17696 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17697 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17698 && REG_P (operands[0]) && REG_P (operands[4])
17699 && REGNO (operands[0]) == REGNO (operands[4])
17700 && peep2_reg_dead_p (4, operands[0])
17701 && (<MODE>mode != QImode
17702 || immediate_operand (operands[2], SImode)
17703 || q_regs_operand (operands[2], SImode))
17704 && !reg_overlap_mentioned_p (operands[0], operands[1])
17705 && !reg_overlap_mentioned_p (operands[0], operands[2])
17706 && ix86_match_ccmode (peep2_next_insn (3),
17707 (GET_CODE (operands[3]) == PLUS
17708 || GET_CODE (operands[3]) == MINUS)
17709 ? CCGOCmode : CCNOmode)"
17710 [(parallel [(set (match_dup 4) (match_dup 5))
17711 (set (match_dup 1) (match_dup 6))])]
17713 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17714 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17715 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17716 copy_rtx (operands[1]), operands[2]);
17717 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17718 operands[5], const0_rtx);
17719 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17720 copy_rtx (operands[1]),
17721 copy_rtx (operands[2]));
17724 ;; Attempt to always use XOR for zeroing registers.
17726 [(set (match_operand 0 "register_operand")
17727 (match_operand 1 "const0_operand"))]
17728 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17729 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17730 && GENERAL_REGNO_P (REGNO (operands[0]))
17731 && peep2_regno_dead_p (0, FLAGS_REG)"
17732 [(parallel [(set (match_dup 0) (const_int 0))
17733 (clobber (reg:CC FLAGS_REG))])]
17734 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17737 [(set (strict_low_part (match_operand 0 "register_operand"))
17739 "(GET_MODE (operands[0]) == QImode
17740 || GET_MODE (operands[0]) == HImode)
17741 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17742 && peep2_regno_dead_p (0, FLAGS_REG)"
17743 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17744 (clobber (reg:CC FLAGS_REG))])])
17746 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17748 [(set (match_operand:SWI248 0 "register_operand")
17750 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17751 && GENERAL_REGNO_P (REGNO (operands[0]))
17752 && peep2_regno_dead_p (0, FLAGS_REG)"
17753 [(parallel [(set (match_dup 0) (const_int -1))
17754 (clobber (reg:CC FLAGS_REG))])]
17756 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
17757 operands[0] = gen_lowpart (SImode, operands[0]);
17760 ;; Attempt to convert simple lea to add/shift.
17761 ;; These can be created by move expanders.
17762 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17763 ;; relevant lea instructions were already split.
17766 [(set (match_operand:SWI48 0 "register_operand")
17767 (plus:SWI48 (match_dup 0)
17768 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17770 && peep2_regno_dead_p (0, FLAGS_REG)"
17771 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17772 (clobber (reg:CC FLAGS_REG))])])
17775 [(set (match_operand:SWI48 0 "register_operand")
17776 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17779 && peep2_regno_dead_p (0, FLAGS_REG)"
17780 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17781 (clobber (reg:CC FLAGS_REG))])])
17784 [(set (match_operand:DI 0 "register_operand")
17786 (plus:SI (match_operand:SI 1 "register_operand")
17787 (match_operand:SI 2 "nonmemory_operand"))))]
17788 "TARGET_64BIT && !TARGET_OPT_AGU
17789 && REGNO (operands[0]) == REGNO (operands[1])
17790 && peep2_regno_dead_p (0, FLAGS_REG)"
17791 [(parallel [(set (match_dup 0)
17792 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17793 (clobber (reg:CC FLAGS_REG))])])
17796 [(set (match_operand:DI 0 "register_operand")
17798 (plus:SI (match_operand:SI 1 "nonmemory_operand")
17799 (match_operand:SI 2 "register_operand"))))]
17800 "TARGET_64BIT && !TARGET_OPT_AGU
17801 && REGNO (operands[0]) == REGNO (operands[2])
17802 && peep2_regno_dead_p (0, FLAGS_REG)"
17803 [(parallel [(set (match_dup 0)
17804 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17805 (clobber (reg:CC FLAGS_REG))])])
17808 [(set (match_operand:SWI48 0 "register_operand")
17809 (mult:SWI48 (match_dup 0)
17810 (match_operand:SWI48 1 "const_int_operand")))]
17811 "exact_log2 (INTVAL (operands[1])) >= 0
17812 && peep2_regno_dead_p (0, FLAGS_REG)"
17813 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17814 (clobber (reg:CC FLAGS_REG))])]
17815 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17818 [(set (match_operand:DI 0 "register_operand")
17820 (mult:SI (match_operand:SI 1 "register_operand")
17821 (match_operand:SI 2 "const_int_operand"))))]
17823 && exact_log2 (INTVAL (operands[2])) >= 0
17824 && REGNO (operands[0]) == REGNO (operands[1])
17825 && peep2_regno_dead_p (0, FLAGS_REG)"
17826 [(parallel [(set (match_dup 0)
17827 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17828 (clobber (reg:CC FLAGS_REG))])]
17829 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17831 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17832 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17833 ;; On many CPUs it is also faster, since special hardware to avoid esp
17834 ;; dependencies is present.
17836 ;; While some of these conversions may be done using splitters, we use
17837 ;; peepholes in order to allow combine_stack_adjustments pass to see
17838 ;; nonobfuscated RTL.
17840 ;; Convert prologue esp subtractions to push.
17841 ;; We need register to push. In order to keep verify_flow_info happy we have
17843 ;; - use scratch and clobber it in order to avoid dependencies
17844 ;; - use already live register
17845 ;; We can't use the second way right now, since there is no reliable way how to
17846 ;; verify that given register is live. First choice will also most likely in
17847 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17848 ;; call clobbered registers are dead. We may want to use base pointer as an
17849 ;; alternative when no register is available later.
17852 [(match_scratch:W 1 "r")
17853 (parallel [(set (reg:P SP_REG)
17854 (plus:P (reg:P SP_REG)
17855 (match_operand:P 0 "const_int_operand")))
17856 (clobber (reg:CC FLAGS_REG))
17857 (clobber (mem:BLK (scratch)))])]
17858 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17859 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17860 [(clobber (match_dup 1))
17861 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17862 (clobber (mem:BLK (scratch)))])])
17865 [(match_scratch:W 1 "r")
17866 (parallel [(set (reg:P SP_REG)
17867 (plus:P (reg:P SP_REG)
17868 (match_operand:P 0 "const_int_operand")))
17869 (clobber (reg:CC FLAGS_REG))
17870 (clobber (mem:BLK (scratch)))])]
17871 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17872 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17873 [(clobber (match_dup 1))
17874 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17875 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17876 (clobber (mem:BLK (scratch)))])])
17878 ;; Convert esp subtractions to push.
17880 [(match_scratch:W 1 "r")
17881 (parallel [(set (reg:P SP_REG)
17882 (plus:P (reg:P SP_REG)
17883 (match_operand:P 0 "const_int_operand")))
17884 (clobber (reg:CC FLAGS_REG))])]
17885 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17886 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17887 [(clobber (match_dup 1))
17888 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17891 [(match_scratch:W 1 "r")
17892 (parallel [(set (reg:P SP_REG)
17893 (plus:P (reg:P SP_REG)
17894 (match_operand:P 0 "const_int_operand")))
17895 (clobber (reg:CC FLAGS_REG))])]
17896 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17897 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17898 [(clobber (match_dup 1))
17899 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17900 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17902 ;; Convert epilogue deallocator to pop.
17904 [(match_scratch:W 1 "r")
17905 (parallel [(set (reg:P SP_REG)
17906 (plus:P (reg:P SP_REG)
17907 (match_operand:P 0 "const_int_operand")))
17908 (clobber (reg:CC FLAGS_REG))
17909 (clobber (mem:BLK (scratch)))])]
17910 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17911 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17912 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17913 (clobber (mem:BLK (scratch)))])])
17915 ;; Two pops case is tricky, since pop causes dependency
17916 ;; on destination register. We use two registers if available.
17918 [(match_scratch:W 1 "r")
17919 (match_scratch:W 2 "r")
17920 (parallel [(set (reg:P SP_REG)
17921 (plus:P (reg:P SP_REG)
17922 (match_operand:P 0 "const_int_operand")))
17923 (clobber (reg:CC FLAGS_REG))
17924 (clobber (mem:BLK (scratch)))])]
17925 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17926 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17927 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17928 (clobber (mem:BLK (scratch)))])
17929 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17932 [(match_scratch:W 1 "r")
17933 (parallel [(set (reg:P SP_REG)
17934 (plus:P (reg:P SP_REG)
17935 (match_operand:P 0 "const_int_operand")))
17936 (clobber (reg:CC FLAGS_REG))
17937 (clobber (mem:BLK (scratch)))])]
17938 "optimize_insn_for_size_p ()
17939 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17940 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17941 (clobber (mem:BLK (scratch)))])
17942 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17944 ;; Convert esp additions to pop.
17946 [(match_scratch:W 1 "r")
17947 (parallel [(set (reg:P SP_REG)
17948 (plus:P (reg:P SP_REG)
17949 (match_operand:P 0 "const_int_operand")))
17950 (clobber (reg:CC FLAGS_REG))])]
17951 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17952 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17954 ;; Two pops case is tricky, since pop causes dependency
17955 ;; on destination register. We use two registers if available.
17957 [(match_scratch:W 1 "r")
17958 (match_scratch:W 2 "r")
17959 (parallel [(set (reg:P SP_REG)
17960 (plus:P (reg:P SP_REG)
17961 (match_operand:P 0 "const_int_operand")))
17962 (clobber (reg:CC FLAGS_REG))])]
17963 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17964 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17965 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17968 [(match_scratch:W 1 "r")
17969 (parallel [(set (reg:P SP_REG)
17970 (plus:P (reg:P SP_REG)
17971 (match_operand:P 0 "const_int_operand")))
17972 (clobber (reg:CC FLAGS_REG))])]
17973 "optimize_insn_for_size_p ()
17974 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17975 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17976 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17978 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17979 ;; required and register dies. Similarly for 128 to -128.
17981 [(set (match_operand 0 "flags_reg_operand")
17982 (match_operator 1 "compare_operator"
17983 [(match_operand 2 "register_operand")
17984 (match_operand 3 "const_int_operand")]))]
17985 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17986 && incdec_operand (operands[3], GET_MODE (operands[3])))
17987 || (!TARGET_FUSE_CMP_AND_BRANCH
17988 && INTVAL (operands[3]) == 128))
17989 && ix86_match_ccmode (insn, CCGCmode)
17990 && peep2_reg_dead_p (1, operands[2])"
17991 [(parallel [(set (match_dup 0)
17992 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17993 (clobber (match_dup 2))])])
17995 ;; Convert imul by three, five and nine into lea
17998 [(set (match_operand:SWI48 0 "register_operand")
17999 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
18000 (match_operand:SWI48 2 "const359_operand")))
18001 (clobber (reg:CC FLAGS_REG))])]
18002 "!TARGET_PARTIAL_REG_STALL
18003 || <MODE>mode == SImode
18004 || optimize_function_for_size_p (cfun)"
18005 [(set (match_dup 0)
18006 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
18008 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18012 [(set (match_operand:SWI48 0 "register_operand")
18013 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
18014 (match_operand:SWI48 2 "const359_operand")))
18015 (clobber (reg:CC FLAGS_REG))])]
18016 "optimize_insn_for_speed_p ()
18017 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
18018 [(set (match_dup 0) (match_dup 1))
18020 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
18022 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18024 ;; imul $32bit_imm, mem, reg is vector decoded, while
18025 ;; imul $32bit_imm, reg, reg is direct decoded.
18027 [(match_scratch:SWI48 3 "r")
18028 (parallel [(set (match_operand:SWI48 0 "register_operand")
18029 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
18030 (match_operand:SWI48 2 "immediate_operand")))
18031 (clobber (reg:CC FLAGS_REG))])]
18032 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18033 && !satisfies_constraint_K (operands[2])"
18034 [(set (match_dup 3) (match_dup 1))
18035 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
18036 (clobber (reg:CC FLAGS_REG))])])
18039 [(match_scratch:SI 3 "r")
18040 (parallel [(set (match_operand:DI 0 "register_operand")
18042 (mult:SI (match_operand:SI 1 "memory_operand")
18043 (match_operand:SI 2 "immediate_operand"))))
18044 (clobber (reg:CC FLAGS_REG))])]
18046 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18047 && !satisfies_constraint_K (operands[2])"
18048 [(set (match_dup 3) (match_dup 1))
18049 (parallel [(set (match_dup 0)
18050 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18051 (clobber (reg:CC FLAGS_REG))])])
18053 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18054 ;; Convert it into imul reg, reg
18055 ;; It would be better to force assembler to encode instruction using long
18056 ;; immediate, but there is apparently no way to do so.
18058 [(parallel [(set (match_operand:SWI248 0 "register_operand")
18060 (match_operand:SWI248 1 "nonimmediate_operand")
18061 (match_operand:SWI248 2 "const_int_operand")))
18062 (clobber (reg:CC FLAGS_REG))])
18063 (match_scratch:SWI248 3 "r")]
18064 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18065 && satisfies_constraint_K (operands[2])"
18066 [(set (match_dup 3) (match_dup 2))
18067 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
18068 (clobber (reg:CC FLAGS_REG))])]
18070 if (!rtx_equal_p (operands[0], operands[1]))
18071 emit_move_insn (operands[0], operands[1]);
18074 ;; After splitting up read-modify operations, array accesses with memory
18075 ;; operands might end up in form:
18077 ;; movl 4(%esp), %edx
18079 ;; instead of pre-splitting:
18081 ;; addl 4(%esp), %eax
18083 ;; movl 4(%esp), %edx
18084 ;; leal (%edx,%eax,4), %eax
18087 [(match_scratch:W 5 "r")
18088 (parallel [(set (match_operand 0 "register_operand")
18089 (ashift (match_operand 1 "register_operand")
18090 (match_operand 2 "const_int_operand")))
18091 (clobber (reg:CC FLAGS_REG))])
18092 (parallel [(set (match_operand 3 "register_operand")
18093 (plus (match_dup 0)
18094 (match_operand 4 "x86_64_general_operand")))
18095 (clobber (reg:CC FLAGS_REG))])]
18096 "IN_RANGE (INTVAL (operands[2]), 1, 3)
18097 /* Validate MODE for lea. */
18098 && ((!TARGET_PARTIAL_REG_STALL
18099 && (GET_MODE (operands[0]) == QImode
18100 || GET_MODE (operands[0]) == HImode))
18101 || GET_MODE (operands[0]) == SImode
18102 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18103 && (rtx_equal_p (operands[0], operands[3])
18104 || peep2_reg_dead_p (2, operands[0]))
18105 /* We reorder load and the shift. */
18106 && !reg_overlap_mentioned_p (operands[0], operands[4])"
18107 [(set (match_dup 5) (match_dup 4))
18108 (set (match_dup 0) (match_dup 1))]
18110 machine_mode op1mode = GET_MODE (operands[1]);
18111 machine_mode mode = op1mode == DImode ? DImode : SImode;
18112 int scale = 1 << INTVAL (operands[2]);
18113 rtx index = gen_lowpart (word_mode, operands[1]);
18114 rtx base = gen_lowpart (word_mode, operands[5]);
18115 rtx dest = gen_lowpart (mode, operands[3]);
18117 operands[1] = gen_rtx_PLUS (word_mode, base,
18118 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
18119 if (mode != word_mode)
18120 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18122 operands[5] = base;
18123 if (op1mode != word_mode)
18124 operands[5] = gen_lowpart (op1mode, operands[5]);
18126 operands[0] = dest;
18129 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18130 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18131 ;; caught for use by garbage collectors and the like. Using an insn that
18132 ;; maps to SIGILL makes it more likely the program will rightfully die.
18133 ;; Keeping with tradition, "6" is in honor of #UD.
18134 (define_insn "trap"
18135 [(trap_if (const_int 1) (const_int 6))]
18138 #ifdef HAVE_AS_IX86_UD2
18141 return ASM_SHORT "0x0b0f";
18144 [(set_attr "length" "2")])
18146 (define_expand "prefetch"
18147 [(prefetch (match_operand 0 "address_operand")
18148 (match_operand:SI 1 "const_int_operand")
18149 (match_operand:SI 2 "const_int_operand"))]
18150 "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18152 bool write = INTVAL (operands[1]) != 0;
18153 int locality = INTVAL (operands[2]);
18155 gcc_assert (IN_RANGE (locality, 0, 3));
18157 /* Use 3dNOW prefetch in case we are asking for write prefetch not
18158 supported by SSE counterpart or the SSE prefetch is not available
18159 (K6 machines). Otherwise use SSE prefetch as it allows specifying
18161 if (TARGET_PREFETCHWT1 && write && locality <= 2)
18162 operands[2] = const2_rtx;
18163 else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
18164 operands[2] = GEN_INT (3);
18166 operands[1] = const0_rtx;
18169 (define_insn "*prefetch_sse"
18170 [(prefetch (match_operand 0 "address_operand" "p")
18172 (match_operand:SI 1 "const_int_operand"))]
18173 "TARGET_PREFETCH_SSE"
18175 static const char * const patterns[4] = {
18176 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18179 int locality = INTVAL (operands[1]);
18180 gcc_assert (IN_RANGE (locality, 0, 3));
18182 return patterns[locality];
18184 [(set_attr "type" "sse")
18185 (set_attr "atom_sse_attr" "prefetch")
18186 (set (attr "length_address")
18187 (symbol_ref "memory_address_length (operands[0], false)"))
18188 (set_attr "memory" "none")])
18190 (define_insn "*prefetch_3dnow"
18191 [(prefetch (match_operand 0 "address_operand" "p")
18192 (match_operand:SI 1 "const_int_operand" "n")
18196 if (INTVAL (operands[1]) == 0)
18197 return "prefetch\t%a0";
18199 return "prefetchw\t%a0";
18201 [(set_attr "type" "mmx")
18202 (set (attr "length_address")
18203 (symbol_ref "memory_address_length (operands[0], false)"))
18204 (set_attr "memory" "none")])
18206 (define_insn "*prefetch_prefetchwt1"
18207 [(prefetch (match_operand 0 "address_operand" "p")
18210 "TARGET_PREFETCHWT1"
18211 "prefetchwt1\t%a0";
18212 [(set_attr "type" "sse")
18213 (set (attr "length_address")
18214 (symbol_ref "memory_address_length (operands[0], false)"))
18215 (set_attr "memory" "none")])
18217 (define_expand "stack_protect_set"
18218 [(match_operand 0 "memory_operand")
18219 (match_operand 1 "memory_operand")]
18220 "TARGET_SSP_TLS_GUARD"
18222 rtx (*insn)(rtx, rtx);
18224 #ifdef TARGET_THREAD_SSP_OFFSET
18225 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18226 insn = (TARGET_LP64
18227 ? gen_stack_tls_protect_set_di
18228 : gen_stack_tls_protect_set_si);
18230 insn = (TARGET_LP64
18231 ? gen_stack_protect_set_di
18232 : gen_stack_protect_set_si);
18235 emit_insn (insn (operands[0], operands[1]));
18239 (define_insn "stack_protect_set_<mode>"
18240 [(set (match_operand:PTR 0 "memory_operand" "=m")
18241 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18243 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18244 (clobber (reg:CC FLAGS_REG))]
18245 "TARGET_SSP_TLS_GUARD"
18246 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18247 [(set_attr "type" "multi")])
18249 (define_insn "stack_tls_protect_set_<mode>"
18250 [(set (match_operand:PTR 0 "memory_operand" "=m")
18251 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
18252 UNSPEC_SP_TLS_SET))
18253 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18254 (clobber (reg:CC FLAGS_REG))]
18256 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18257 [(set_attr "type" "multi")])
18259 (define_expand "stack_protect_test"
18260 [(match_operand 0 "memory_operand")
18261 (match_operand 1 "memory_operand")
18263 "TARGET_SSP_TLS_GUARD"
18265 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18267 rtx (*insn)(rtx, rtx, rtx);
18269 #ifdef TARGET_THREAD_SSP_OFFSET
18270 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18271 insn = (TARGET_LP64
18272 ? gen_stack_tls_protect_test_di
18273 : gen_stack_tls_protect_test_si);
18275 insn = (TARGET_LP64
18276 ? gen_stack_protect_test_di
18277 : gen_stack_protect_test_si);
18280 emit_insn (insn (flags, operands[0], operands[1]));
18282 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18283 flags, const0_rtx, operands[2]));
18287 (define_insn "stack_protect_test_<mode>"
18288 [(set (match_operand:CCZ 0 "flags_reg_operand")
18289 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18290 (match_operand:PTR 2 "memory_operand" "m")]
18292 (clobber (match_scratch:PTR 3 "=&r"))]
18293 "TARGET_SSP_TLS_GUARD"
18294 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18295 [(set_attr "type" "multi")])
18297 (define_insn "stack_tls_protect_test_<mode>"
18298 [(set (match_operand:CCZ 0 "flags_reg_operand")
18299 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18300 (match_operand:PTR 2 "const_int_operand" "i")]
18301 UNSPEC_SP_TLS_TEST))
18302 (clobber (match_scratch:PTR 3 "=r"))]
18304 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18305 [(set_attr "type" "multi")])
18307 (define_insn "sse4_2_crc32<mode>"
18308 [(set (match_operand:SI 0 "register_operand" "=r")
18310 [(match_operand:SI 1 "register_operand" "0")
18311 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18313 "TARGET_SSE4_2 || TARGET_CRC32"
18314 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18315 [(set_attr "type" "sselog1")
18316 (set_attr "prefix_rep" "1")
18317 (set_attr "prefix_extra" "1")
18318 (set (attr "prefix_data16")
18319 (if_then_else (match_operand:HI 2)
18321 (const_string "*")))
18322 (set (attr "prefix_rex")
18323 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18325 (const_string "*")))
18326 (set_attr "mode" "SI")])
18328 (define_insn "sse4_2_crc32di"
18329 [(set (match_operand:DI 0 "register_operand" "=r")
18331 [(match_operand:DI 1 "register_operand" "0")
18332 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18334 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18335 "crc32{q}\t{%2, %0|%0, %2}"
18336 [(set_attr "type" "sselog1")
18337 (set_attr "prefix_rep" "1")
18338 (set_attr "prefix_extra" "1")
18339 (set_attr "mode" "DI")])
18341 (define_insn "rdpmc"
18342 [(set (match_operand:DI 0 "register_operand" "=A")
18343 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18347 [(set_attr "type" "other")
18348 (set_attr "length" "2")])
18350 (define_insn "rdpmc_rex64"
18351 [(set (match_operand:DI 0 "register_operand" "=a")
18352 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18354 (set (match_operand:DI 1 "register_operand" "=d")
18355 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18358 [(set_attr "type" "other")
18359 (set_attr "length" "2")])
18361 (define_insn "rdtsc"
18362 [(set (match_operand:DI 0 "register_operand" "=A")
18363 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18366 [(set_attr "type" "other")
18367 (set_attr "length" "2")])
18369 (define_insn "rdtsc_rex64"
18370 [(set (match_operand:DI 0 "register_operand" "=a")
18371 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18372 (set (match_operand:DI 1 "register_operand" "=d")
18373 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18376 [(set_attr "type" "other")
18377 (set_attr "length" "2")])
18379 (define_insn "rdtscp"
18380 [(set (match_operand:DI 0 "register_operand" "=A")
18381 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18382 (set (match_operand:SI 1 "register_operand" "=c")
18383 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18386 [(set_attr "type" "other")
18387 (set_attr "length" "3")])
18389 (define_insn "rdtscp_rex64"
18390 [(set (match_operand:DI 0 "register_operand" "=a")
18391 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18392 (set (match_operand:DI 1 "register_operand" "=d")
18393 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18394 (set (match_operand:SI 2 "register_operand" "=c")
18395 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18398 [(set_attr "type" "other")
18399 (set_attr "length" "3")])
18401 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18403 ;; FXSR, XSAVE and XSAVEOPT instructions
18405 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18407 (define_insn "fxsave"
18408 [(set (match_operand:BLK 0 "memory_operand" "=m")
18409 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18412 [(set_attr "type" "other")
18413 (set_attr "memory" "store")
18414 (set (attr "length")
18415 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18417 (define_insn "fxsave64"
18418 [(set (match_operand:BLK 0 "memory_operand" "=m")
18419 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18420 "TARGET_64BIT && TARGET_FXSR"
18422 [(set_attr "type" "other")
18423 (set_attr "memory" "store")
18424 (set (attr "length")
18425 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18427 (define_insn "fxrstor"
18428 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18432 [(set_attr "type" "other")
18433 (set_attr "memory" "load")
18434 (set (attr "length")
18435 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18437 (define_insn "fxrstor64"
18438 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18439 UNSPECV_FXRSTOR64)]
18440 "TARGET_64BIT && TARGET_FXSR"
18442 [(set_attr "type" "other")
18443 (set_attr "memory" "load")
18444 (set (attr "length")
18445 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18447 (define_int_iterator ANY_XSAVE
18449 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18450 (UNSPECV_XSAVEC "TARGET_XSAVEC")
18451 (UNSPECV_XSAVES "TARGET_XSAVES")])
18453 (define_int_iterator ANY_XSAVE64
18455 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18456 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18457 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18459 (define_int_attr xsave
18460 [(UNSPECV_XSAVE "xsave")
18461 (UNSPECV_XSAVE64 "xsave64")
18462 (UNSPECV_XSAVEOPT "xsaveopt")
18463 (UNSPECV_XSAVEOPT64 "xsaveopt64")
18464 (UNSPECV_XSAVEC "xsavec")
18465 (UNSPECV_XSAVEC64 "xsavec64")
18466 (UNSPECV_XSAVES "xsaves")
18467 (UNSPECV_XSAVES64 "xsaves64")])
18469 (define_int_iterator ANY_XRSTOR
18471 (UNSPECV_XRSTORS "TARGET_XSAVES")])
18473 (define_int_iterator ANY_XRSTOR64
18475 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18477 (define_int_attr xrstor
18478 [(UNSPECV_XRSTOR "xrstor")
18479 (UNSPECV_XRSTOR64 "xrstor")
18480 (UNSPECV_XRSTORS "xrstors")
18481 (UNSPECV_XRSTORS64 "xrstors")])
18483 (define_insn "<xsave>"
18484 [(set (match_operand:BLK 0 "memory_operand" "=m")
18485 (unspec_volatile:BLK
18486 [(match_operand:DI 1 "register_operand" "A")]
18488 "!TARGET_64BIT && TARGET_XSAVE"
18490 [(set_attr "type" "other")
18491 (set_attr "memory" "store")
18492 (set (attr "length")
18493 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18495 (define_insn "<xsave>_rex64"
18496 [(set (match_operand:BLK 0 "memory_operand" "=m")
18497 (unspec_volatile:BLK
18498 [(match_operand:SI 1 "register_operand" "a")
18499 (match_operand:SI 2 "register_operand" "d")]
18501 "TARGET_64BIT && TARGET_XSAVE"
18503 [(set_attr "type" "other")
18504 (set_attr "memory" "store")
18505 (set (attr "length")
18506 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18508 (define_insn "<xsave>"
18509 [(set (match_operand:BLK 0 "memory_operand" "=m")
18510 (unspec_volatile:BLK
18511 [(match_operand:SI 1 "register_operand" "a")
18512 (match_operand:SI 2 "register_operand" "d")]
18514 "TARGET_64BIT && TARGET_XSAVE"
18516 [(set_attr "type" "other")
18517 (set_attr "memory" "store")
18518 (set (attr "length")
18519 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18521 (define_insn "<xrstor>"
18522 [(unspec_volatile:BLK
18523 [(match_operand:BLK 0 "memory_operand" "m")
18524 (match_operand:DI 1 "register_operand" "A")]
18526 "!TARGET_64BIT && TARGET_XSAVE"
18528 [(set_attr "type" "other")
18529 (set_attr "memory" "load")
18530 (set (attr "length")
18531 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18533 (define_insn "<xrstor>_rex64"
18534 [(unspec_volatile:BLK
18535 [(match_operand:BLK 0 "memory_operand" "m")
18536 (match_operand:SI 1 "register_operand" "a")
18537 (match_operand:SI 2 "register_operand" "d")]
18539 "TARGET_64BIT && TARGET_XSAVE"
18541 [(set_attr "type" "other")
18542 (set_attr "memory" "load")
18543 (set (attr "length")
18544 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18546 (define_insn "<xrstor>64"
18547 [(unspec_volatile:BLK
18548 [(match_operand:BLK 0 "memory_operand" "m")
18549 (match_operand:SI 1 "register_operand" "a")
18550 (match_operand:SI 2 "register_operand" "d")]
18552 "TARGET_64BIT && TARGET_XSAVE"
18554 [(set_attr "type" "other")
18555 (set_attr "memory" "load")
18556 (set (attr "length")
18557 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18559 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18561 ;; Floating-point instructions for atomic compound assignments
18563 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18565 ; Clobber all floating-point registers on environment save and restore
18566 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18567 (define_insn "fnstenv"
18568 [(set (match_operand:BLK 0 "memory_operand" "=m")
18569 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18570 (clobber (reg:HI FPCR_REG))
18571 (clobber (reg:XF ST0_REG))
18572 (clobber (reg:XF ST1_REG))
18573 (clobber (reg:XF ST2_REG))
18574 (clobber (reg:XF ST3_REG))
18575 (clobber (reg:XF ST4_REG))
18576 (clobber (reg:XF ST5_REG))
18577 (clobber (reg:XF ST6_REG))
18578 (clobber (reg:XF ST7_REG))]
18581 [(set_attr "type" "other")
18582 (set_attr "memory" "store")
18583 (set (attr "length")
18584 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18586 (define_insn "fldenv"
18587 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18589 (clobber (reg:CCFP FPSR_REG))
18590 (clobber (reg:HI FPCR_REG))
18591 (clobber (reg:XF ST0_REG))
18592 (clobber (reg:XF ST1_REG))
18593 (clobber (reg:XF ST2_REG))
18594 (clobber (reg:XF ST3_REG))
18595 (clobber (reg:XF ST4_REG))
18596 (clobber (reg:XF ST5_REG))
18597 (clobber (reg:XF ST6_REG))
18598 (clobber (reg:XF ST7_REG))]
18601 [(set_attr "type" "other")
18602 (set_attr "memory" "load")
18603 (set (attr "length")
18604 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18606 (define_insn "fnstsw"
18607 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18608 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18611 [(set_attr "type" "other,other")
18612 (set_attr "memory" "none,store")
18613 (set (attr "length")
18614 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18616 (define_insn "fnclex"
18617 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18620 [(set_attr "type" "other")
18621 (set_attr "memory" "none")
18622 (set_attr "length" "2")])
18624 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18626 ;; LWP instructions
18628 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18630 (define_expand "lwp_llwpcb"
18631 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18632 UNSPECV_LLWP_INTRINSIC)]
18635 (define_insn "*lwp_llwpcb<mode>1"
18636 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18637 UNSPECV_LLWP_INTRINSIC)]
18640 [(set_attr "type" "lwp")
18641 (set_attr "mode" "<MODE>")
18642 (set_attr "length" "5")])
18644 (define_expand "lwp_slwpcb"
18645 [(set (match_operand 0 "register_operand" "=r")
18646 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18651 insn = (Pmode == DImode
18653 : gen_lwp_slwpcbsi);
18655 emit_insn (insn (operands[0]));
18659 (define_insn "lwp_slwpcb<mode>"
18660 [(set (match_operand:P 0 "register_operand" "=r")
18661 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18664 [(set_attr "type" "lwp")
18665 (set_attr "mode" "<MODE>")
18666 (set_attr "length" "5")])
18668 (define_expand "lwp_lwpval<mode>3"
18669 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18670 (match_operand:SI 2 "nonimmediate_operand" "rm")
18671 (match_operand:SI 3 "const_int_operand" "i")]
18672 UNSPECV_LWPVAL_INTRINSIC)]
18674 ;; Avoid unused variable warning.
18675 "(void) operands[0];")
18677 (define_insn "*lwp_lwpval<mode>3_1"
18678 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18679 (match_operand:SI 1 "nonimmediate_operand" "rm")
18680 (match_operand:SI 2 "const_int_operand" "i")]
18681 UNSPECV_LWPVAL_INTRINSIC)]
18683 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18684 [(set_attr "type" "lwp")
18685 (set_attr "mode" "<MODE>")
18686 (set (attr "length")
18687 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18689 (define_expand "lwp_lwpins<mode>3"
18690 [(set (reg:CCC FLAGS_REG)
18691 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18692 (match_operand:SI 2 "nonimmediate_operand" "rm")
18693 (match_operand:SI 3 "const_int_operand" "i")]
18694 UNSPECV_LWPINS_INTRINSIC))
18695 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18696 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18699 (define_insn "*lwp_lwpins<mode>3_1"
18700 [(set (reg:CCC FLAGS_REG)
18701 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18702 (match_operand:SI 1 "nonimmediate_operand" "rm")
18703 (match_operand:SI 2 "const_int_operand" "i")]
18704 UNSPECV_LWPINS_INTRINSIC))]
18706 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18707 [(set_attr "type" "lwp")
18708 (set_attr "mode" "<MODE>")
18709 (set (attr "length")
18710 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18712 (define_int_iterator RDFSGSBASE
18716 (define_int_iterator WRFSGSBASE
18720 (define_int_attr fsgs
18721 [(UNSPECV_RDFSBASE "fs")
18722 (UNSPECV_RDGSBASE "gs")
18723 (UNSPECV_WRFSBASE "fs")
18724 (UNSPECV_WRGSBASE "gs")])
18726 (define_insn "rd<fsgs>base<mode>"
18727 [(set (match_operand:SWI48 0 "register_operand" "=r")
18728 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18729 "TARGET_64BIT && TARGET_FSGSBASE"
18731 [(set_attr "type" "other")
18732 (set_attr "prefix_extra" "2")])
18734 (define_insn "wr<fsgs>base<mode>"
18735 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18737 "TARGET_64BIT && TARGET_FSGSBASE"
18739 [(set_attr "type" "other")
18740 (set_attr "prefix_extra" "2")])
18742 (define_insn "rdrand<mode>_1"
18743 [(set (match_operand:SWI248 0 "register_operand" "=r")
18744 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18745 (set (reg:CCC FLAGS_REG)
18746 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18749 [(set_attr "type" "other")
18750 (set_attr "prefix_extra" "1")])
18752 (define_insn "rdseed<mode>_1"
18753 [(set (match_operand:SWI248 0 "register_operand" "=r")
18754 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18755 (set (reg:CCC FLAGS_REG)
18756 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18759 [(set_attr "type" "other")
18760 (set_attr "prefix_extra" "1")])
18762 (define_expand "pause"
18763 [(set (match_dup 0)
18764 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18767 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18768 MEM_VOLATILE_P (operands[0]) = 1;
18771 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18772 ;; They have the same encoding.
18773 (define_insn "*pause"
18774 [(set (match_operand:BLK 0)
18775 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18778 [(set_attr "length" "2")
18779 (set_attr "memory" "unknown")])
18781 (define_expand "xbegin"
18782 [(set (match_operand:SI 0 "register_operand")
18783 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18786 rtx_code_label *label = gen_label_rtx ();
18788 /* xbegin is emitted as jump_insn, so reload won't be able
18789 to reload its operand. Force the value into AX hard register. */
18790 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18791 emit_move_insn (ax_reg, constm1_rtx);
18793 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18795 emit_label (label);
18796 LABEL_NUSES (label) = 1;
18798 emit_move_insn (operands[0], ax_reg);
18803 (define_insn "xbegin_1"
18805 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18807 (label_ref (match_operand 1))
18809 (set (match_operand:SI 0 "register_operand" "+a")
18810 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18813 [(set_attr "type" "other")
18814 (set_attr "length" "6")])
18816 (define_insn "xend"
18817 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18820 [(set_attr "type" "other")
18821 (set_attr "length" "3")])
18823 (define_insn "xabort"
18824 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18828 [(set_attr "type" "other")
18829 (set_attr "length" "3")])
18831 (define_expand "xtest"
18832 [(set (match_operand:QI 0 "register_operand")
18833 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18836 emit_insn (gen_xtest_1 ());
18838 ix86_expand_setcc (operands[0], NE,
18839 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18843 (define_insn "xtest_1"
18844 [(set (reg:CCZ FLAGS_REG)
18845 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18848 [(set_attr "type" "other")
18849 (set_attr "length" "3")])
18851 (define_insn "pcommit"
18852 [(unspec_volatile [(const_int 0)] UNSPECV_PCOMMIT)]
18855 [(set_attr "type" "other")
18856 (set_attr "length" "4")])
18858 (define_insn "clwb"
18859 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18863 [(set_attr "type" "sse")
18864 (set_attr "atom_sse_attr" "fence")
18865 (set_attr "memory" "unknown")])
18867 (define_insn "clflushopt"
18868 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18869 UNSPECV_CLFLUSHOPT)]
18870 "TARGET_CLFLUSHOPT"
18872 [(set_attr "type" "sse")
18873 (set_attr "atom_sse_attr" "fence")
18874 (set_attr "memory" "unknown")])
18876 ;; MONITORX and MWAITX
18877 (define_insn "mwaitx"
18878 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
18879 (match_operand:SI 1 "register_operand" "a")
18880 (match_operand:SI 2 "register_operand" "b")]
18883 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
18884 ;; Since 32bit register operands are implicitly zero extended to 64bit,
18885 ;; we only need to set up 32bit registers.
18887 [(set_attr "length" "3")])
18889 (define_insn "monitorx_<mode>"
18890 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
18891 (match_operand:SI 1 "register_operand" "c")
18892 (match_operand:SI 2 "register_operand" "d")]
18895 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
18896 ;; RCX and RDX are used. Since 32bit register operands are implicitly
18897 ;; zero extended to 64bit, we only need to set up 32bit registers.
18899 [(set (attr "length")
18900 (symbol_ref ("(Pmode != word_mode) + 3")))])
18902 ;; MPX instructions
18904 (define_expand "<mode>_mk"
18905 [(set (match_operand:BND 0 "register_operand")
18909 [(match_operand:<bnd_ptr> 1 "register_operand")
18910 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
18914 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18916 UNSPEC_BNDMK_ADDR);
18919 (define_insn "*<mode>_mk"
18920 [(set (match_operand:BND 0 "register_operand" "=w")
18922 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18924 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
18925 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
18926 UNSPEC_BNDMK_ADDR)])]
18929 "bndmk\t{%3, %0|%0, %3}"
18930 [(set_attr "type" "mpxmk")])
18932 (define_expand "mov<mode>"
18933 [(set (match_operand:BND 0 "general_operand")
18934 (match_operand:BND 1 "general_operand"))]
18937 ix86_expand_move (<MODE>mode, operands);DONE;
18940 (define_insn "*mov<mode>_internal_mpx"
18941 [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
18942 (match_operand:BND 1 "general_operand" "wm,w"))]
18944 "bndmov\t{%1, %0|%0, %1}"
18945 [(set_attr "type" "mpxmov")])
18947 (define_expand "<mode>_<bndcheck>"
18948 [(parallel [(unspec [(match_operand:BND 0 "register_operand")
18949 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
18951 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18954 operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
18955 MEM_VOLATILE_P (operands[2]) = 1;
18958 (define_insn "*<mode>_<bndcheck>"
18959 [(parallel [(unspec [(match_operand:BND 0 "register_operand" "w")
18960 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
18961 (set (match_operand:BLK 2 "bnd_mem_operator")
18962 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18964 "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
18965 [(set_attr "type" "mpxchk")])
18967 (define_expand "<mode>_ldx"
18968 [(parallel [(set:BND (match_operand:BND 0 "register_operand")
18972 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
18973 (match_operand:<bnd_ptr> 2 "register_operand")]))]
18975 (use (mem:BLK (match_dup 1)))])]
18978 /* Avoid registers which connot be used as index. */
18979 if (!index_register_operand (operands[2], Pmode))
18981 rtx temp = gen_reg_rtx (Pmode);
18982 emit_move_insn (temp, operands[2]);
18983 operands[2] = temp;
18986 /* If it was a register originally then it may have
18987 mode other than Pmode. We need to extend in such
18988 case because bndldx may work only with Pmode regs. */
18989 if (GET_MODE (operands[2]) != Pmode)
18990 operands[2] = ix86_zero_extend_to_Pmode (operands[2]);
18992 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18994 UNSPEC_BNDLDX_ADDR);
18997 (define_insn "*<mode>_ldx"
18998 [(parallel [(set:BND (match_operand:BND 0 "register_operand" "=w")
19000 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19002 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
19003 (match_operand:<bnd_ptr> 2 "register_operand" "l")]
19004 UNSPEC_BNDLDX_ADDR)])]
19006 (use (mem:BLK (match_dup 1)))])]
19008 "bndldx\t{%3, %0|%0, %3}"
19009 [(set_attr "type" "mpxld")])
19011 (define_expand "<mode>_stx"
19012 [(parallel [(unspec [(mem:<bnd_ptr>
19014 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
19015 (match_operand:<bnd_ptr> 1 "register_operand")]))
19016 (match_operand:BND 2 "register_operand")] UNSPEC_BNDSTX)
19018 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
19021 /* Avoid registers which connot be used as index. */
19022 if (!index_register_operand (operands[1], Pmode))
19024 rtx temp = gen_reg_rtx (Pmode);
19025 emit_move_insn (temp, operands[1]);
19026 operands[1] = temp;
19029 /* If it was a register originally then it may have
19030 mode other than Pmode. We need to extend in such
19031 case because bndstx may work only with Pmode regs. */
19032 if (GET_MODE (operands[1]) != Pmode)
19033 operands[1] = ix86_zero_extend_to_Pmode (operands[1]);
19035 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
19037 UNSPEC_BNDLDX_ADDR);
19038 operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
19039 MEM_VOLATILE_P (operands[4]) = 1;
19042 (define_insn "*<mode>_stx"
19043 [(parallel [(unspec [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19045 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
19046 (match_operand:<bnd_ptr> 1 "register_operand" "l")]
19047 UNSPEC_BNDLDX_ADDR)])
19048 (match_operand:BND 2 "register_operand" "w")] UNSPEC_BNDSTX)
19049 (set (match_operand:BLK 4 "bnd_mem_operator")
19050 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
19052 "bndstx\t{%2, %3|%3, %2}"
19053 [(set_attr "type" "mpxst")])
19055 (define_insn "move_size_reloc_<mode>"
19056 [(set (match_operand:SWI48 0 "register_operand" "=r")
19058 [(match_operand:SWI48 1 "symbol_operand")]
19062 if (x86_64_immediate_size_operand (operands[1], VOIDmode))
19063 return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
19065 return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
19067 [(set_attr "type" "imov")
19068 (set_attr "mode" "<MODE>")])
19072 (include "sync.md")